Skip to content

test(e2e): add e2e test case #5

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

Merged
merged 13 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
42 changes: 42 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches:
- 'main'

name: CI E2E
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-test
cancel-in-progress: true
env:
CI: e2e
NODE_OPTIONS: --max-old-space-size=8192
HUSKY: 0

jobs:
e2e:
name: E2E
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install pnpm
run: npm install -g pnpm@9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install Python setuptools
if: matrix.os == 'macos-latest'
run: brew install python-setuptools
- name: Install appdmg
if: matrix.os == 'macos-latest'
run: npm install -g appdmg
- name: Install dependencies
run: pnpm install
- name: Run e2e
run: pnpm run test:e2e
25 changes: 1 addition & 24 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- 'main'

name: CI Test, Typecheck, Build
name: CI Test, Typecheck
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-test
cancel-in-progress: true
Expand Down Expand Up @@ -33,26 +33,3 @@ jobs:
run: pnpm run typecheck
- name: Run test
run: pnpm run test

build:
name: Build
strategy:
matrix:
os: [macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install pnpm
run: npm install -g pnpm@9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install Python setuptools
run: brew install python-setuptools
- name: Install appdmg
run: npm install -g appdmg
- name: Install dependencies
run: pnpm install
- name: Run build
run: pnpm run build
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ out
*.log*
.eslintcache
.env
resources/report.html
test-results/
4 changes: 4 additions & 0 deletions .lintstagedrc.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
* SPDX-License-Identifier: Apache-2.0
*/
export default {
'**/*.{ts,tsx}': ['npx prettier --write'],
'src/{main,preload}/**/*.{ts,tsx}': [() => 'npm run typecheck:node'],
Expand Down
56 changes: 56 additions & 0 deletions e2e/app.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
* SPDX-License-Identifier: Apache-2.0
*/
import {
ElectronApplication,
Page,
_electron as electron,
expect,
test,
} from '@playwright/test';
import { findLatestBuild, parseElectronApp } from 'electron-playwright-helpers';

let electronApp: ElectronApplication;
let page: Page;

test.beforeAll(async () => {
const latestBuild = findLatestBuild();
const { executable: executablePath, main } = parseElectronApp(latestBuild);
console.log('executablePath:', executablePath, '\nmain:', main);
process.env.CI = 'e2e';
electronApp = await electron.launch({
args: [main],
executablePath,
env: {
...process.env,
CI: 'e2e',
},
});

page = await electronApp.firstWindow();
electronApp.on('window', async (page) => {
const filename = page.url()?.split('/').pop();
console.log(`Window opened: ${filename}`);

// capture errors
page.on('pageerror', (error) => {
console.error(error);
});
// capture console messages
page.on('console', (msg) => {
console.log(msg.text());
});
});
});

test.afterAll(async () => {
await electronApp?.close();
});

test('app can launch', async () => {
await page.waitForLoadState('domcontentloaded');

const buttonElement = await page.$('button');
expect(await buttonElement?.isVisible()).toBe(true);
});
28 changes: 28 additions & 0 deletions e2e/vitest.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
* SPDX-License-Identifier: Apache-2.0
*/
import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';

import tsconfigPath from 'vite-tsconfig-paths';
import { defineProject } from 'vitest/config';

const __dirname = fileURLToPath(new URL('.', import.meta.url));

export default defineProject({
root: __dirname,
test: {
globals: true,
setupFiles: [],
environment: 'node',
includeSource: [resolve(__dirname, '.')],
testTimeout: 15 * 1000,
},

plugins: [
tsconfigPath({
projects: ['../tsconfig.node.json'],
}),
],
});
23 changes: 14 additions & 9 deletions forge.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,20 @@ const config: ForgeConfig = {
new AutoUnpackNativesPlugin({}),
// Fuses are used to enable/disable various Electron functionality
// at package time, before code signing the application
new FusesPlugin({
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false,
[FuseV1Options.EnableCookieEncryption]: true,
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
[FuseV1Options.EnableNodeCliInspectArguments]: false,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
[FuseV1Options.OnlyLoadAppFromAsar]: true,
}),
// https://github.com/microsoft/playwright/issues/28669#issuecomment-2268380066
...(process.env.CI === 'e2e'
? []
: [
new FusesPlugin({
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false,
[FuseV1Options.EnableCookieEncryption]: true,
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
[FuseV1Options.EnableNodeCliInspectArguments]: false,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
[FuseV1Options.OnlyLoadAppFromAsar]: true,
}),
]),
],
};

Expand Down
14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@
"debug:w": "electron-vite dev -w --sourcemap --remote-debugging-port=9222",
"dev:w": "electron-vite dev -w",
"asar:analyze": "asar extract out/UI\\ TARS-darwin-arm64/UI\\ TARS.app/Contents/Resources/app.asar ./dist/asar",
"package": "electron-forge package dist",
"package": "electron-forge package",
"clean": "rimraf dist out",
"test": "vitest",
"pretest:e2e": "npm run build:dist && cross-env CI=e2e npm run package",
"test:e2e": "playwright test",
"build:deps": "pnpm --filter \"!ui-tars-desktop,ui-tars-desktop...\" build && cd packages/visualizer && pnpm install --ignore-workspace",
"build": "pnpm run clean && pnpm run build:deps && pnpm run typecheck && cross-env NODE_ENV=production electron-vite build && electron-forge make --enable-logging",
"build:dist": "cross-env NODE_ENV=production electron-vite build",
"build": "npm run clean && npm run build:deps && npm run typecheck && cross-env NODE_ENV=production electron-vite build && electron-forge make --enable-logging",
"make": "electron-forge make",
"publish:mac-x64": "npm run build && electron-forge publish --arch=x64 --platform=darwin",
"publish:mac-arm64": "npm run build && electron-forge publish --arch=arm64 --platform=darwin",
"publish:win32": "npm run build && electron-forge publish --arch=x64 --platform=win32",
Expand All @@ -32,9 +36,8 @@
"prepare": "husky"
},
"dependencies": {
"@computer-use/nut-js": "^4.2.0",
"@computer-use/node-mac-permissions": "2.2.2",
"mac-screen-capture-permissions": "2.1.0",
"@computer-use/nut-js": "^4.2.0",
"@electron-toolkit/preload": "^3.0.1",
"@electron-toolkit/utils": "^3.0.0",
"@electron/notarize": "^2.3.2",
Expand All @@ -50,6 +53,7 @@
"electron-updater": "^6.1.4",
"js-yaml": "^4.1.0",
"lodash-es": "4.17.21",
"mac-screen-capture-permissions": "2.1.0",
"ms": "^2.1.3",
"openai": "4.73.0",
"react-use": "^17.6.0",
Expand Down Expand Up @@ -95,6 +99,7 @@
"@electron/fuses": "^1.8.0",
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@playwright/test": "^1.49.1",
"@trivago/prettier-plugin-sort-imports": "^5.2.1",
"@types/node": "^20.14.8",
"@types/react": "^18.3.3",
Expand All @@ -107,6 +112,7 @@
"cross-env": "^7.0.3",
"electron": "34.0.0",
"electron-packager-languages": "0.5.0",
"electron-playwright-helpers": "^1.7.1",
"electron-vite": "^2.3.0",
"eslint": "^8.57.0",
"eslint-plugin-import": "^2.25.0",
Expand Down
16 changes: 16 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Copyright (c) 2025 Bytedance, Inc. and its affiliates.
* SPDX-License-Identifier: Apache-2.0
*/
import { defineConfig } from '@playwright/test';

export default defineConfig({
testDir: './e2e',
fullyParallel: true,
retries: process.env.CI ? 2 : 0,
workers: 1,
use: {
trace: 'on-first-retry',
},
timeout: 60000,
});
48 changes: 48 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file removed scripts/xxx.jpg
Binary file not shown.
Loading
Loading