Unverified 提交 f86b78bb authored 作者: wwwillchen-bot's avatar wwwillchen-bot 提交者: GitHub

fix: deflake E2E tests (refresh.spec.ts, themes_management.spec.ts) (#2752)

## Summary - **refresh.spec.ts**: Fix race condition where the "refresh app" test would fail because the iframe body was empty after refresh. Added explicit waits for the iframe body to have content both before removing it and after clicking refresh, preventing the `toMatchAriaSnapshot` from matching against an empty `<body></body>`. - **themes_management.spec.ts**: Fix strict mode violations where `getByLabel('Description (optional)')` resolved to 2 elements (one on the Manual tab, one on the AI tab). Replaced ambiguous label selectors with specific element ID selectors (`#manual-description`, `#manual-prompt`, `#ai-description`). Also scoped edit dialog selectors to the dialog role to avoid similar ambiguity. ## Verification Both spec files were verified with `--repeat-each=10` (0 retries) after fixes: - `refresh.spec.ts`: 40/40 passed (was 34/40 before fix) - `themes_management.spec.ts`: 50/50 passed (was 49/50 before fix) ## Flaky test scan results Scanned 2 CI runs on main + 11 PRs by wwwillchen/wwwillchen-bot. Most previously flaky tests (setup_flow, setup, select_component, debugging_logs, switch_versions, etc.) appear to have been fixed in prior commits. Only refresh.spec.ts and themes_management.spec.ts were still reproducing locally. ## Test plan - [x] `refresh.spec.ts` passes 10x repeat-each with 0 retries - [x] `themes_management.spec.ts` passes 10x repeat-each with 0 retries - [x] Formatting, linting, 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/2752" 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: 's avatarclaude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
上级 67072434
......@@ -5,10 +5,16 @@ testSkipIfWindows("refresh app", async ({ po }) => {
await po.setUp({ autoApprove: true });
await po.sendPrompt("hi");
// Wait for the preview iframe to have content before removing body
await po.previewPanel.expectPreviewIframeIsVisible();
const iframe = po.previewPanel.getPreviewIframeElement();
await expect(iframe.contentFrame().locator("body")).not.toBeEmpty({
timeout: Timeout.LONG,
});
// Drop the document.body inside the contentFrame to make
// sure refresh works.
await po.previewPanel
.getPreviewIframeElement()
await iframe
.contentFrame()
.locator("body")
.evaluate((body) => {
......@@ -16,6 +22,12 @@ testSkipIfWindows("refresh app", async ({ po }) => {
});
await po.previewPanel.clickPreviewRefresh();
// Wait for the iframe to reload with content after refresh
await expect(iframe.contentFrame().locator("body")).not.toBeEmpty({
timeout: Timeout.LONG,
});
await po.previewPanel.snapshotPreview();
});
......
......@@ -28,11 +28,9 @@ test("themes management - CRUD operations", async ({ po }) => {
// Fill in manual configuration form
await po.page.locator("#manual-name").fill("My Test Theme");
await po.page.locator("#manual-description").fill("A test theme description");
await po.page
.getByLabel("Description (optional)")
.fill("A test theme description");
await po.page
.getByLabel("Theme Prompt")
.locator("#manual-prompt")
.fill("Use blue colors and modern styling");
// Save the theme
......@@ -60,10 +58,14 @@ test("themes management - CRUD operations", async ({ po }) => {
.getByLabel("Theme Name")
.fill("Updated Theme");
await po.page
.getByRole("dialog")
.getByLabel("Description (optional)")
.fill("Updated description");
await po.page.getByLabel("Theme Prompt").clear();
await po.page.getByLabel("Theme Prompt").fill("Updated prompt content");
await po.page.getByRole("dialog").getByLabel("Theme Prompt").clear();
await po.page
.getByRole("dialog")
.getByLabel("Theme Prompt")
.fill("Updated prompt content");
// Save changes
await po.page.getByRole("button", { name: "Save" }).click();
......@@ -126,11 +128,9 @@ test("themes management - create theme from chat input", async ({ po }) => {
// Fill in manual configuration form
await po.page.locator("#manual-name").fill("Chat Input Theme");
await po.page.locator("#manual-description").fill("Created from chat input");
await po.page
.getByLabel("Description (optional)")
.fill("Created from chat input");
await po.page
.getByLabel("Theme Prompt")
.locator("#manual-prompt")
.fill("Use dark mode with purple accents");
// Save the theme
......@@ -240,9 +240,7 @@ test("themes management - AI generator flow", async ({ po }) => {
// Fill in theme details
await po.page.locator("#ai-name").fill("AI Generated Theme");
await po.page
.getByLabel("Description (optional)")
.fill("Created via AI generator");
await po.page.locator("#ai-description").fill("Created via AI generator");
// Upload an image
const fileChooserPromise = po.page.waitForEvent("filechooser");
......@@ -310,9 +308,7 @@ test("themes management - AI generator from website URL", async ({ po }) => {
// Fill in theme details
await po.page.locator("#ai-name").fill("Website Theme");
await po.page
.getByLabel("Description (optional)")
.fill("Generated from website");
await po.page.locator("#ai-description").fill("Generated from website");
// Enter a website URL
await urlInput.fill("https://example.com");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论