mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
test: add electron test (#1840)
This commit is contained in:
69
.github/workflows/build.yml
vendored
69
.github/workflows/build.yml
vendored
@@ -17,16 +17,6 @@ jobs:
|
|||||||
uses: ./.github/actions/setup-node
|
uses: ./.github/actions/setup-node
|
||||||
- run: yarn lint --max-warnings=0
|
- run: yarn lint --max-warnings=0
|
||||||
|
|
||||||
install-all:
|
|
||||||
name: Install All Dependencies
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
environment: development
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Install All Dependencies
|
|
||||||
uses: ./.github/actions/setup-node
|
|
||||||
|
|
||||||
build-storybook:
|
build-storybook:
|
||||||
name: Build Storybook
|
name: Build Storybook
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -44,6 +34,23 @@ jobs:
|
|||||||
path: ./packages/component/storybook-static
|
path: ./packages/component/storybook-static
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
build-electron:
|
||||||
|
name: Build @affine/electron
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: development
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: ./.github/actions/setup-node
|
||||||
|
- name: Build Electron
|
||||||
|
working-directory: apps/electron
|
||||||
|
run: yarn exec ts-node-esm ./scripts/build-ci.mts
|
||||||
|
- name: Upload Ubuntu desktop artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: affine-ubuntu
|
||||||
|
path: ./apps/electron/dist
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build @affine/web
|
name: Build @affine/web
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -230,6 +237,48 @@ jobs:
|
|||||||
path: ./test-results
|
path: ./test-results
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
|
|
||||||
|
dekstop-test:
|
||||||
|
name: Desktop Test
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
environment: development
|
||||||
|
needs: [build, build-electron]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: ./.github/actions/setup-node
|
||||||
|
with:
|
||||||
|
playwright-install: true
|
||||||
|
- name: Download Ubuntu desktop artifact
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: affine-ubuntu
|
||||||
|
path: ./apps/electron/dist
|
||||||
|
|
||||||
|
- name: Download artifact
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: next-js
|
||||||
|
path: ./apps/web/.next
|
||||||
|
|
||||||
|
- name: Generate static files
|
||||||
|
run: yarn export
|
||||||
|
working-directory: ./apps/web
|
||||||
|
|
||||||
|
- name: Move static files to electron
|
||||||
|
run: mv ./apps/web/out ./apps/electron/resources/web-static
|
||||||
|
|
||||||
|
- name: Run desktop tests
|
||||||
|
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn test
|
||||||
|
working-directory: apps/electron
|
||||||
|
|
||||||
|
- name: Upload test results
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: test-results-e2e-${{ matrix.shard }}
|
||||||
|
path: ./test-results
|
||||||
|
if-no-files-found: ignore
|
||||||
|
|
||||||
unit-test:
|
unit-test:
|
||||||
name: Unit Test
|
name: Unit Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -134,7 +134,6 @@ We would like to express our gratitude to all the individuals who have already c
|
|||||||
<img src="https://user-images.githubusercontent.com/5910926/233382206-312428ca-094a-4579-ae06-213961ed7eab.svg" />
|
<img src="https://user-images.githubusercontent.com/5910926/233382206-312428ca-094a-4579-ae06-213961ed7eab.svg" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
## Self-Host
|
## Self-Host
|
||||||
|
|
||||||
Get started with Docker and deploy your own feature-rich, restriction-free deployment of AFFiNE - check the [latest packages].
|
Get started with Docker and deploy your own feature-rich, restriction-free deployment of AFFiNE - check the [latest packages].
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import { join } from 'path';
|
|||||||
import { logger } from '../../logger';
|
import { logger } from '../../logger';
|
||||||
import { isMacOS } from '../../utils';
|
import { isMacOS } from '../../utils';
|
||||||
|
|
||||||
const IS_DEV = process.env.NODE_ENV === 'development';
|
const IS_DEV: boolean =
|
||||||
|
process.env.NODE_ENV === 'development' && !process.env.CI;
|
||||||
|
|
||||||
async function createWindow() {
|
async function createWindow() {
|
||||||
logger.info('create window');
|
logger.info('create window');
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
"make-windows-x64": "electron-forge make --platform=win32 --arch=x64",
|
"make-windows-x64": "electron-forge make --platform=win32 --arch=x64",
|
||||||
"make-linux-x64": "electron-forge make --platform=linux --arch=x64",
|
"make-linux-x64": "electron-forge make --platform=linux --arch=x64",
|
||||||
"rebuild:for-test": "yarn rebuild better-sqlite3",
|
"rebuild:for-test": "yarn rebuild better-sqlite3",
|
||||||
"rebuild:for-electron": "yarn electron-rebuild"
|
"rebuild:for-electron": "yarn electron-rebuild",
|
||||||
|
"test": "playwright test"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"forge": "./forge.config.js"
|
"forge": "./forge.config.js"
|
||||||
@@ -42,6 +43,8 @@
|
|||||||
"electron-window-state": "^5.0.3",
|
"electron-window-state": "^5.0.3",
|
||||||
"esbuild": "^0.17.18",
|
"esbuild": "^0.17.18",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
|
"playwright": "^1.32.3",
|
||||||
|
"ts-node": "^10.9.1",
|
||||||
"undici": "^5.22.0",
|
"undici": "^5.22.0",
|
||||||
"zx": "^7.2.1"
|
"zx": "^7.2.1"
|
||||||
},
|
},
|
||||||
@@ -62,5 +65,9 @@
|
|||||||
"stableVersion": "0.5.3",
|
"stableVersion": "0.5.3",
|
||||||
"installConfig": {
|
"installConfig": {
|
||||||
"hoistingLimits": "workspaces"
|
"hoistingLimits": "workspaces"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"playwright": "*",
|
||||||
|
"ts-node": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
apps/electron/playwright.config.ts
Normal file
27
apps/electron/playwright.config.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import type { PlaywrightTestConfig } from '@playwright/test';
|
||||||
|
// import { devices } from '@playwright/test';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read environment variables from file.
|
||||||
|
* https://github.com/motdotla/dotenv
|
||||||
|
*/
|
||||||
|
// require('dotenv').config();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See https://playwright.dev/docs/test-configuration.
|
||||||
|
*/
|
||||||
|
const config: PlaywrightTestConfig = {
|
||||||
|
testDir: './tests',
|
||||||
|
fullyParallel: true,
|
||||||
|
timeout: process.env.CI ? 50_000 : 30_000,
|
||||||
|
use: {
|
||||||
|
viewport: { width: 1440, height: 800 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (process.env.CI) {
|
||||||
|
config.retries = 3;
|
||||||
|
config.workers = '50%';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config;
|
||||||
17
apps/electron/scripts/build-ci.mts
Executable file
17
apps/electron/scripts/build-ci.mts
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env ts-node-esm
|
||||||
|
import * as esbuild from 'esbuild';
|
||||||
|
|
||||||
|
import { config } from './common.mjs';
|
||||||
|
|
||||||
|
const common = config();
|
||||||
|
await esbuild.build(common.preload);
|
||||||
|
|
||||||
|
await esbuild.build({
|
||||||
|
...common.main,
|
||||||
|
define: {
|
||||||
|
...common.main.define,
|
||||||
|
'process.env.NODE_ENV': `"production"`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Compiled successfully.');
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
const NODE_MAJOR_VERSION = 18;
|
import { resolve } from 'node:path';
|
||||||
|
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
export const root = fileURLToPath(new URL('..', import.meta.url));
|
||||||
|
export const NODE_MAJOR_VERSION = 18;
|
||||||
|
|
||||||
const nativeNodeModulesPlugin = {
|
const nativeNodeModulesPlugin = {
|
||||||
name: 'native-node-modules',
|
name: 'native-node-modules',
|
||||||
@@ -14,7 +19,7 @@ const nativeNodeModulesPlugin = {
|
|||||||
const ENV_MACROS = ['AFFINE_GOOGLE_CLIENT_ID', 'AFFINE_GOOGLE_CLIENT_SECRET'];
|
const ENV_MACROS = ['AFFINE_GOOGLE_CLIENT_ID', 'AFFINE_GOOGLE_CLIENT_SECRET'];
|
||||||
|
|
||||||
/** @return {{main: import('esbuild').BuildOptions, preload: import('esbuild').BuildOptions}} */
|
/** @return {{main: import('esbuild').BuildOptions, preload: import('esbuild').BuildOptions}} */
|
||||||
export default () => {
|
export const config = () => {
|
||||||
const define = Object.fromEntries(
|
const define = Object.fromEntries(
|
||||||
ENV_MACROS.map(key => [
|
ENV_MACROS.map(key => [
|
||||||
'process.env.' + key,
|
'process.env.' + key,
|
||||||
@@ -23,8 +28,8 @@ export default () => {
|
|||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
main: {
|
main: {
|
||||||
entryPoints: ['layers/main/src/index.ts'],
|
entryPoints: [resolve(root, './layers/main/src/index.ts')],
|
||||||
outdir: 'dist/layers/main',
|
outdir: resolve(root, './dist/layers/main'),
|
||||||
bundle: true,
|
bundle: true,
|
||||||
target: `node${NODE_MAJOR_VERSION}`,
|
target: `node${NODE_MAJOR_VERSION}`,
|
||||||
platform: 'node',
|
platform: 'node',
|
||||||
@@ -33,8 +38,8 @@ export default () => {
|
|||||||
define: define,
|
define: define,
|
||||||
},
|
},
|
||||||
preload: {
|
preload: {
|
||||||
entryPoints: ['layers/preload/src/index.ts'],
|
entryPoints: [resolve(root, './layers/preload/src/index.ts')],
|
||||||
outdir: 'dist/layers/preload',
|
outdir: resolve(root, './dist/layers/preload'),
|
||||||
bundle: true,
|
bundle: true,
|
||||||
target: `node${NODE_MAJOR_VERSION}`,
|
target: `node${NODE_MAJOR_VERSION}`,
|
||||||
platform: 'node',
|
platform: 'node',
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
import { spawn } from 'node:child_process';
|
import { spawn } from 'node:child_process';
|
||||||
import { readFileSync } from 'node:fs';
|
import { readFileSync } from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
|
|
||||||
import electronPath from 'electron';
|
import electronPath from 'electron';
|
||||||
import * as esbuild from 'esbuild';
|
import * as esbuild from 'esbuild';
|
||||||
|
|
||||||
import commonFn from './common.mjs';
|
import { config, root } from './common.mjs';
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
|
||||||
const __dirname = path.dirname(__filename);
|
|
||||||
|
|
||||||
/** @type 'production' | 'development'' */
|
/** @type 'production' | 'development'' */
|
||||||
const mode = (process.env.NODE_ENV = process.env.NODE_ENV || 'development');
|
const mode = (process.env.NODE_ENV = process.env.NODE_ENV || 'development');
|
||||||
@@ -22,9 +18,9 @@ const stderrFilterPatterns = [
|
|||||||
/ExtensionLoadWarning/,
|
/ExtensionLoadWarning/,
|
||||||
];
|
];
|
||||||
|
|
||||||
// these are set before calling commonFn so we have a chance to override them
|
// these are set before calling `config`, so we have a chance to override them
|
||||||
try {
|
try {
|
||||||
const devJson = readFileSync(path.resolve(__dirname, '../dev.json'), 'utf-8');
|
const devJson = readFileSync(path.resolve(root, './dev.json'), 'utf-8');
|
||||||
const devEnv = JSON.parse(devJson);
|
const devEnv = JSON.parse(devJson);
|
||||||
Object.assign(process.env, devEnv);
|
Object.assign(process.env, devEnv);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -67,7 +63,7 @@ function spawnOrReloadElectron() {
|
|||||||
spawnProcess.on('exit', process.exit);
|
spawnProcess.on('exit', process.exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
const common = commonFn();
|
const common = config();
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
async function watchPreload(onInitialBuild) {
|
async function watchPreload(onInitialBuild) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import path from 'node:path';
|
|||||||
|
|
||||||
import * as esbuild from 'esbuild';
|
import * as esbuild from 'esbuild';
|
||||||
|
|
||||||
import commonFn from './common.mjs';
|
import { config } from './common.mjs';
|
||||||
|
|
||||||
const repoRootDir = path.join(__dirname, '..', '..', '..');
|
const repoRootDir = path.join(__dirname, '..', '..', '..');
|
||||||
const electronRootDir = path.join(__dirname, '..');
|
const electronRootDir = path.join(__dirname, '..');
|
||||||
@@ -77,7 +77,7 @@ async function cleanup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function buildLayers() {
|
async function buildLayers() {
|
||||||
const common = commonFn();
|
const common = config();
|
||||||
await esbuild.build(common.preload);
|
await esbuild.build(common.preload);
|
||||||
|
|
||||||
await esbuild.build({
|
await esbuild.build({
|
||||||
|
|||||||
22
apps/electron/tests/basic.spec.ts
Normal file
22
apps/electron/tests/basic.spec.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { resolve } from 'node:path';
|
||||||
|
|
||||||
|
import { expect, test } from '@playwright/test';
|
||||||
|
import { _electron as electron } from 'playwright';
|
||||||
|
|
||||||
|
test('new page', async () => {
|
||||||
|
const electronApp = await electron.launch({
|
||||||
|
args: [resolve(__dirname, '..')],
|
||||||
|
executablePath: resolve(__dirname, '../node_modules/.bin/electron'),
|
||||||
|
});
|
||||||
|
const page = await electronApp.firstWindow();
|
||||||
|
await page.getByTestId('new-page-button').click({
|
||||||
|
delay: 100,
|
||||||
|
});
|
||||||
|
await page.waitForSelector('v-line');
|
||||||
|
const flavour = await page.evaluate(
|
||||||
|
// @ts-expect-error
|
||||||
|
() => globalThis.currentWorkspace.flavour
|
||||||
|
);
|
||||||
|
expect(flavour).toBe('local');
|
||||||
|
await electronApp.close();
|
||||||
|
});
|
||||||
8
apps/electron/tests/tsconfig.json
Normal file
8
apps/electron/tests/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"noEmit": true
|
||||||
|
},
|
||||||
|
"include": ["**.spec.ts", "**.test.ts"]
|
||||||
|
}
|
||||||
27
apps/electron/tsconfig.json
Normal file
27
apps/electron/tsconfig.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"isolatedModules": false,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"types": ["node"],
|
||||||
|
"outDir": "dist",
|
||||||
|
"noEmit": false
|
||||||
|
},
|
||||||
|
"include": ["layers", "types", "package.json"],
|
||||||
|
"exclude": ["out", "dist", "node_modules"],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ts-node": {
|
||||||
|
"esm": true,
|
||||||
|
"experimentalSpecifierResolution": "node"
|
||||||
|
}
|
||||||
|
}
|
||||||
11
apps/electron/tsconfig.node.json
Normal file
11
apps/electron/tsconfig.node.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"include": ["./scripts", "package.json"]
|
||||||
|
}
|
||||||
@@ -37,7 +37,7 @@ export const ChangeLog = () => {
|
|||||||
<StyledChangeLogWrapper isClose={isClose}>
|
<StyledChangeLogWrapper isClose={isClose}>
|
||||||
<StyledChangeLog data-testid="change-log" isClose={isClose}>
|
<StyledChangeLog data-testid="change-log" isClose={isClose}>
|
||||||
<StyledLink
|
<StyledLink
|
||||||
href='https://github.com/toeverything/AFFiNE/releases'
|
href="https://github.com/toeverything/AFFiNE/releases"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<NewIcon />
|
<NewIcon />
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import { config } from '@affine/env';
|
import { config } from '@affine/env';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
import { WorkspaceFlavour } from '@affine/workspace/type';
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
|
|||||||
@@ -37,6 +37,9 @@
|
|||||||
{
|
{
|
||||||
"path": "./tests"
|
"path": "./tests"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "./apps/electron/tests"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "./apps/web"
|
"path": "./apps/web"
|
||||||
},
|
},
|
||||||
@@ -66,6 +69,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "./tsconfig.node.json"
|
"path": "./tsconfig.node.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./apps/electron"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"files": [],
|
"files": [],
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ export default defineConfig({
|
|||||||
'packages/**/*.spec.tsx',
|
'packages/**/*.spec.tsx',
|
||||||
'apps/web/**/*.spec.ts',
|
'apps/web/**/*.spec.ts',
|
||||||
'apps/web/**/*.spec.tsx',
|
'apps/web/**/*.spec.tsx',
|
||||||
'apps/electron/**/*.spec.ts',
|
|
||||||
'tests/unit/**/*.spec.ts',
|
'tests/unit/**/*.spec.ts',
|
||||||
'tests/unit/**/*.spec.tsx',
|
'tests/unit/**/*.spec.tsx',
|
||||||
],
|
],
|
||||||
|
exclude: ['**/node_modules', '**/dist', '**/build', '**/out'],
|
||||||
testTimeout: 5000,
|
testTimeout: 5000,
|
||||||
coverage: {
|
coverage: {
|
||||||
provider: 'istanbul', // or 'c8'
|
provider: 'istanbul', // or 'c8'
|
||||||
|
|||||||
@@ -132,9 +132,14 @@ __metadata:
|
|||||||
electron-window-state: ^5.0.3
|
electron-window-state: ^5.0.3
|
||||||
esbuild: ^0.17.18
|
esbuild: ^0.17.18
|
||||||
fs-extra: ^11.1.1
|
fs-extra: ^11.1.1
|
||||||
|
playwright: ^1.32.3
|
||||||
|
ts-node: ^10.9.1
|
||||||
undici: ^5.22.0
|
undici: ^5.22.0
|
||||||
yjs: ^13.6.0
|
yjs: ^13.6.0
|
||||||
zx: ^7.2.1
|
zx: ^7.2.1
|
||||||
|
peerDependencies:
|
||||||
|
playwright: "*"
|
||||||
|
ts-node: "*"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@@ -18914,7 +18919,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"playwright@npm:^1.14.0":
|
"playwright@npm:^1.14.0, playwright@npm:^1.32.3":
|
||||||
version: 1.32.3
|
version: 1.32.3
|
||||||
resolution: "playwright@npm:1.32.3"
|
resolution: "playwright@npm:1.32.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user