Skip to content

Commit a40022c

Browse files
authored
Merge pull request #234 from simonladen/FISH-8908-set-up-automated-tests
FISH-8908 - add e2e tests
2 parents 1140572 + 2a67f76 commit a40022c

11 files changed

Lines changed: 164 additions & 101 deletions

File tree

Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pipeline {
2222
stage('Install Dependencies') {
2323
steps {
2424
// Install project dependencies
25-
sh 'curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -'
25+
sh 'curl -sL https://deb.nodesource.com/setup_20.x | sudo -E bash -'
2626
sh 'sudo apt-get install -y nodejs'
2727
sh 'sudo npm install -g yarn'
2828

package.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@
711711
"compile": "tsc -p ./",
712712
"watch": "tsc -watch -p ./",
713713
"pretest": "yarn run compile",
714-
"test": "node ./out/test/runTest.js",
714+
"test:e2e": "playwright test -c src/test/e2e/playwright.config.ts",
715715
"tslint": "tslint -t verbose src/**/*.ts"
716716
},
717717
"dependencies": {
@@ -733,17 +733,19 @@
733733
"xml2js": "^0.6.0"
734734
},
735735
"devDependencies": {
736+
"@playwright/test": "^1.47.2",
736737
"@types/fs-extra": "^11.0.1",
737738
"@types/glob": "^8.0.0",
738739
"@types/lodash": "^4.14.155",
739-
"@types/mocha": "^10.0.0",
740+
"@types/mocha": "10.0.8",
740741
"@types/node": "^22.5.4",
741742
"@types/vscode": "^1.93.0",
743+
"@vscode/test-electron": "2.4.1",
742744
"glob": "^7.1.7",
743-
"mocha": "^10.0.0",
745+
"mocha": "10.7.3",
744746
"os": "^0.1.1",
747+
"playwright": "^1.47.2",
745748
"tslint": "^6.1.0",
746-
"typescript": "^5.0.3",
747-
"vscode-test": "^1.2.2"
749+
"typescript": "^5.0.3"
748750
}
749751
}

src/test/e2e/README.md

Whitespace-only changes.

src/test/e2e/basePage.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import * as fs from 'fs';
2+
import * as os from 'os';
3+
import * as path from 'path';
4+
import type { Page } from '@playwright/test';
5+
import { _electron, test as base } from '@playwright/test';
6+
import { downloadAndUnzipVSCode } from '@vscode/test-electron/out/download';
7+
8+
export { expect } from '@playwright/test';
9+
10+
export type TestOptions = {
11+
vscodeVersion: string;
12+
};
13+
14+
type TestFixtures = TestOptions & {
15+
page: Page;
16+
createTmpDir: () => Promise<string>;
17+
};
18+
19+
export const MaxTimeout = 10000;
20+
21+
let testProjectPath: string;
22+
export const test = base.extend<TestFixtures>({
23+
vscodeVersion: ['insiders', { option: true }],
24+
page: async ({ vscodeVersion, createTmpDir }, use) => {
25+
const defaultCachePath = await createTmpDir();
26+
const vscodePath = await downloadAndUnzipVSCode(vscodeVersion);
27+
testProjectPath = path.join(__dirname, '..', '..', '..');
28+
29+
const electronApp = await _electron.launch({
30+
executablePath: vscodePath,
31+
// Got it from https://github.com/gitkraken/vscode-gitlens/blob/main/tests/e2e/specs/baseTest.ts
32+
args: [
33+
'--no-sandbox',
34+
'--disable-gpu-sandbox',
35+
'--disable-updates',
36+
'--skip-welcome',
37+
'--skip-release-notes',
38+
'--disable-workspace-trust',
39+
`--extensionDevelopmentPath=${path.join(__dirname, '..', '..', '..')}`,
40+
`--extensions-dir=${path.join(defaultCachePath, 'extensions')}`,
41+
`--user-data-dir=${path.join(defaultCachePath, 'user-data')}`,
42+
testProjectPath,
43+
],
44+
});
45+
46+
const page = await electronApp.firstWindow();
47+
48+
await use(page);
49+
50+
await electronApp.close();
51+
52+
const logPath = path.join(defaultCachePath, 'user-data');
53+
if (fs.existsSync(logPath)) {
54+
const logOutputPath = test.info().outputPath('vscode-logs');
55+
await fs.promises.cp(logPath, logOutputPath, { recursive: true });
56+
}
57+
},
58+
59+
// eslint-disable-next-line no-empty-pattern
60+
createTmpDir: async ({}, use) => {
61+
const tempDirs: string[] = [];
62+
await use(async () => {
63+
const tempDir = await fs.promises.realpath(await fs.promises.mkdtemp(path.join(os.tmpdir(), 'gltest-')));
64+
tempDirs.push(tempDir);
65+
return tempDir;
66+
});
67+
for (const tempDir of tempDirs) {
68+
await fs.promises.rm(tempDir, { recursive: true });
69+
}
70+
},
71+
});

src/test/e2e/playwright.config.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { defineConfig } from '@playwright/test';
2+
import type { TestOptions } from './basePage.js';
3+
4+
// eslint-disable-next-line import-x/no-default-export
5+
export default defineConfig<TestOptions>({
6+
use: {
7+
headless: true, // Ensure headless mode is enabled - Electron does not have a headless mode
8+
viewport: { width: 1920, height: 1080 },
9+
},
10+
reporter: 'list', // process.env.CI ? 'html' : 'list',
11+
timeout: 60000, // 1 minute
12+
workers: 1,
13+
expect: {
14+
timeout: 60000, // 1 minute
15+
},
16+
globalSetup: './setup',
17+
outputDir: '../../../out/test-results',
18+
projects: [
19+
{
20+
name: 'VSCode stable',
21+
use: {
22+
vscodeVersion: 'stable',
23+
},
24+
},
25+
{
26+
name: 'VSCode insiders',
27+
use: {
28+
vscodeVersion: 'insiders',
29+
},
30+
},
31+
],
32+
testMatch: '**/*.test.ts'
33+
});

src/test/e2e/setup.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { downloadAndUnzipVSCode } from '@vscode/test-electron';
2+
3+
// eslint-disable-next-line import-x/no-default-export
4+
export default async () => {
5+
await downloadAndUnzipVSCode('insiders');
6+
await downloadAndUnzipVSCode('stable');
7+
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Page } from 'playwright/test';
2+
import { expect, test } from '../basePage.js';
3+
4+
test.describe('Test Payara layout', () => {
5+
test.beforeEach('Open Payara plugin', async ({page}) =>{
6+
await page.getByRole('tab', { name: 'Payara' }).waitFor();
7+
const payaraIcon = page.getByRole('tab', { name: 'Payara' });
8+
await payaraIcon.click();
9+
});
10+
11+
test('should contain Payara icon in activity bar', async ({page}) => {
12+
await page.getByRole('tab', { name: 'Payara' }).waitFor();
13+
const payaraIcon = page.getByRole('tab', { name: 'Payara' });
14+
expect(payaraIcon).toHaveCount(1);
15+
});
16+
17+
test('should contain Payara in the title', async ({page}) => {
18+
await page.getByRole('heading', {name: 'PAYARA'}).waitFor();
19+
const payaraTitle = page.getByRole('heading', {name: 'PAYARA'});
20+
expect(payaraTitle).toHaveCount(1);
21+
});
22+
23+
test('should have one section for Servers and one for Micro', async ({page}) => {
24+
const payaraServerSection = page.getByRole('button', {name: 'Servers'});
25+
const payaraMicroSection = page.getByRole('button', {name: 'Micro Instances'});
26+
expect(payaraServerSection).toHaveCount(1);
27+
expect(payaraMicroSection).toHaveCount(1);
28+
});
29+
});

src/test/e2e/tsconfig.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"extends": "../../../tsconfig.json",
3+
"compilerOptions": {
4+
"target": "es2022",
5+
"module": "node16",
6+
"moduleResolution": "node16",
7+
"strict": true,
8+
"esModuleInterop": true,
9+
"skipLibCheck": true,
10+
"forceConsistentCasingInFileNames": true,
11+
"outDir": "./out",
12+
"rootDir": ".",
13+
"sourceMap": true
14+
},
15+
"include": ["**/*.ts"]
16+
}

src/test/runTest.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/test/suite/extension.test.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)