mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-22 19:53:48 +08:00
chore(core): upload flaky test traces (#9974)
This commit is contained in:
@@ -175,7 +175,7 @@ jobs:
|
|||||||
run: yarn workspace @blocksuite/legacy-e2e test --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
run: yarn workspace @blocksuite/legacy-e2e test --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
||||||
|
|
||||||
- name: Upload test results
|
- name: Upload test results
|
||||||
if: ${{ failure() }}
|
if: always()
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-results-e2e-legacy-bs-${{ matrix.shard }}
|
name: test-results-e2e-legacy-bs-${{ matrix.shard }}
|
||||||
@@ -207,7 +207,7 @@ jobs:
|
|||||||
run: yarn affine @affine-test/affine-local e2e --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
run: yarn affine @affine-test/affine-local e2e --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
||||||
|
|
||||||
- name: Upload test results
|
- name: Upload test results
|
||||||
if: ${{ failure() }}
|
if: always()
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-results-e2e-${{ matrix.shard }}
|
name: test-results-e2e-${{ matrix.shard }}
|
||||||
@@ -239,7 +239,7 @@ jobs:
|
|||||||
run: yarn affine @affine-test/affine-mobile e2e --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
run: yarn affine @affine-test/affine-mobile e2e --forbid-only --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
||||||
|
|
||||||
- name: Upload test results
|
- name: Upload test results
|
||||||
if: ${{ failure() }}
|
if: always()
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-results-e2e-mobile-${{ matrix.shard }}
|
name: test-results-e2e-mobile-${{ matrix.shard }}
|
||||||
@@ -328,6 +328,7 @@ jobs:
|
|||||||
package: '@affine/native'
|
package: '@affine/native'
|
||||||
- name: Upload ${{ steps.filename.outputs.filename }}
|
- name: Upload ${{ steps.filename.outputs.filename }}
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.filename.outputs.filename }}
|
name: ${{ steps.filename.outputs.filename }}
|
||||||
path: ${{ env.DEV_DRIVE_WORKSPACE || github.workspace }}/packages/frontend/native/${{ steps.filename.outputs.filename }}
|
path: ${{ env.DEV_DRIVE_WORKSPACE || github.workspace }}/packages/frontend/native/${{ steps.filename.outputs.filename }}
|
||||||
@@ -354,6 +355,7 @@ jobs:
|
|||||||
package: '@affine/server-native'
|
package: '@affine/server-native'
|
||||||
- name: Upload server-native.node
|
- name: Upload server-native.node
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: server-native.node
|
name: server-native.node
|
||||||
path: ./packages/backend/native/server-native.node
|
path: ./packages/backend/native/server-native.node
|
||||||
@@ -379,6 +381,7 @@ jobs:
|
|||||||
run: tar -czf dist.tar.gz --directory=packages/frontend/apps/electron-renderer/dist .
|
run: tar -czf dist.tar.gz --directory=packages/frontend/apps/electron-renderer/dist .
|
||||||
- name: Upload web artifact
|
- name: Upload web artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: web
|
name: web
|
||||||
path: dist.tar.gz
|
path: dist.tar.gz
|
||||||
@@ -660,12 +663,16 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
tests:
|
tests:
|
||||||
- name: 'Server E2E Test 1/3'
|
- name: 'Server E2E Test 1/3'
|
||||||
|
shard: 1
|
||||||
script: yarn affine @affine-test/affine-cloud e2e --forbid-only --shard=1/3
|
script: yarn affine @affine-test/affine-cloud e2e --forbid-only --shard=1/3
|
||||||
- name: 'Server E2E Test 2/3'
|
- name: 'Server E2E Test 2/3'
|
||||||
|
shard: 2
|
||||||
script: yarn affine @affine-test/affine-cloud e2e --forbid-only --shard=2/3
|
script: yarn affine @affine-test/affine-cloud e2e --forbid-only --shard=2/3
|
||||||
- name: 'Server E2E Test 3/3'
|
- name: 'Server E2E Test 3/3'
|
||||||
|
shard: 3
|
||||||
script: yarn affine @affine-test/affine-cloud e2e --forbid-only --shard=3/3
|
script: yarn affine @affine-test/affine-cloud e2e --forbid-only --shard=3/3
|
||||||
- name: 'Server Desktop E2E Test'
|
- name: 'Server Desktop E2E Test'
|
||||||
|
shard: desktop
|
||||||
script: |
|
script: |
|
||||||
yarn affine @affine/electron build:dev
|
yarn affine @affine/electron build:dev
|
||||||
# Workaround for Electron apps failing to initialize on Ubuntu 24.04 due to AppArmor restrictions
|
# Workaround for Electron apps failing to initialize on Ubuntu 24.04 due to AppArmor restrictions
|
||||||
@@ -728,10 +735,10 @@ jobs:
|
|||||||
COPILOT_PERPLEXITY_API_KEY: 1
|
COPILOT_PERPLEXITY_API_KEY: 1
|
||||||
|
|
||||||
- name: Upload test results
|
- name: Upload test results
|
||||||
if: ${{ failure() }}
|
if: always()
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-results-e2e-server
|
name: test-results-e2e-server-${{ matrix.tests.shard }}
|
||||||
path: ./test-results
|
path: ./test-results
|
||||||
if-no-files-found: ignore
|
if-no-files-found: ignore
|
||||||
|
|
||||||
@@ -853,7 +860,7 @@ jobs:
|
|||||||
yarn affine @affine/electron node ./scripts/macos-arm64-output-check.ts
|
yarn affine @affine/electron node ./scripts/macos-arm64-output-check.ts
|
||||||
|
|
||||||
- name: Upload test results
|
- name: Upload test results
|
||||||
if: ${{ failure() }}
|
if: always()
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: test-results-e2e-${{ matrix.spec.os }}-${{ matrix.spec.arch }}
|
name: test-results-e2e-${{ matrix.spec.os }}-${{ matrix.spec.arch }}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import process from 'node:process';
|
import process from 'node:process';
|
||||||
|
|
||||||
|
import { testResultDir } from '@affine-test/kit/playwright';
|
||||||
import type { PlaywrightWorkerOptions } from '@playwright/test';
|
import type { PlaywrightWorkerOptions } from '@playwright/test';
|
||||||
import { defineConfig } from '@playwright/test';
|
import { defineConfig } from '@playwright/test';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
testDir: '.',
|
testDir: '.',
|
||||||
|
outputDir: testResultDir,
|
||||||
timeout: process.env.CI ? 40000 : 999999,
|
timeout: process.env.CI ? 40000 : 999999,
|
||||||
fullyParallel: true,
|
fullyParallel: true,
|
||||||
snapshotDir: 'snapshots',
|
snapshotDir: 'snapshots',
|
||||||
|
|||||||
@@ -322,7 +322,6 @@ export async function enterPlaygroundRoom(
|
|||||||
page.on('console', message => {
|
page.on('console', message => {
|
||||||
if (
|
if (
|
||||||
[
|
[
|
||||||
'',
|
|
||||||
// React devtools:
|
// React devtools:
|
||||||
'%cDownload the React DevTools for a better development experience: https://reactjs.org/link/react-devtools font-weight:bold',
|
'%cDownload the React DevTools for a better development experience: https://reactjs.org/link/react-devtools font-weight:bold',
|
||||||
// Vite:
|
// Vite:
|
||||||
@@ -334,7 +333,7 @@ export async function enterPlaygroundRoom(
|
|||||||
'Lit is in dev mode. Not recommended for production! See https://lit.dev/msg/dev-mode for more information.',
|
'Lit is in dev mode. Not recommended for production! See https://lit.dev/msg/dev-mode for more information.',
|
||||||
// Figma embed:
|
// Figma embed:
|
||||||
'Running frontend commit',
|
'Running frontend commit',
|
||||||
].includes(message.text())
|
].some(text => message.text().startsWith(text))
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ const config: PlaywrightTestConfig = {
|
|||||||
viewport: { width: 1440, height: 800 },
|
viewport: { width: 1440, height: 800 },
|
||||||
actionTimeout: 10 * 1000,
|
actionTimeout: 10 * 1000,
|
||||||
locale: 'en-US',
|
locale: 'en-US',
|
||||||
trace: 'on',
|
trace: 'retain-on-failure',
|
||||||
video: 'on',
|
video: 'retain-on-failure',
|
||||||
},
|
},
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
workers: 4,
|
workers: 4,
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ const config: PlaywrightTestConfig = {
|
|||||||
viewport: { width: 1440, height: 800 },
|
viewport: { width: 1440, height: 800 },
|
||||||
actionTimeout: 10 * 1000,
|
actionTimeout: 10 * 1000,
|
||||||
locale: 'en-US',
|
locale: 'en-US',
|
||||||
trace: 'on',
|
trace: 'retain-on-failure',
|
||||||
video: 'on',
|
video: 'retain-on-failure',
|
||||||
},
|
},
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
workers: process.env.CI && !process.env.COPILOT ? 1 : 4,
|
workers: process.env.CI && !process.env.COPILOT ? 1 : 4,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const config: PlaywrightTestConfig = {
|
|||||||
outputDir: testResultDir,
|
outputDir: testResultDir,
|
||||||
use: {
|
use: {
|
||||||
viewport: { width: 1440, height: 800 },
|
viewport: { width: 1440, height: 800 },
|
||||||
trace: 'on-first-retry',
|
trace: 'retain-on-failure',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -30,19 +30,11 @@ const insertInputText = async (page: Page, text: string) => {
|
|||||||
expect(actual).toBe(text);
|
expect(actual).toBe(text);
|
||||||
};
|
};
|
||||||
|
|
||||||
const keyboardDownAndSelect = async (page: Page, label: string) => {
|
const selectItem = async (page: Page, label: string) => {
|
||||||
await page.keyboard.press('ArrowDown');
|
const selectedEl = page
|
||||||
const selectedEl = page.locator(
|
.locator('[cmdk-item] [data-testid="cmdk-label"]')
|
||||||
'[cmdk-item][data-selected="true"] [data-testid="cmdk-label"]'
|
.filter({ hasText: label });
|
||||||
);
|
await selectedEl.click();
|
||||||
if (
|
|
||||||
!(await selectedEl.isVisible()) ||
|
|
||||||
(await selectedEl.innerText()) !== label
|
|
||||||
) {
|
|
||||||
await keyboardDownAndSelect(page, label);
|
|
||||||
} else {
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const commandsIsVisible = async (page: Page, label: string) => {
|
const commandsIsVisible = async (page: Page, label: string) => {
|
||||||
@@ -257,7 +249,7 @@ test('can use keyboard down to select goto setting', async ({ page }) => {
|
|||||||
await openHomePage(page);
|
await openHomePage(page);
|
||||||
await waitForEditorLoad(page);
|
await waitForEditorLoad(page);
|
||||||
await openQuickSearchByShortcut(page);
|
await openQuickSearchByShortcut(page);
|
||||||
await keyboardDownAndSelect(page, 'Go to Settings');
|
await selectItem(page, 'Go to Settings');
|
||||||
|
|
||||||
await expect(page.getByTestId('setting-modal')).toBeVisible();
|
await expect(page.getByTestId('setting-modal')).toBeVisible();
|
||||||
});
|
});
|
||||||
@@ -351,7 +343,7 @@ test('can use cmdk to export png', async ({ page }) => {
|
|||||||
await openQuickSearchByShortcut(page);
|
await openQuickSearchByShortcut(page);
|
||||||
const [download] = await Promise.all([
|
const [download] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
keyboardDownAndSelect(page, 'Export to PNG'),
|
selectItem(page, 'Export to PNG'),
|
||||||
]);
|
]);
|
||||||
expect(download.suggestedFilename()).toBe('this is a new page to export.png');
|
expect(download.suggestedFilename()).toBe('this is a new page to export.png');
|
||||||
});
|
});
|
||||||
@@ -363,7 +355,7 @@ test('can use cmdk to delete page and restore it', async ({ page }) => {
|
|||||||
await getBlockSuiteEditorTitle(page).click();
|
await getBlockSuiteEditorTitle(page).click();
|
||||||
await getBlockSuiteEditorTitle(page).fill('this is a new page to delete');
|
await getBlockSuiteEditorTitle(page).fill('this is a new page to delete');
|
||||||
await openQuickSearchByShortcut(page);
|
await openQuickSearchByShortcut(page);
|
||||||
await keyboardDownAndSelect(page, 'Move to trash');
|
await selectItem(page, 'Move to trash');
|
||||||
await page.getByTestId('confirm-modal-confirm').click();
|
await page.getByTestId('confirm-modal-confirm').click();
|
||||||
const restoreButton = page.getByTestId('page-restore-button');
|
const restoreButton = page.getByTestId('page-restore-button');
|
||||||
await expect(restoreButton).toBeVisible();
|
await expect(restoreButton).toBeVisible();
|
||||||
@@ -371,7 +363,7 @@ test('can use cmdk to delete page and restore it', async ({ page }) => {
|
|||||||
await openQuickSearchByShortcut(page);
|
await openQuickSearchByShortcut(page);
|
||||||
expect(await commandsIsVisible(page, 'Move to trash')).toBe(false);
|
expect(await commandsIsVisible(page, 'Move to trash')).toBe(false);
|
||||||
expect(await commandsIsVisible(page, 'Restore from trash')).toBe(true);
|
expect(await commandsIsVisible(page, 'Restore from trash')).toBe(true);
|
||||||
await keyboardDownAndSelect(page, 'Restore from trash');
|
await selectItem(page, 'Restore from trash');
|
||||||
await expect(restoreButton).not.toBeVisible();
|
await expect(restoreButton).not.toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ const config: PlaywrightTestConfig = {
|
|||||||
// Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer
|
// Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer
|
||||||
// You can open traces locally(`npx playwright show-trace trace.zip`)
|
// You can open traces locally(`npx playwright show-trace trace.zip`)
|
||||||
// or in your browser on [Playwright Trace Viewer](https://trace.playwright.dev/).
|
// or in your browser on [Playwright Trace Viewer](https://trace.playwright.dev/).
|
||||||
trace: 'on-first-retry',
|
trace: 'retain-on-failure',
|
||||||
// Record video only when retrying a test for the first time.
|
// Record video only when retrying a test for the first time.
|
||||||
video: 'on-first-retry',
|
video: 'retain-on-failure',
|
||||||
},
|
},
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
workers: 4,
|
workers: 4,
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ const config: PlaywrightTestConfig = {
|
|||||||
// Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer
|
// Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer
|
||||||
// You can open traces locally(`npx playwright show-trace trace.zip`)
|
// You can open traces locally(`npx playwright show-trace trace.zip`)
|
||||||
// or in your browser on [Playwright Trace Viewer](https://trace.playwright.dev/).
|
// or in your browser on [Playwright Trace Viewer](https://trace.playwright.dev/).
|
||||||
trace: 'on-first-retry',
|
trace: 'retain-on-failure',
|
||||||
// Record video only when retrying a test for the first time.
|
// Record video only when retrying a test for the first time.
|
||||||
video: 'on-first-retry',
|
video: 'retain-on-failure',
|
||||||
},
|
},
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
workers: 4,
|
workers: 4,
|
||||||
|
|||||||
@@ -20,5 +20,9 @@ export const test = baseTest.extend<{
|
|||||||
});
|
});
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
await use(page);
|
await use(page);
|
||||||
|
console.log(
|
||||||
|
'Browser User Agent:',
|
||||||
|
await page.evaluate(() => navigator.userAgent)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user