Skip to content

Commit 97ed142

Browse files
authored
Fix flaky e2e tests (#951)
* Fix * Change discovery test to serial * Add global-setup.ts * Change playwright trace config * Update comment * CR suggestions * Change number of workers
1 parent 48eed62 commit 97ed142

5 files changed

Lines changed: 46 additions & 8 deletions

File tree

e2e/global-setup.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Warm-up that verifies the tracing infrastructure is fully initialized.
3+
*
4+
* TracingManager.handle_continue(:setup_tracing) runs asynchronously after app boot.
5+
* We open a dev app + debugger pair and check if traces were captured.
6+
* If not, we trigger callback in dev app and check for traces with timeout (repeated 5 times).
7+
*/
8+
import { chromium } from '@playwright/test';
9+
10+
export default async function globalSetup() {
11+
const browser = await chromium.launch();
12+
const page = await browser.newPage();
13+
14+
await page.goto(
15+
process.env.PLAYWRIGHT_TEST_BASE_URL ?? 'http://localhost:4005/'
16+
);
17+
18+
await page.locator('#live-debugger-debug-button').click();
19+
const dbgAppPromise = page.waitForEvent('popup');
20+
await page.getByText('Open in new tab').click();
21+
const dbgApp = await dbgAppPromise;
22+
23+
for (let i = 0; i < 5; i++) {
24+
try {
25+
await dbgApp
26+
.locator('#traces-list-stream details')
27+
.waitFor({ timeout: 2000 });
28+
break;
29+
} catch {
30+
await page.locator('#increment-button').click();
31+
}
32+
}
33+
34+
await browser.close();
35+
}

e2e/playwright.config.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import { defineConfig, devices } from '@playwright/test';
44
* See https://playwright.dev/docs/test-configuration.
55
*/
66
export default defineConfig({
7+
globalSetup: './global-setup.ts',
78
testDir: './tests',
89
/* Run tests in files in parallel */
910
fullyParallel: true,
1011
/* Fail the build on CI if you accidentally left test.only in the source code. */
1112
forbidOnly: !!process.env.CI,
1213
/* Retry on CI only */
1314
retries: process.env.CI ? 2 : 0,
14-
workers: process.env.CI ? 2 : undefined,
15+
workers: process.env.CI ? 4 : undefined,
1516
maxFailures: process.env.CI ? 5 : undefined,
1617
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
1718
reporter: 'html',
@@ -21,7 +22,7 @@ export default defineConfig({
2122
baseURL: 'http://localhost:4005',
2223

2324
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
24-
trace: 'on-first-retry',
25+
trace: 'retain-on-failure',
2526
},
2627

2728
projects: [
@@ -38,11 +39,13 @@ export default defineConfig({
3839
{
3940
name: 'serial-tests chromium',
4041
use: { ...devices['Desktop Chrome'] },
42+
workers: 1,
4143
testMatch: '**/*.serial.spec.ts',
4244
dependencies: ['chromium', 'firefox'],
4345
},
4446
{
4547
name: 'serial-tests firefox',
48+
workers: 1,
4649
use: { ...devices['Desktop Firefox'] },
4750
testMatch: '**/*.serial.spec.ts',
4851
dependencies: ['chromium', 'firefox', 'serial-tests chromium'],

e2e/tests/assigns.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ const showButton = async (page: Page, selector: string) => {
2828
const clickPinButton = async (page: Page, assignKey: string) => {
2929
const selector = `#all-assigns button[phx-click="pin-assign"][phx-value-key="${assignKey}"]`;
3030
await showButton(page, selector);
31-
await page.locator(selector).click();
31+
await page.locator(selector).click({ force: true });
3232
};
3333

3434
const clickUnpinButton = async (page: Page, assignKey: string) => {
3535
const selector = `#pinned-assigns button[phx-click="unpin-assign"][phx-value-key="${assignKey}"]`;
3636
await showButton(page, selector);
37-
await page.locator(selector).click();
37+
await page.locator(selector).click({ force: true });
3838
};
3939

4040
test('user can search assigns using the searchbar', async ({ dbgApp }) => {
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ test('user can see active live views and their highlights which are refreshed au
2525
await expect(dbgApp.getByText(devPidString1)).toBeVisible();
2626

2727
const devApp2 = await context.newPage();
28-
devApp2.goto('/');
28+
await devApp2.goto('/');
2929

3030
const devPidString2 =
3131
(await devApp2.locator('#current-pid').textContent()) ?? '';
@@ -62,7 +62,7 @@ test('settings button exists and redirects works as expected', async ({
6262

6363
await dbgApp.getByRole('link', { name: 'Icon settings' }).click();
6464

65-
await expect(dbgApp.getByRole('heading')).toHaveText('Settings');
65+
await expect(dbgApp.getByRole('heading', { name: 'Settings' })).toBeVisible();
6666

6767
await dbgApp.getByRole('link', { name: 'Icon arrow left' }).click();
6868

e2e/tests/node-inspector.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ test('callback traces have proper execution times displayed', async ({
7474

7575
await expect(traces).toHaveCount(2);
7676
await expect(traces.last().locator('span.text-warning-text')).toHaveText(
77-
/40\d ms/
77+
/^\s*4\d\d ms\s*$/
7878
);
7979

8080
await devApp
@@ -87,7 +87,7 @@ test('callback traces have proper execution times displayed', async ({
8787

8888
await expect(traces).toHaveCount(4);
8989
await expect(traces.nth(1).locator('span.text-error-text')).toHaveText(
90-
/1\.10 s/
90+
/^\s*1\.1\d s\s*$/
9191
);
9292
});
9393

0 commit comments

Comments
 (0)