Skip to content

Commit 49375c8

Browse files
wwwillchen-botgithub-actions[bot]claude
authored
fix: deflake E2E tests (setup_flow.spec.ts) (#2740)
## Summary - Deflake `setup_flow.spec.ts` which was the most flaky test file (20 occurrences across 10 CI runs and 5 PRs) - Wrap initial "Setup Dyad" heading check in `toPass()` with `Timeout.MEDIUM` to handle slow page renders in CI - Wrap `page.reload()` in `toPass()` retry to handle intermittent `ERR_FILE_NOT_FOUND` errors in Electron - Expand Node.js accordion section before checking for install button (section not auto-expanded after reload with mock) - Use `force: true` on "Continue" button click to avoid accordion overlap pointer interception - Replace hardcoded timeouts with `Timeout.MEDIUM` constants for CI/local adaptability ## Test plan - [x] Ran `setup_flow.spec.ts` with `--repeat-each=10` (30 tests total) - all passed - [x] Previously failed 6/10 times on "node.js install flow" test, now passes 10/10 - [x] Other top flaky specs (context_manage, chat_input, edit_code, logs_server, themes_management, fix_error) passed all repeats locally without changes - their CI flakiness is environment-specific - [x] All 819 unit tests pass - [x] Lint and type checks pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/2740" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end --> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a0bc7c7 commit 49375c8

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

e2e-tests/setup_flow.spec.ts

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { testWithConfig } from "./helpers/test_helper";
1+
import { testWithConfig, Timeout } from "./helpers/test_helper";
22
import { expect } from "@playwright/test";
33

44
const testSetup = testWithConfig({
@@ -9,10 +9,15 @@ testSetup.describe("Setup Flow", () => {
99
testSetup(
1010
"setup banner shows correct state when node.js is installed",
1111
async ({ po }) => {
12-
// Verify the "Setup Dyad" heading is visible
13-
await expect(
14-
po.page.getByText("Setup Dyad", { exact: true }),
15-
).toBeVisible();
12+
// Wait for the page to fully render before checking UI elements
13+
await po.page.waitForLoadState("domcontentloaded");
14+
15+
// Verify the "Setup Dyad" heading is visible (use toPass for CI resilience)
16+
await expect(async () => {
17+
await expect(
18+
po.page.getByText("Setup Dyad", { exact: true }),
19+
).toBeVisible();
20+
}).toPass({ timeout: Timeout.MEDIUM });
1621

1722
// Verify both accordion sections are visible
1823
await expect(
@@ -39,16 +44,25 @@ testSetup.describe("Setup Flow", () => {
3944
testSetup("node.js install flow", async ({ po }) => {
4045
// Start with Node.js not installed
4146
await po.setNodeMock(false);
42-
await po.page.reload();
43-
await po.page.waitForLoadState("domcontentloaded");
4447

45-
// Verify setup banner and install button are visible
46-
await expect(
47-
po.page.getByText("Setup Dyad", { exact: true }),
48-
).toBeVisible();
48+
// Reload with retry to handle intermittent ERR_FILE_NOT_FOUND in Electron
49+
await expect(async () => {
50+
await po.page.reload({ waitUntil: "domcontentloaded" });
51+
}).toPass({ timeout: Timeout.MEDIUM });
52+
53+
// Verify setup banner is visible (use toPass for resilience)
54+
await expect(async () => {
55+
await expect(
56+
po.page.getByText("Setup Dyad", { exact: true }),
57+
).toBeVisible();
58+
}).toPass({ timeout: Timeout.MEDIUM });
59+
60+
// Expand the Node.js section to reveal the install button
61+
await po.page.getByText("1. Install Node.js (App Runtime)").click();
62+
4963
await expect(
5064
po.page.getByRole("button", { name: "Install Node.js Runtime" }),
51-
).toBeVisible({ timeout: 10000 });
65+
).toBeVisible({ timeout: Timeout.MEDIUM });
5266

5367
// Manual configuration link should be visible
5468
await expect(
@@ -61,17 +75,16 @@ testSetup.describe("Setup Flow", () => {
6175
.click();
6276

6377
// After clicking install, the "Continue" button should appear
64-
await expect(
65-
po.page.getByRole("button", { name: /Continue.*I installed Node\.js/ }),
66-
).toBeVisible();
78+
const continueButton = po.page.getByRole("button", {
79+
name: /Continue.*I installed Node\.js/,
80+
});
81+
await expect(continueButton).toBeVisible();
6782

6883
// Simulate user having installed Node.js
6984
await po.setNodeMock(true);
7085

71-
// Click the continue button
72-
await po.page
73-
.getByRole("button", { name: /Continue.*I installed Node\.js/ })
74-
.click();
86+
// Click the continue button (use force to avoid accordion overlap issues)
87+
await continueButton.click({ force: true });
7588

7689
// Node.js should now show as installed
7790
await expect(

0 commit comments

Comments
 (0)