Skip to content

Commit bd1a984

Browse files
authored
test(e2e): add e2e test case (#5)
* test(e2e): add e2e test case * chore: test case * chore: test case * chore(ci): playwright test * chore: use package * chore: deps * fix: reportHTMLUrl * chore: report html * chore: e2e test * chore(e2e): test cases * chore(ci): add test case * chore: cross-env * chore: unused package step
1 parent 05b0478 commit bd1a984

File tree

16 files changed

+239
-112
lines changed

16 files changed

+239
-112
lines changed

.github/workflows/e2e.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
on:
2+
pull_request:
3+
types: [opened, synchronize, reopened]
4+
push:
5+
branches:
6+
- 'main'
7+
8+
name: CI E2E
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}-test
11+
cancel-in-progress: true
12+
env:
13+
CI: e2e
14+
NODE_OPTIONS: --max-old-space-size=8192
15+
HUSKY: 0
16+
17+
jobs:
18+
e2e:
19+
name: E2E
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
os: [macos-latest, windows-latest]
24+
runs-on: ${{ matrix.os }}
25+
steps:
26+
- uses: actions/checkout@v4
27+
- name: Install pnpm
28+
run: npm install -g pnpm@9
29+
- uses: actions/setup-node@v4
30+
with:
31+
node-version: 20
32+
cache: 'pnpm'
33+
- name: Install Python setuptools
34+
if: matrix.os == 'macos-latest'
35+
run: brew install python-setuptools
36+
- name: Install appdmg
37+
if: matrix.os == 'macos-latest'
38+
run: npm install -g appdmg
39+
- name: Install dependencies
40+
run: pnpm install
41+
- name: Run e2e
42+
run: pnpm run test:e2e

.github/workflows/test.yml

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
branches:
66
- 'main'
77

8-
name: CI Test, Typecheck, Build
8+
name: CI Test, Typecheck
99
concurrency:
1010
group: ${{ github.workflow }}-${{ github.ref }}-test
1111
cancel-in-progress: true
@@ -33,26 +33,3 @@ jobs:
3333
run: pnpm run typecheck
3434
- name: Run test
3535
run: pnpm run test
36-
37-
build:
38-
name: Build
39-
strategy:
40-
matrix:
41-
os: [macos-latest]
42-
runs-on: ${{ matrix.os }}
43-
steps:
44-
- uses: actions/checkout@v4
45-
- name: Install pnpm
46-
run: npm install -g pnpm@9
47-
- uses: actions/setup-node@v4
48-
with:
49-
node-version: 20
50-
cache: 'pnpm'
51-
- name: Install Python setuptools
52-
run: brew install python-setuptools
53-
- name: Install appdmg
54-
run: npm install -g appdmg
55-
- name: Install dependencies
56-
run: pnpm install
57-
- name: Run build
58-
run: pnpm run build

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ out
55
*.log*
66
.eslintcache
77
.env
8-
resources/report.html
8+
test-results/

.lintstagedrc.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
15
export default {
26
'**/*.{ts,tsx}': ['npx prettier --write'],
37
'src/{main,preload}/**/*.{ts,tsx}': [() => 'npm run typecheck:node'],

e2e/app.test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import {
6+
ElectronApplication,
7+
Page,
8+
_electron as electron,
9+
expect,
10+
test,
11+
} from '@playwright/test';
12+
import { findLatestBuild, parseElectronApp } from 'electron-playwright-helpers';
13+
14+
let electronApp: ElectronApplication;
15+
let page: Page;
16+
17+
test.beforeAll(async () => {
18+
const latestBuild = findLatestBuild();
19+
const { executable: executablePath, main } = parseElectronApp(latestBuild);
20+
console.log('executablePath:', executablePath, '\nmain:', main);
21+
process.env.CI = 'e2e';
22+
electronApp = await electron.launch({
23+
args: [main],
24+
executablePath,
25+
env: {
26+
...process.env,
27+
CI: 'e2e',
28+
},
29+
});
30+
31+
page = await electronApp.firstWindow();
32+
electronApp.on('window', async (page) => {
33+
const filename = page.url()?.split('/').pop();
34+
console.log(`Window opened: ${filename}`);
35+
36+
// capture errors
37+
page.on('pageerror', (error) => {
38+
console.error(error);
39+
});
40+
// capture console messages
41+
page.on('console', (msg) => {
42+
console.log(msg.text());
43+
});
44+
});
45+
});
46+
47+
test.afterAll(async () => {
48+
await electronApp?.close();
49+
});
50+
51+
test('app can launch', async () => {
52+
await page.waitForLoadState('domcontentloaded');
53+
54+
const buttonElement = await page.$('button');
55+
expect(await buttonElement?.isVisible()).toBe(true);
56+
});

e2e/vitest.config.mts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import { resolve } from 'node:path';
6+
import { fileURLToPath } from 'node:url';
7+
8+
import tsconfigPath from 'vite-tsconfig-paths';
9+
import { defineProject } from 'vitest/config';
10+
11+
const __dirname = fileURLToPath(new URL('.', import.meta.url));
12+
13+
export default defineProject({
14+
root: __dirname,
15+
test: {
16+
globals: true,
17+
setupFiles: [],
18+
environment: 'node',
19+
includeSource: [resolve(__dirname, '.')],
20+
testTimeout: 15 * 1000,
21+
},
22+
23+
plugins: [
24+
tsconfigPath({
25+
projects: ['../tsconfig.node.json'],
26+
}),
27+
],
28+
});

forge.config.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,20 @@ const config: ForgeConfig = {
154154
new AutoUnpackNativesPlugin({}),
155155
// Fuses are used to enable/disable various Electron functionality
156156
// at package time, before code signing the application
157-
new FusesPlugin({
158-
version: FuseVersion.V1,
159-
[FuseV1Options.RunAsNode]: false,
160-
[FuseV1Options.EnableCookieEncryption]: true,
161-
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
162-
[FuseV1Options.EnableNodeCliInspectArguments]: false,
163-
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
164-
[FuseV1Options.OnlyLoadAppFromAsar]: true,
165-
}),
157+
// https://github.com/microsoft/playwright/issues/28669#issuecomment-2268380066
158+
...(process.env.CI === 'e2e'
159+
? []
160+
: [
161+
new FusesPlugin({
162+
version: FuseVersion.V1,
163+
[FuseV1Options.RunAsNode]: false,
164+
[FuseV1Options.EnableCookieEncryption]: true,
165+
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
166+
[FuseV1Options.EnableNodeCliInspectArguments]: false,
167+
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
168+
[FuseV1Options.OnlyLoadAppFromAsar]: true,
169+
}),
170+
]),
166171
],
167172
};
168173

package.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@
1919
"debug:w": "electron-vite dev -w --sourcemap --remote-debugging-port=9222",
2020
"dev:w": "electron-vite dev -w",
2121
"asar:analyze": "asar extract out/UI\\ TARS-darwin-arm64/UI\\ TARS.app/Contents/Resources/app.asar ./dist/asar",
22-
"package": "electron-forge package dist",
22+
"package": "electron-forge package",
2323
"clean": "rimraf dist out",
2424
"test": "vitest",
25+
"pretest:e2e": "npm run build:dist && cross-env CI=e2e npm run package",
26+
"test:e2e": "playwright test",
2527
"build:deps": "pnpm --filter \"!ui-tars-desktop,ui-tars-desktop...\" build && cd packages/visualizer && pnpm install --ignore-workspace",
26-
"build": "pnpm run clean && pnpm run build:deps && pnpm run typecheck && cross-env NODE_ENV=production electron-vite build && electron-forge make --enable-logging",
28+
"build:dist": "cross-env NODE_ENV=production electron-vite build",
29+
"build": "npm run clean && npm run build:deps && npm run typecheck && cross-env NODE_ENV=production electron-vite build && electron-forge make --enable-logging",
30+
"make": "electron-forge make",
2731
"publish:mac-x64": "npm run build && electron-forge publish --arch=x64 --platform=darwin",
2832
"publish:mac-arm64": "npm run build && electron-forge publish --arch=arm64 --platform=darwin",
2933
"publish:win32": "npm run build && electron-forge publish --arch=x64 --platform=win32",
@@ -32,9 +36,8 @@
3236
"prepare": "husky"
3337
},
3438
"dependencies": {
35-
"@computer-use/nut-js": "^4.2.0",
3639
"@computer-use/node-mac-permissions": "2.2.2",
37-
"mac-screen-capture-permissions": "2.1.0",
40+
"@computer-use/nut-js": "^4.2.0",
3841
"@electron-toolkit/preload": "^3.0.1",
3942
"@electron-toolkit/utils": "^3.0.0",
4043
"@electron/notarize": "^2.3.2",
@@ -50,6 +53,7 @@
5053
"electron-updater": "^6.1.4",
5154
"js-yaml": "^4.1.0",
5255
"lodash-es": "4.17.21",
56+
"mac-screen-capture-permissions": "2.1.0",
5357
"ms": "^2.1.3",
5458
"openai": "4.73.0",
5559
"react-use": "^17.6.0",
@@ -95,6 +99,7 @@
9599
"@electron/fuses": "^1.8.0",
96100
"@emotion/react": "^11.13.3",
97101
"@emotion/styled": "^11.13.0",
102+
"@playwright/test": "^1.49.1",
98103
"@trivago/prettier-plugin-sort-imports": "^5.2.1",
99104
"@types/node": "^20.14.8",
100105
"@types/react": "^18.3.3",
@@ -107,6 +112,7 @@
107112
"cross-env": "^7.0.3",
108113
"electron": "34.0.0",
109114
"electron-packager-languages": "0.5.0",
115+
"electron-playwright-helpers": "^1.7.1",
110116
"electron-vite": "^2.3.0",
111117
"eslint": "^8.57.0",
112118
"eslint-plugin-import": "^2.25.0",

playwright.config.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import { defineConfig } from '@playwright/test';
6+
7+
export default defineConfig({
8+
testDir: './e2e',
9+
fullyParallel: true,
10+
retries: process.env.CI ? 2 : 0,
11+
workers: 1,
12+
use: {
13+
trace: 'on-first-retry',
14+
},
15+
timeout: 60000,
16+
});

pnpm-lock.yaml

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/xxx.jpg

-17.8 MB
Binary file not shown.

0 commit comments

Comments
 (0)