Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: add e2e tests #47

Merged
merged 28 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f466955
ci: added e2e folder with test file and other config files
jgrer Aug 2, 2024
fc80ccd
ci: remove extra packages and add e2e.yaml file
jgrer Aug 2, 2024
d51a30c
fix: change to trigger on push to e2e-tests branch
jgrer Aug 2, 2024
d378a6f
ci: change build extension action to use docker build command directl…
jgrer Aug 2, 2024
0ace623
ci: input image name and do initial scan
jgrer Aug 5, 2024
73fffc4
ci: type instead of fill
jgrer Aug 5, 2024
b5d05b1
ci: null check
jgrer Aug 5, 2024
f756613
ci: wait for vuln display after patching
jgrer Aug 5, 2024
ae48f87
ci: test patched image text display
jgrer Aug 5, 2024
bfb3101
ci: change null evaluations
jgrer Aug 5, 2024
db7d99a
ci: added console logging
jgrer Aug 5, 2024
a10cf89
ci: confirm loading started
jgrer Aug 5, 2024
ac5cd19
ci: null check for loading text
jgrer Aug 5, 2024
bc88030
ci: await more operations
jgrer Aug 5, 2024
77566d3
ci: add debug text to print patched image name
jgrer Aug 5, 2024
51bc300
ci: swap out if statements for optional chaining
jgrer Aug 5, 2024
cf6a332
ci: check for undefined and null
jgrer Aug 5, 2024
e30493d
ci: run docker images command and check for output
jgrer Aug 5, 2024
a324343
ci: log output.stdout instead of output object
jgrer Aug 5, 2024
d8048ab
change tests to run on pushs to main branch
jgrer Aug 5, 2024
2b1cf51
style: spelling error
jgrer Aug 5, 2024
84a3c70
ci: remove copyright and license text
jgrer Aug 6, 2024
0bd2a93
ci: removed duplicate file
jgrer Aug 6, 2024
13b44d4
ci: remove copyright and license text from other files
jgrer Aug 6, 2024
acac413
ci: update all tags to pin to digest + tag & added spaces between steps
jgrer Aug 6, 2024
184af67
ci: downgrade dependency review action to v4.3.2
jgrer Aug 6, 2024
2d113a6
style: added new line to two files
jgrer Aug 6, 2024
718a820
ci: revert action back to latest version
jgrer Aug 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: E2E tests

on:
push:
branches:
- main
pull_request:

jobs:
e2e:
name: Run E2E tests
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

- name: Install and start Docker Desktop
uses: docker/desktop-action/start@ca8f1a94b6716d5b278b081b654fbb7cd0b8fdb3 # v0.3.6

- name: Change Desktop settings and allow installing non marketplace extensions
run: |
jq '.onlyMarketplaceExtensions|=false' ~/.docker/desktop/settings.json >./new-settings.json
mv -f ./new-settings.json ~/.docker/desktop/settings.json

- name: Build extension
run: |
docker build --tag=projectcopacetic/copacetic-docker-desktop-extension:test .

- name: Kill Mono process running on port 8084 to unblock it # https://github.com/actions/runner-images/issues/2821
shell: bash
run: |
sudo fuser -k -n tcp 8084

- name: Enable corepack
run: corepack enable

- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: "20"

- name: Run E2E tests
env:
SKIP_EXTENSION_IMAGE_BUILD: true
run: |
cd e2e
yarn install
xvfb-run --auto-servernum --server-args="-screen 0 1920x1080x24" -- yarn test:e2e
14 changes: 14 additions & 0 deletions e2e/.babelrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "14.17"
}
}
],
"@babel/preset-typescript"
],
"plugins": []
}
24 changes: 24 additions & 0 deletions e2e/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"extends": [
"eslint:recommended",
"prettier"
],
"parser": "babel-eslint",
"env": {
"es6": true,
"node": true,
"jest": true,
"browser": true
},
"plugins": [
"prettier"
],
"rules": {
"prettier/prettier": [
"error"
]
},
"globals": {
"page": true
}
}
3 changes: 3 additions & 0 deletions e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
screenshots
.yarn
node_modules
5 changes: 5 additions & 0 deletions e2e/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"singleQuote": true,
"trailingComma": "all",
"tabWidth": 2
}
1 change: 1 addition & 0 deletions e2e/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
5 changes: 5 additions & 0 deletions e2e/globals.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { Page } from 'puppeteer-core';

declare global {
var page: Page | null;
}
7 changes: 7 additions & 0 deletions e2e/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
verbose: true,
testPathIgnorePatterns: ['/node_modules/'],
testEnvironment: 'node',
preset: 'ts-jest',
testTimeout: 360000,
};
55 changes: 55 additions & 0 deletions e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "electron-e2e",
"version": "1.0.0",
"description": "Testcafe setup to run docker desktop e2e tests",
"author": "docker",
"packageManager": "[email protected]",
"license": "ISC",
"devDependencies": {
"@babel/preset-env": "^7.24.8",
"@babel/preset-typescript": "^7.24.7",
"@docker/extension-test-helper": "^0.1.2",
"@jest/test-sequencer": "^29.7.0",
"@tsconfig/node16": "^16.1.3",
"@types/dockerode": "^3.3.30",
"@types/jest": "^29.5.12",
"@types/mkdirp": "^2.0.0",
"axios": "^1.7.2",
"babel-eslint": "^10.1.0",
"cross-env": "^7.0.3",
"dockerode": "^4.0.2",
"electron": "31.2.1",
"eslint": "^9.7.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"jest": "^29.7.0",
"prettier": "^3.3.3",
"ts-jest": "^29.2.3",
"typescript": "^4.5.5"
},
"dependencies": {
"@rumpl/node-eventsource": "^1.0.0",
"@types/bytes": "^3.1.4",
"bytes": "^3.1.2",
"find-process": "^1.4.4",
"fkill": "^9.0.0",
"get-port": "^7.1.0",
"got": "^14.4.1",
"mkdirp": "^3.0.1",
"puppeteer": "^22.13.1",
"puppeteer-core": "^22.13.1"
},
"scripts": {
"test:e2e": "yarn run test:e2e:packaged",
"test:e2e:packaged": "cross-env NODE_ENV=test WHICH_INSTANCE=packaged jest --colors --bail --runInBand --forceExit",
"pretest:e2e:dev": "(cd ../../client/desktop && yarn build:development)",
"test:e2e:dev": "cross-env NODE_ENV=test WHICH_INSTANCE=dev jest --colors --bail --runInBand --forceExit",
"test:puppeteer:debug": "cross-env NODE_ENV=test npx ndb jest --colors --bail --runInBand --forceExit",
"test:puppeteer:verbose": "cross-env NODE_ENV=test DEBUG=puppeteer:* jest --colors --bail --runInBand --forceExit",
"lint": "yarn run lint:js && yarn run check:ts",
"lint:js": "eslint .",
"check:ts": "tsc --noEmit",
"prettier:check": "prettier --check \"**/*.js\" \"**/*.ts\"",
"prettier": "prettier --write \"**/*.js\" \"**/*.ts\""
}
}
85 changes: 85 additions & 0 deletions e2e/test-copa-extension.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { DesktopUI } from '@docker/extension-test-helper';
import { exec as originalExec } from 'child_process';
import { describe, beforeAll, afterAll, test } from '@jest/globals';
import * as util from 'util';
import { WaitForSelectorOptions } from 'puppeteer-core';

export const exec = util.promisify(originalExec);

let dashboard: DesktopUI;

beforeAll(async () => {
if (process.env.SKIP_EXTENSION_IMAGE_BUILD != 'true') {
console.log('starting building extension...');
await exec(`projectcopacetic/copacetic-docker-desktop-extension:test`, {
cwd: '../',
});
console.log('extension built');
}
// await exec(
// `docker container create --name e2e-test-container -v e2e-test-volume:/data hello-world`,
// );
// console.log('sample volume and container created');
await exec(
`docker extension install -f projectcopacetic/copacetic-docker-desktop-extension:test`,
);
console.log('extension installed');
});

afterAll(async () => {
await dashboard?.stop();
console.log('dashboard app closed');
await exec(`docker extension uninstall projectcopacetic/copacetic-docker-desktop-extension:test`);
console.log('extension uninstalled');
});

describe('Test Main Workflow of Extension', () => {
test('display the patched image', async () => {
dashboard = await DesktopUI.start();

const eFrame = await dashboard.navigateToExtension(
'projectcopacetic/copacetic-docker-desktop-extension',
);

const imageInput = await eFrame.waitForSelector("#image-select-combo-box");

console.log('input nginx:1.21.6 image');
await imageInput?.type('nginx:1.21.6');
await imageInput?.dispose();

const scanPatchImageButton = await eFrame.waitForSelector('#scan-or-patch-image-button');

console.log('click scan button');
await scanPatchImageButton?.click();

const vulnDisplay = await eFrame.waitForSelector('#loaded-vuln-display-page', { timeout: 120000 });
console.log('scan finished (vulns being displayed)')
await vulnDisplay?.dispose();

console.log('click patch button');
await scanPatchImageButton?.click();
await scanPatchImageButton?.dispose();

const loadingText = await eFrame.waitForSelector('#loading-patch-text');
console.log('confirm loading started');
await loadingText?.dispose();

const patchedImageElement = await eFrame.waitForSelector('#new-patched-image-name-text', { timeout: 240000 });
console.log("scan finished (success)");
let patchedImageText = "";
const evalText = await patchedImageElement?.evaluate(element => element.textContent);
if (evalText !== null && evalText !== undefined) {
patchedImageText = evalText;
console.log('created patched image: ' + evalText);
}
await patchedImageElement?.dispose();

expect(patchedImageText).toBe("nginx:1.21.6-patched!");

const output = await exec(`docker images`);
console.log(output.stdout);

expect(output.stdout.includes('nginx')).toBe(true);
expect(output.stdout.includes('1.21.6-patched')).toBe(true);
});
});
18 changes: 18 additions & 0 deletions e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": "@tsconfig/node16/tsconfig.json",
"compilerOptions": {
"preserveConstEnums": true,
"lib": [
"es2020",
"dom"
],
"esModuleInterop": true
},
"include": [
"."
],
"exclude": [
"node_modules"
],
"noEmit": true // we don't ever generate .js files from this project, jest can run TS directly
}
Loading
Loading