Skip to content

Commit 487e92b

Browse files
xaiplanger
andauthored
Basic playwright electron support (#12207)
This change allows to write tests against an Electron app by starting the Electron app first and then attaching Playwright to it. Also, it solves the workspace problem by creating it upfront and pointing to it on app start. Because playwright cannot access native UI elements, we introduce an optional environment variable THEIA_ELECTRON_DISABLE_NATIVE_ELEMENTS that, when set to 1, enforces the rendering of HTML-based menus and file chooser dialogs, which can be accessed by playwright. Playwright also requires us to disable early rendering of the window, which we also do via an environment variable (THEIA_ELECTRON_NO_EARLY_WINDOW). A unified TheiaAppLoader is introduced that can be used in both browser and electron tests. All existing tests are adjusted to use the new AppLoader and can be run in Electron if the environment variable USE_ELECTRON is set to true. For convenience, a yarn target ui-tests-electron has been added to the playwright package.json. Furthermore, the target ui-tests-ci has been added (runs all playwright tests in the browser and in Electron) and the Github workflow has been adjusted. Contributed on behalf of STMicroelectronics Signed-off-by: Olaf Lessenich <[email protected]> Co-authored-by: Philip Langer <[email protected]>
1 parent 046e143 commit 487e92b

32 files changed

+544
-181
lines changed

.github/workflows/playwright.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ jobs:
5151
- name: Test (playwright)
5252
uses: GabrielBB/xvfb-action@v1
5353
with:
54-
run: yarn test:playwright
54+
run: yarn --cwd examples/playwright ui-tests-ci
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// *****************************************************************************
2+
// Copyright (C) 2022 EclipseSource and others.
3+
//
4+
// This program and the accompanying materials are made available under the
5+
// terms of the Eclipse Public License v. 2.0 which is available at
6+
// http://www.eclipse.org/legal/epl-2.0.
7+
//
8+
// This Source Code may also be made available under the following Secondary
9+
// Licenses when the conditions for such availability set forth in the Eclipse
10+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
11+
// with the GNU Classpath Exception which is available at
12+
// https://www.gnu.org/software/classpath/license.html.
13+
//
14+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
// *****************************************************************************
16+
17+
import { PlaywrightTestConfig } from '@playwright/test';
18+
import baseConfig from './playwright.config';
19+
20+
const ciConfig: PlaywrightTestConfig = {
21+
...baseConfig,
22+
workers: 1,
23+
retries: 2,
24+
reporter: [['list'], ['allure-playwright'], ['github']]
25+
};
26+
27+
export default ciConfig;
Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// *****************************************************************************
2-
// Copyright (C) 2021-2023 logi.cals GmbH, EclipseSource and others.
2+
// Copyright (C) 2021 logi.cals GmbH, EclipseSource and others.
33
//
44
// This program and the accompanying materials are made available under the
55
// terms of the Eclipse Public License v. 2.0 which is available at
@@ -11,41 +11,35 @@
1111
// with the GNU Classpath Exception which is available at
1212
// https://www.gnu.org/software/classpath/license.html.
1313
//
14-
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
14+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
1515
// *****************************************************************************
1616

17-
import { defineConfig } from '@playwright/test';
17+
import { PlaywrightTestConfig } from '@playwright/test';
1818

19-
// Note: process.env.CI is always set to true for GitHub Actions
20-
21-
export default defineConfig({
22-
testDir: './lib/tests',
23-
testMatch: ['**/*.test.js'],
24-
workers: process.env.CI ? 1 : 2,
25-
retries: process.env.CI ? 1 : 0,
26-
// The number of times to repeat each test, useful for debugging flaky tests
27-
repeatEach: 1,
19+
const config: PlaywrightTestConfig = {
20+
testDir: '../lib/tests',
21+
testMatch: ['**/*.js'],
22+
workers: 1,
23+
fullyParallel: false,
2824
// Timeout for each test in milliseconds.
29-
timeout: 30 * 1000,
25+
timeout: 60 * 1000,
3026
use: {
3127
baseURL: 'http://localhost:3000',
3228
browserName: 'chromium',
33-
screenshot: 'only-on-failure',
3429
permissions: ['clipboard-read'],
35-
viewport: { width: 1920, height: 1080 },
36-
},
37-
snapshotDir: './src/tests/snapshots',
38-
expect: {
39-
toMatchSnapshot: { threshold: 0.01 }
30+
screenshot: 'only-on-failure'
4031
},
4132
preserveOutput: 'failures-only',
42-
reporter: process.env.CI
43-
? [['list'], ['allure-playwright'], ['github']]
44-
: [['list'], ['allure-playwright']],
33+
reporter: [
34+
['list'],
35+
['allure-playwright']
36+
],
4537
// Reuse Theia backend on port 3000 or start instance before executing the tests
4638
webServer: {
4739
command: 'yarn theia:start',
4840
port: 3000,
4941
reuseExistingServer: true
5042
}
51-
});
43+
};
44+
45+
export default config;

examples/playwright/src/tests/fixtures/theia-fixture.ts renamed to examples/playwright/configs/playwright.debug.config.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@
1111
// with the GNU Classpath Exception which is available at
1212
// https://www.gnu.org/software/classpath/license.html.
1313
//
14-
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
14+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
1515
// *****************************************************************************
1616

17-
import test, { Page } from '@playwright/test';
17+
import { PlaywrightTestConfig } from '@playwright/test';
1818

19-
export let page: Page;
19+
import baseConfig from './playwright.config';
2020

21-
test.beforeAll(async ({ browser }) => {
22-
page = await browser.newPage();
23-
});
21+
const debugConfig: PlaywrightTestConfig = {
22+
...baseConfig,
23+
workers: 1,
24+
timeout: 15000000
25+
};
2426

25-
export default test;
27+
export default debugConfig;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// *****************************************************************************
2+
// Copyright (C) 2021 logi.cals GmbH, EclipseSource and others.
3+
//
4+
// This program and the accompanying materials are made available under the
5+
// terms of the Eclipse Public License v. 2.0 which is available at
6+
// http://www.eclipse.org/legal/epl-2.0.
7+
//
8+
// This Source Code may also be made available under the following Secondary
9+
// Licenses when the conditions for such availability set forth in the Eclipse
10+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
11+
// with the GNU Classpath Exception which is available at
12+
// https://www.gnu.org/software/classpath/license.html.
13+
//
14+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
// *****************************************************************************
16+
17+
import { PlaywrightTestConfig } from '@playwright/test';
18+
19+
import baseConfig from './playwright.config';
20+
21+
const headfulConfig: PlaywrightTestConfig = {
22+
...baseConfig,
23+
workers: 1,
24+
use: {
25+
...baseConfig.use,
26+
headless: false
27+
}
28+
};
29+
30+
export default headfulConfig;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
// override existing rules for ui-tests package
3+
"rules": {
4+
"no-undef": "off", // disabled due to 'browser', '$', '$$'
5+
"no-unused-expressions": "off"
6+
}
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
// override existing rules for ui-tests playwright package
3+
"rules": {
4+
"no-null/no-null": "off"
5+
}
6+
}

examples/playwright/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
"lint": "eslint -c ./.eslintrc.js --ext .ts ./src",
2020
"lint:fix": "eslint -c ./.eslintrc.js --ext .ts ./src --fix",
2121
"playwright:install": "playwright install chromium",
22-
"ui-tests": "yarn build && playwright test",
23-
"ui-tests-headful": "yarn build && playwright test --headed",
22+
"ui-tests": "yarn build && playwright test --config=./configs/playwright.config.ts",
23+
"ui-tests-electron": "yarn build && USE_ELECTRON=true playwright test --config=./configs/playwright.config.ts",
24+
"ui-tests-ci": "yarn build && playwright test --config=./configs/playwright.ci.config.ts",
25+
"ui-tests-headful": "yarn build && playwright test --config=./configs/playwright.headful.config.ts",
2426
"ui-tests-report-generate": "allure generate ./allure-results --clean -o allure-results/allure-report",
2527
"ui-tests-report": "yarn ui-tests-report-generate && allure open allure-results/allure-report"
2628
},

examples/playwright/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
export * from './theia-about-dialog';
1818
export * from './theia-app';
19+
export * from './theia-app-loader';
1920
export * from './theia-context-menu';
2021
export * from './theia-dialog';
2122
export * from './theia-editor';

examples/playwright/src/tests/theia-app.test.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,19 @@
1414
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
1515
// *****************************************************************************
1616

17+
import { expect, test } from '@playwright/test';
18+
import { TheiaAppLoader } from '../theia-app-loader';
1719
import { TheiaApp } from '../theia-app';
1820

19-
import { expect } from '@playwright/test';
20-
import test, { page } from './fixtures/theia-fixture';
21-
22-
let app: TheiaApp;
23-
2421
test.describe('Theia Application', () => {
22+
let app: TheiaApp;
2523

26-
test('should load', async () => {
27-
app = await TheiaApp.load(page);
24+
test.afterAll(async () => {
25+
await app.page.close();
2826
});
2927

30-
test('should show main content panel', async () => {
28+
test('should load and should show main content panel', async ({ playwright, browser }) => {
29+
app = await TheiaAppLoader.load({ playwright, browser });
3130
expect(await app.isMainContentPanelVisible()).toBe(true);
3231
});
3332

0 commit comments

Comments
 (0)