mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 04:18:54 +00:00
test(electron): add cloud test (#4184)
Co-authored-by: Peng Xiao <pengxiao@outlook.com>
This commit is contained in:
13
.github/workflows/build-desktop.yml
vendored
13
.github/workflows/build-desktop.yml
vendored
@@ -101,6 +101,7 @@ jobs:
|
||||
with:
|
||||
playwright-install: true
|
||||
hard-link-nm: false
|
||||
|
||||
- name: Build AFFiNE native
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
@@ -125,21 +126,15 @@ jobs:
|
||||
- name: Build Desktop Layers
|
||||
run: yarn workspace @affine/electron build
|
||||
|
||||
- name: Upload desktop dist
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: dist-${{ matrix.spec.platform }}-${{ matrix.spec.arch }}
|
||||
path: ./apps/electron/dist
|
||||
|
||||
- name: Run desktop tests
|
||||
if: ${{ matrix.spec.test && matrix.spec.os == 'ubuntu-latest' }}
|
||||
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn workspace @affine/electron test
|
||||
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn workspace @affine-test/affine-desktop e2e
|
||||
env:
|
||||
COVERAGE: true
|
||||
|
||||
- name: Run desktop tests
|
||||
if: ${{ matrix.spec.test && matrix.spec.os != 'ubuntu-latest' }}
|
||||
run: yarn workspace @affine/electron test
|
||||
run: yarn workspace @affine-test/affine-desktop e2e
|
||||
env:
|
||||
COVERAGE: true
|
||||
|
||||
@@ -149,7 +144,7 @@ jobs:
|
||||
SKIP_BUNDLE: true
|
||||
run: yarn workspace @affine/electron make --platform=darwin --arch=arm64
|
||||
|
||||
- name: Bundle output check
|
||||
- name: Output check
|
||||
if: ${{ matrix.spec.os == 'macos-latest' && matrix.spec.arch == 'arm64' }}
|
||||
run: |
|
||||
yarn ts-node-esm ./scripts/macos-arm64-output-check.mts
|
||||
|
||||
102
.github/workflows/build-server.yml
vendored
102
.github/workflows/build-server.yml
vendored
@@ -184,7 +184,7 @@ jobs:
|
||||
path: ./apps/server
|
||||
|
||||
- name: Run playwright tests
|
||||
run: yarn workspace @affine-test/affine-cloud e2e --forbid-only
|
||||
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- yarn workspace @affine-test/affine-cloud e2e --forbid-only
|
||||
env:
|
||||
COVERAGE: true
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
@@ -208,3 +208,103 @@ jobs:
|
||||
name: test-results-e2e-server
|
||||
path: ./tests/affine-cloud/test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
server-desktop-e2e-test:
|
||||
name: Server Desktop E2E Test
|
||||
runs-on: ubuntu-latest
|
||||
environment: development
|
||||
needs: build-storage
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: affine
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
mailer:
|
||||
image: mailhog/mailhog
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
playwright-install: true
|
||||
hard-link-nm: false
|
||||
|
||||
- name: Build AFFiNE native
|
||||
uses: ./.github/actions/build-rust
|
||||
with:
|
||||
target: x86_64-unknown-linux-gnu
|
||||
package: '@affine/native'
|
||||
nx_token: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
- name: Initialize database
|
||||
run: |
|
||||
psql -h localhost -U postgres -c "CREATE DATABASE affine;"
|
||||
psql -h localhost -U postgres -c "CREATE USER affine WITH PASSWORD 'affine';"
|
||||
psql -h localhost -U postgres -c "ALTER USER affine WITH SUPERUSER;"
|
||||
env:
|
||||
PGPASSWORD: affine
|
||||
|
||||
- name: Generate prisma client
|
||||
run: |
|
||||
yarn exec prisma generate
|
||||
yarn exec prisma db push
|
||||
working-directory: apps/server
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Run init-db script
|
||||
run: yarn exec ts-node-esm ./scripts/init-db.ts
|
||||
working-directory: apps/server
|
||||
env:
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
|
||||
- name: Download storage.node
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: storage.node
|
||||
path: ./apps/server
|
||||
|
||||
- name: Build Plugins
|
||||
run: yarn run build:plugins
|
||||
|
||||
- name: Build Desktop Layers
|
||||
run: yarn workspace @affine/electron build:dev
|
||||
|
||||
- name: Run playwright tests
|
||||
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" yarn workspace @affine-test/affine-desktop-cloud e2e
|
||||
env:
|
||||
COVERAGE: true
|
||||
DEV_SERVER_URL: http://localhost:8080
|
||||
DATABASE_URL: postgresql://affine:affine@localhost:5432/affine
|
||||
ENABLE_LOCAL_EMAIL: true
|
||||
|
||||
- name: Collect code coverage report
|
||||
run: yarn exec nyc report -t .nyc_output --report-dir .coverage --reporter=lcov
|
||||
|
||||
- name: Upload e2e test coverage results
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./.coverage/lcov.info
|
||||
flags: server-e2etest
|
||||
name: affine
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Upload test results
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-results-e2e-server
|
||||
path: ./tests/affine-cloud/test-results
|
||||
if-no-files-found: ignore
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import { execSync } from 'node:child_process';
|
||||
import { join } from 'node:path';
|
||||
|
||||
export default async function () {
|
||||
execSync('yarn ts-node-esm scripts/', {
|
||||
cwd: join(__dirname, '..'),
|
||||
});
|
||||
}
|
||||
@@ -14,10 +14,10 @@
|
||||
"dev": "yarn cross-env DEV_SERVER_URL=http://localhost:8080 node scripts/dev.mjs",
|
||||
"dev:prod": "yarn node scripts/dev.mjs",
|
||||
"build": "NODE_ENV=production zx scripts/build-layers.mjs",
|
||||
"build:dev": "NODE_ENV=development zx scripts/build-layers.mjs",
|
||||
"generate-assets": "zx scripts/generate-assets.mjs",
|
||||
"package": "electron-forge package",
|
||||
"make": "electron-forge make",
|
||||
"test": "DEBUG=pw:browser yarn -T run playwright test -c ./playwright.config.ts",
|
||||
"make-squirrel": "yarn ts-node-esm -T scripts/make-squirrel.mts"
|
||||
},
|
||||
"config": {
|
||||
@@ -43,7 +43,6 @@
|
||||
"@electron/remote": "2.0.11",
|
||||
"@reforged/maker-appimage": "^3.3.1",
|
||||
"@toeverything/infra": "workspace:*",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/uuid": "^9.0.3",
|
||||
"cross-env": "7.0.3",
|
||||
"electron": "^26.1.0",
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import path from 'node:path';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
|
||||
import { removeWithRetry } from '@affine-test/kit/utils/utils';
|
||||
import { v4 } from 'uuid';
|
||||
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
|
||||
|
||||
import { removeWithRetry } from '../../../../tests/utils';
|
||||
|
||||
const tmpDir = path.join(__dirname, 'tmp');
|
||||
const appDataPath = path.join(tmpDir, 'app-data');
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import path from 'node:path';
|
||||
|
||||
import { SqliteConnection } from '@affine/native';
|
||||
import { removeWithRetry } from '@affine-test/kit/utils/utils';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
import { applyUpdate, Doc as YDoc } from 'yjs';
|
||||
|
||||
import { removeWithRetry } from '../../../../tests/utils';
|
||||
import { copyToTemp, migrateToSubdocAndReplaceDatabase } from '../migration';
|
||||
|
||||
const tmpDir = path.join(__dirname, 'tmp');
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import path from 'node:path';
|
||||
|
||||
import { removeWithRetry } from '@affine-test/kit/utils/utils';
|
||||
import fs from 'fs-extra';
|
||||
import { v4 } from 'uuid';
|
||||
import { afterEach, expect, test, vi } from 'vitest';
|
||||
import { Doc as YDoc, encodeStateAsUpdate } from 'yjs';
|
||||
|
||||
import { removeWithRetry } from '../../../../tests/utils';
|
||||
import { dbSubjects } from '../subjects';
|
||||
|
||||
const tmpDir = path.join(__dirname, 'tmp');
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import path from 'node:path';
|
||||
|
||||
import { removeWithRetry } from '@affine-test/kit/utils/utils';
|
||||
import fs from 'fs-extra';
|
||||
import { v4 } from 'uuid';
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import { removeWithRetry } from '../../../../tests/utils';
|
||||
|
||||
const tmpDir = path.join(__dirname, 'tmp');
|
||||
const appDataPath = path.join(tmpDir, 'app-data');
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import assert from 'node:assert';
|
||||
import path from 'node:path';
|
||||
|
||||
import { removeWithRetry } from '@affine-test/kit/utils/utils';
|
||||
import fs from 'fs-extra';
|
||||
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import { removeWithRetry } from '../../../tests/utils';
|
||||
import type { MainIPCHandlerMap } from '../exposed';
|
||||
|
||||
const registeredHandlers = new Map<
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
|
||||
import fs from 'fs-extra';
|
||||
|
||||
export async function removeWithRetry(
|
||||
filePath: string,
|
||||
maxRetries = 5,
|
||||
delay = 500
|
||||
) {
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
await fs.remove(filePath);
|
||||
console.log(`File ${filePath} successfully deleted.`);
|
||||
return true;
|
||||
} catch (err: any) {
|
||||
if (err.code === 'EBUSY' || err.code === 'EPERM') {
|
||||
console.log(`File ${filePath} is busy or locked, retrying...`);
|
||||
await setTimeout(delay);
|
||||
} else {
|
||||
console.error(`Failed to delete file ${filePath}:`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add a return statement here to ensure that a value is always returned
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"types": ["node"],
|
||||
"outDir": "dist",
|
||||
"outDir": "lib",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"noImplicitOverride": true
|
||||
},
|
||||
"include": ["./src"],
|
||||
"exclude": ["node_modules", "out", "dist", "**/__tests__/**/*"],
|
||||
"exclude": ["node_modules", "lib", "dist", "**/__tests__/**/*"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../packages/infra"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"composite": true
|
||||
},
|
||||
"include": ["**/__tests__/**/*", "./tests", "./e2e"],
|
||||
"include": ["**/__tests__/**/*", "./tests"],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.json"
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
"tests/kit",
|
||||
"tests/affine-legacy/*",
|
||||
"tests/affine-local",
|
||||
"tests/affine-desktop",
|
||||
"tests/affine-desktop-cloud",
|
||||
"tests/affine-plugin",
|
||||
"tests/affine-prototype",
|
||||
"tests/affine-cloud"
|
||||
|
||||
34
tests/affine-desktop-cloud/e2e/basic.spec.ts
Normal file
34
tests/affine-desktop-cloud/e2e/basic.spec.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { test } from '@affine-test/kit/electron';
|
||||
import {
|
||||
createRandomUser,
|
||||
enableCloudWorkspace,
|
||||
loginUser,
|
||||
} from '@affine-test/kit/utils/cloud';
|
||||
import { waitForEditorLoad } from '@affine-test/kit/utils/page-logic';
|
||||
import { createLocalWorkspace } from '@affine-test/kit/utils/workspace';
|
||||
|
||||
let user: {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
test.beforeEach(async () => {
|
||||
user = await createRandomUser();
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await loginUser(page, user.email);
|
||||
});
|
||||
|
||||
test('new page', async ({ page }) => {
|
||||
await page.reload();
|
||||
await waitForEditorLoad(page);
|
||||
await createLocalWorkspace(
|
||||
{
|
||||
name: 'test',
|
||||
},
|
||||
page
|
||||
);
|
||||
await enableCloudWorkspace(page);
|
||||
});
|
||||
15
tests/affine-desktop-cloud/package.json
Normal file
15
tests/affine-desktop-cloud/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "@affine-test/affine-desktop-cloud",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"e2e": "DEBUG=pw:browser yarn playwright test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@affine-test/fixtures": "workspace:*",
|
||||
"@affine-test/kit": "workspace:*",
|
||||
"@playwright/test": "^1.37.1",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"fs-extra": "^11.1.1"
|
||||
},
|
||||
"version": "0.9.0-canary.8"
|
||||
}
|
||||
61
tests/affine-desktop-cloud/playwright.config.ts
Normal file
61
tests/affine-desktop-cloud/playwright.config.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
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: './e2e',
|
||||
fullyParallel: true,
|
||||
timeout: process.env.CI ? 50_000 : 30_000,
|
||||
use: {
|
||||
viewport: { width: 1440, height: 800 },
|
||||
},
|
||||
reporter: process.env.CI ? 'github' : 'list',
|
||||
webServer: [
|
||||
// Intentionally not building the web, reminds you to run it by yourself.
|
||||
{
|
||||
command: 'yarn -T run start:web-static',
|
||||
port: 8080,
|
||||
timeout: 120 * 1000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
env: {
|
||||
COVERAGE: process.env.COVERAGE || 'false',
|
||||
},
|
||||
},
|
||||
{
|
||||
command: 'yarn workspace @affine/server start',
|
||||
port: 3010,
|
||||
timeout: 120 * 1000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
stdout: 'pipe',
|
||||
stderr: 'pipe',
|
||||
env: {
|
||||
DATABASE_URL:
|
||||
process.env.DATABASE_URL ??
|
||||
'postgresql://affine:affine@localhost:5432/affine',
|
||||
NODE_ENV: 'development',
|
||||
AFFINE_ENV: process.env.AFFINE_ENV ?? 'dev',
|
||||
DEBUG: 'affine:*',
|
||||
FORCE_COLOR: 'true',
|
||||
DEBUG_COLORS: 'true',
|
||||
ENABLE_LOCAL_EMAIL: process.env.ENABLE_LOCAL_EMAIL ?? 'true',
|
||||
NEXTAUTH_URL: 'http://localhost:8080',
|
||||
OAUTH_EMAIL_SENDER: 'noreply@toeverything.info',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
if (process.env.CI) {
|
||||
config.retries = 3;
|
||||
config.workers = '50%';
|
||||
}
|
||||
|
||||
export default config;
|
||||
16
tests/affine-desktop-cloud/tsconfig.json
Normal file
16
tests/affine-desktop-cloud/tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["e2e"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../kit"
|
||||
},
|
||||
{
|
||||
"path": "../fixtures"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import { platform } from 'node:os';
|
||||
|
||||
import { test } from '@affine-test/kit/electron';
|
||||
import { clickSideBarSettingButton } from '@affine-test/kit/utils/sidebar';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
import { test } from './fixture';
|
||||
|
||||
test('new page', async ({ page, workspace }) => {
|
||||
await page.getByTestId('new-page-button').click({
|
||||
delay: 100,
|
||||
@@ -1,10 +1,9 @@
|
||||
import path from 'node:path';
|
||||
|
||||
import { test } from '@affine-test/kit/electron';
|
||||
import { expect } from '@playwright/test';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
import { test } from './fixture';
|
||||
|
||||
test('check workspace has a DB file', async ({ appInfo, workspace }) => {
|
||||
const w = await workspace.current();
|
||||
const dbPath = path.join(
|
||||
15
tests/affine-desktop/package.json
Normal file
15
tests/affine-desktop/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "@affine-test/affine-desktop",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"e2e": "DEBUG=pw:browser yarn playwright test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@affine-test/fixtures": "workspace:*",
|
||||
"@affine-test/kit": "workspace:*",
|
||||
"@playwright/test": "^1.37.1",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"fs-extra": "^11.1.1"
|
||||
},
|
||||
"version": "0.9.0-canary.8"
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import type { PlaywrightTestConfig } from '@playwright/test';
|
||||
*/
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: './e2e',
|
||||
testIgnore: '**/lib/**',
|
||||
fullyParallel: true,
|
||||
timeout: process.env.CI ? 50_000 : 30_000,
|
||||
use: {
|
||||
16
tests/affine-desktop/tsconfig.json
Normal file
16
tests/affine-desktop/tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["e2e"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../kit"
|
||||
},
|
||||
{
|
||||
"path": "../fixtures"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
/* eslint-disable no-empty-pattern */
|
||||
import crypto from 'node:crypto';
|
||||
import { join, resolve } from 'node:path';
|
||||
|
||||
import type { Page } from '@playwright/test';
|
||||
import fs from 'fs-extra';
|
||||
import type { ElectronApplication } from 'playwright';
|
||||
import { _electron as electron } from 'playwright';
|
||||
|
||||
import {
|
||||
enableCoverage,
|
||||
istanbulTempDir,
|
||||
test as base,
|
||||
testResultDir,
|
||||
} from '@affine-test/kit/playwright';
|
||||
import type { Page } from '@playwright/test';
|
||||
import fs from 'fs-extra';
|
||||
import type { ElectronApplication } from 'playwright';
|
||||
import { _electron as electron } from 'playwright';
|
||||
} from './playwright';
|
||||
import { removeWithRetry } from './utils/utils';
|
||||
|
||||
import { removeWithRetry } from '../tests/utils';
|
||||
const projectRoot = resolve(__dirname, '..', '..');
|
||||
const electronRoot = resolve(projectRoot, 'apps', 'electron');
|
||||
|
||||
function generateUUID() {
|
||||
return crypto.randomUUID();
|
||||
@@ -37,14 +39,7 @@ export const test = base.extend<{
|
||||
await page.getByTestId('onboarding-modal-close-button').click({
|
||||
delay: 100,
|
||||
});
|
||||
if (!process.env.CI) {
|
||||
await electronApp.evaluate(({ BrowserWindow }) => {
|
||||
BrowserWindow.getAllWindows()[0].webContents.openDevTools({
|
||||
mode: 'detach',
|
||||
});
|
||||
});
|
||||
}
|
||||
// wat for blocksuite to be loaded
|
||||
// wait for blocksuite to be loaded
|
||||
await page.waitForSelector('v-line');
|
||||
if (enableCoverage) {
|
||||
await fs.promises.mkdir(istanbulTempDir, { recursive: true });
|
||||
@@ -71,15 +66,16 @@ export const test = base.extend<{
|
||||
}
|
||||
await page.close();
|
||||
},
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
electronApp: async ({}, use) => {
|
||||
// a random id to avoid conflicts between tests
|
||||
const id = generateUUID();
|
||||
const ext = process.platform === 'win32' ? '.cmd' : '';
|
||||
const dist = resolve(__dirname, '..', 'dist');
|
||||
const clonedDist = resolve(__dirname, '../e2e-dist-' + id);
|
||||
const dist = resolve(electronRoot, 'dist');
|
||||
const clonedDist = resolve(electronRoot, 'e2e-dist-' + id);
|
||||
await fs.copy(dist, clonedDist);
|
||||
const packageJson = await fs.readJSON(
|
||||
resolve(__dirname, '..', 'package.json')
|
||||
resolve(electronRoot, 'package.json')
|
||||
);
|
||||
// overwrite the app name
|
||||
packageJson.name = 'affine-test-' + id;
|
||||
@@ -88,15 +84,27 @@ export const test = base.extend<{
|
||||
// write to the cloned dist
|
||||
await fs.writeJSON(resolve(clonedDist, 'package.json'), packageJson);
|
||||
|
||||
const env: Record<string, string> = {};
|
||||
for (const [key, value] of Object.entries(process.env)) {
|
||||
if (value) {
|
||||
env[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.DEV_SERVER_URL) {
|
||||
env.DEV_SERVER_URL = process.env.DEV_SERVER_URL;
|
||||
}
|
||||
|
||||
const electronApp = await electron.launch({
|
||||
args: [clonedDist],
|
||||
env,
|
||||
executablePath: resolve(
|
||||
__dirname,
|
||||
'..',
|
||||
electronRoot,
|
||||
'node_modules',
|
||||
'.bin',
|
||||
`electron${ext}`
|
||||
),
|
||||
cwd: clonedDist,
|
||||
recordVideo: {
|
||||
dir: testResultDir,
|
||||
},
|
||||
@@ -4,6 +4,7 @@
|
||||
"type": "module",
|
||||
"version": "0.9.0-canary.12",
|
||||
"exports": {
|
||||
"./electron": "./electron.ts",
|
||||
"./playwright": "./playwright.ts",
|
||||
"./utils/*": "./utils/*.ts"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
|
||||
import type { Page } from '@playwright/test';
|
||||
import fs from 'fs-extra';
|
||||
|
||||
export async function waitForLogMessage(
|
||||
page: Page,
|
||||
@@ -12,3 +15,26 @@ export async function waitForLogMessage(
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function removeWithRetry(
|
||||
filePath: string,
|
||||
maxRetries = 5,
|
||||
delay = 500
|
||||
) {
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
await fs.remove(filePath);
|
||||
console.log(`File ${filePath} successfully deleted.`);
|
||||
return true;
|
||||
} catch (err: any) {
|
||||
if (err.code === 'EBUSY' || err.code === 'EPERM') {
|
||||
console.log(`File ${filePath} is busy or locked, retrying...`);
|
||||
await setTimeout(delay);
|
||||
} else {
|
||||
console.error(`Failed to delete file ${filePath}:`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add a return statement here to ensure that a value is always returned
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,20 @@ export async function createLocalWorkspace(
|
||||
// open create workspace modal
|
||||
await page.getByTestId('new-workspace').click();
|
||||
|
||||
const isDesktop: boolean = await page.evaluate(() => {
|
||||
return !!window.appInfo?.electron;
|
||||
}, []);
|
||||
|
||||
// input workspace name
|
||||
await page.getByPlaceholder('Set a Workspace name').click();
|
||||
await page.getByPlaceholder('Set a Workspace name').fill(params.name);
|
||||
|
||||
// click create button
|
||||
return page.getByRole('button', { name: 'Create' }).click({
|
||||
await page.getByRole('button', { name: 'Create' }).click({
|
||||
delay: 500,
|
||||
});
|
||||
|
||||
if (isDesktop) {
|
||||
await page.getByTestId('create-workspace-continue-button').click();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,6 +181,9 @@
|
||||
{
|
||||
"path": "./tests/affine-cloud"
|
||||
},
|
||||
{
|
||||
"path": "./tests/affine-desktop"
|
||||
},
|
||||
{
|
||||
"path": "./tests/affine-legacy/0.8.0-canary.7"
|
||||
},
|
||||
|
||||
25
yarn.lock
25
yarn.lock
@@ -80,6 +80,30 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@affine-test/affine-desktop-cloud@workspace:tests/affine-desktop-cloud":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine-test/affine-desktop-cloud@workspace:tests/affine-desktop-cloud"
|
||||
dependencies:
|
||||
"@affine-test/fixtures": "workspace:*"
|
||||
"@affine-test/kit": "workspace:*"
|
||||
"@playwright/test": ^1.37.1
|
||||
"@types/fs-extra": ^11.0.1
|
||||
fs-extra: ^11.1.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@affine-test/affine-desktop@workspace:tests/affine-desktop":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine-test/affine-desktop@workspace:tests/affine-desktop"
|
||||
dependencies:
|
||||
"@affine-test/fixtures": "workspace:*"
|
||||
"@affine-test/kit": "workspace:*"
|
||||
"@playwright/test": ^1.37.1
|
||||
"@types/fs-extra": ^11.0.1
|
||||
fs-extra: ^11.1.1
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@affine-test/affine-local@workspace:tests/affine-local":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine-test/affine-local@workspace:tests/affine-local"
|
||||
@@ -388,7 +412,6 @@ __metadata:
|
||||
"@electron/remote": 2.0.11
|
||||
"@reforged/maker-appimage": ^3.3.1
|
||||
"@toeverything/infra": "workspace:*"
|
||||
"@types/fs-extra": ^11.0.1
|
||||
"@types/uuid": ^9.0.3
|
||||
async-call-rpc: ^6.3.1
|
||||
cross-env: 7.0.3
|
||||
|
||||
Reference in New Issue
Block a user