Skip to content

Commit f52fda2

Browse files
authored
test(e2e): remove redundant UI setup (#6161)
1 parent f9ccdfc commit f52fda2

3 files changed

Lines changed: 16 additions & 74 deletions

File tree

docs/testing/test-efficiency.zh-CN.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ expect(retry).toHaveBeenCalledTimes(1);
8888

8989
- 每个用例独立建立自己依赖的项目、配置、mock 和运行状态。
9090
- 不依赖同文件前序用例或同 worker 前序文件遗留的数据。
91+
- 只有验证首页、项目创建表单或创建后的路由行为时,才通过对应 UI 建立项目。
92+
其他浏览器用例应先注入首屏所需配置,通过 API 建立独立项目,再直达目标
93+
路由,避免把无关的首页渲染、modal 交互和 reload 纳入每条测试链路。
9194
- 不为了摊薄启动成本共享可变 daemon、浏览器上下文或数据目录。
9295
- 不用 serial group 隐藏竞争条件。
9396
- 嵌套资源按后创建、先关闭的顺序释放:page、browser context 和 browser

e2e/ui/app.test.ts

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -400,54 +400,7 @@ for (const entry of automatedUiScenarios().filter(
400400
});
401401
}
402402

403-
test('[P0] @critical comment attachment flow attaches preview comments to the next run as structured context', async ({ page }) => {
404-
test.setTimeout(75_000);
405-
const entry = automatedUiScenarios().find((scenario) => scenario.id === 'comment-attachment-flow');
406-
if (!entry?.mockArtifact) {
407-
throw new Error('comment-attachment-flow scenario fixture is missing');
408-
}
409-
410-
await routeMockAgents(page);
411-
await page.route('**/api/runs', async (route) => {
412-
await route.fulfill({
413-
status: 202,
414-
contentType: 'application/json',
415-
body: JSON.stringify({ runId: 'comment-attachment-run' }),
416-
});
417-
});
418-
await page.route('**/api/runs/*/events', async (route) => {
419-
const body = [
420-
'event: start',
421-
'data: {"bin":"mock-agent"}',
422-
'',
423-
'event: end',
424-
'data: {"code":0,"status":"succeeded"}',
425-
'',
426-
'',
427-
].join('\n');
428-
await route.fulfill({
429-
status: 200,
430-
headers: {
431-
'content-type': 'text/event-stream',
432-
'cache-control': 'no-cache',
433-
},
434-
body,
435-
});
436-
});
437-
438-
const projectId = await createEmptyProject(page, 'Comment attachment flow');
439-
await expectWorkspaceReady(page);
440-
await seedHtmlArtifact(page, projectId, entry.mockArtifact.fileName, entry.mockArtifact.html);
441-
await page.reload();
442-
await expectWorkspaceReady(page);
443-
await page.goto(`/projects/${projectId}/files/${entry.mockArtifact.fileName}`, { waitUntil: 'domcontentloaded' });
444-
await waitForLoadingToClear(page);
445-
await expect(artifactPreview(page)).toBeVisible();
446-
447-
await runCommentAttachmentFlow(page, entry);
448-
});
449-
450-
test('[P0] sending preview comments opens the refreshed follow-up artifact', async ({ page }) => {
403+
test('[P0] @critical sending preview comments attaches structured context and opens the refreshed artifact', async ({ page }) => {
451404
test.setTimeout(75_000);
452405
const entry = automatedUiScenarios().find((scenario) => scenario.id === 'comment-attachment-flow');
453406
if (!entry?.mockArtifact) {
@@ -518,6 +471,8 @@ test('[P0] sending preview comments opens the refreshed follow-up artifact', asy
518471
await page.getByTestId('comment-popover-input').fill('Make the headline more specific.');
519472
await page.getByTestId('comment-popover-save').click();
520473
await expect(page.getByTestId('comment-saved-marker-hero-title')).toBeVisible();
474+
await expect(page.getByTestId('staged-comment-attachments')).toHaveCount(0);
475+
await expect(page.getByTestId('comment-popover')).toHaveCount(0);
521476

522477
const sidePanel = page.getByTestId('comment-side-panel');
523478
await expect(sidePanel).toBeVisible();
@@ -547,6 +502,7 @@ test('[P0] sending preview comments opens the refreshed follow-up artifact', asy
547502
filePath?: string;
548503
}>;
549504
};
505+
expect(body.message ?? '').not.toContain('Apply selected preview comments');
550506
expect(body.message).toContain('Make the headline more specific.');
551507
expect(body.commentAttachments).toEqual([
552508
expect.objectContaining({

e2e/ui/real-daemon-run.test.ts

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ test.afterEach(async ({ page }) => {
7676
});
7777

7878
test('[P0] real daemon run streams, persists, and previews an artifact', async ({ page }) => {
79-
await page.goto('/');
8079
await createProject(page, 'Real daemon run smoke');
8180
await expectWorkspaceReady(page);
8281

@@ -106,7 +105,6 @@ test('[P0] real daemon run streams, persists, and previews an artifact', async (
106105
});
107106

108107
test('[P0] real daemon run persists an artifact streamed across multiple chunks', async ({ page }) => {
109-
await page.goto('/');
110108
await createProject(page, 'Chunked daemon run smoke');
111109
await expectWorkspaceReady(page);
112110

@@ -121,7 +119,6 @@ test('[P0] real daemon run persists an artifact streamed across multiple chunks'
121119
});
122120

123121
test('[P1] plain stdout daemon runtime persists artifact tags into project files and preview', async ({ page }) => {
124-
await page.goto('/');
125122
await createProject(page, 'Plain stream artifact smoke', 'qwen');
126123
await expectWorkspaceReady(page);
127124

@@ -135,7 +132,6 @@ test('[P1] plain stdout daemon runtime persists artifact tags into project files
135132
});
136133

137134
test('[P0] real daemon run surfaces process/parser errors in chat', async ({ page }) => {
138-
await page.goto('/');
139135
await createProject(page, 'Daemon error smoke');
140136
await expectWorkspaceReady(page);
141137

@@ -146,7 +142,6 @@ test('[P0] real daemon run surfaces process/parser errors in chat', async ({ pag
146142
});
147143

148144
test('[P0] real daemon run classifies a Claude mid-stream socket drop as a retryable connection error', async ({ page }) => {
149-
await page.goto('/');
150145
await createProject(page, 'Daemon socket-drop smoke', 'claude');
151146
await expectWorkspaceReady(page);
152147

@@ -162,7 +157,6 @@ test('[P0] real daemon run classifies a Claude mid-stream socket drop as a retry
162157
});
163158

164159
test('[P0] real daemon run supports a follow-up turn in the same project', async ({ page }) => {
165-
await page.goto('/');
166160
await createProject(page, 'Daemon follow-up smoke');
167161
await expectWorkspaceReady(page);
168162

@@ -182,7 +176,6 @@ test('[P0] real daemon run supports a follow-up turn in the same project', async
182176
});
183177

184178
test('[P1] real daemon run treats an in-place artifact edit as produced work', async ({ page }) => {
185-
await page.goto('/');
186179
await createProject(page, 'Daemon artifact edit smoke', 'claude');
187180
await expectWorkspaceReady(page);
188181

@@ -222,6 +215,7 @@ test('[P1] real daemon run treats an in-place artifact edit as produced work', a
222215
await expect(editedHeading).toBeVisible();
223216
await editedHeading.click();
224217
await expect(editedHeading).toHaveAttribute('data-od-edit-selected', 'true');
218+
await page.getByTestId('manual-edit-open-inspector').click();
225219
const fontSizeInput = page
226220
.locator('.manual-edit-modal .cc-section')
227221
.filter({ hasText: 'TYPOGRAPHY' })
@@ -241,7 +235,6 @@ test('[P1] real daemon run treats an in-place artifact edit as produced work', a
241235
});
242236

243237
test('[P1] Plan mode daemon run creates, opens, and restores an editable markdown plan', async ({ page }) => {
244-
await page.goto('/');
245238
await createProject(page, 'Plan mode markdown smoke');
246239
await expectWorkspaceReady(page);
247240

@@ -275,7 +268,6 @@ test('[P1] Plan mode daemon run creates, opens, and restores an editable markdow
275268
// generated HTML instead of staying on the markdown plan.
276269
test('[P1] Plan mode generation turn auto-opens the generated HTML file', async ({ page }) => {
277270
test.setTimeout(120_000);
278-
await page.goto('/');
279271
await createProject(page, 'Plan mode html auto-open smoke', 'claude');
280272
await expectWorkspaceReady(page);
281273

@@ -311,7 +303,6 @@ test('[P1] Plan mode generation turn auto-opens the generated HTML file', async
311303
// auto-open path cannot mask the turn-end selection.
312304
test('[P1] Plan mode regeneration re-opens the existing generated HTML file', async ({ page }) => {
313305
test.setTimeout(120_000);
314-
await page.goto('/');
315306
await createProject(page, 'Plan mode html regen smoke');
316307
await expectWorkspaceReady(page);
317308

@@ -345,7 +336,6 @@ test('[P1] Plan mode regeneration re-opens the existing generated HTML file', as
345336
});
346337

347338
test('[P0] real daemon run restores a delayed artifact turn after reload', async ({ page }) => {
348-
await page.goto('/');
349339
await createProject(page, 'Delayed daemon reload smoke');
350340
await expectWorkspaceReady(page);
351341

@@ -373,7 +363,6 @@ test('[P0] real daemon run restores a delayed artifact turn after reload', async
373363
test('[P1] real daemon run reconnects after reload while the run is still active', async ({ page }) => {
374364
test.setTimeout(90_000);
375365

376-
await page.goto('/');
377366
await createProject(page, 'Running daemon reload smoke');
378367
await expectWorkspaceReady(page);
379368

@@ -407,7 +396,6 @@ test('[P1] real daemon run reconnects after reload while the run is still active
407396
test('[P1] artifact persistence survives page reload during an active real daemon run', async ({ page }) => {
408397
test.setTimeout(120_000);
409398

410-
await page.goto('/');
411399
await createProject(page, 'Running daemon reload smoke');
412400
await expectWorkspaceReady(page);
413401

@@ -476,7 +464,6 @@ test('[P1] artifact persistence survives page reload during an active real daemo
476464
});
477465

478466
test('[P1] real daemon run survives reload before the create response reaches the browser', async ({ page }) => {
479-
await page.goto('/');
480467
await createProject(page, 'Delayed daemon create-response reload smoke');
481468
await expectWorkspaceReady(page);
482469

@@ -497,7 +484,6 @@ test('[P1] real daemon run survives reload before the create response reaches th
497484
});
498485

499486
test('[P0] empty daemon output fails cleanly, persists after reload, and does not leave ghost files', async ({ page }) => {
500-
await page.goto('/');
501487
await createProject(page, 'Empty daemon failure smoke');
502488
await expectWorkspaceReady(page);
503489

@@ -522,7 +508,6 @@ test('[P0] empty daemon output fails cleanly, persists after reload, and does no
522508
});
523509

524510
test('[P1] plain stdout daemon runtime surfaces stderr-only failures without ghost files', async ({ page }) => {
525-
await page.goto('/');
526511
await createProject(page, 'Plain stderr failure smoke', 'qwen');
527512
await expectWorkspaceReady(page);
528513

@@ -545,7 +530,6 @@ test('[P1] plain stdout daemon runtime surfaces stderr-only failures without gho
545530
});
546531

547532
test('[P0] separate projects keep daemon artifacts isolated across recent-project navigation', async ({ page }) => {
548-
await page.goto('/');
549533
await createProject(page, 'Real daemon isolation alpha');
550534
await expectWorkspaceReady(page);
551535
await sendPrompt(page, 'Create a deterministic smoke artifact');
@@ -719,18 +703,17 @@ test('[P0] real daemon run supports fake non-Codex runtime protocols', async ({
719703
async function createProject(page: Page, name: string, agentId: FakeAgentId = 'codex') {
720704
await configureFakeAgent(page, agentId);
721705
await installBrowserAgentConfig(page, agentId);
722-
await gotoEntryHome(page);
723-
await setBrowserAgentConfig(page, agentId);
724-
await page.reload({ waitUntil: 'domcontentloaded' });
706+
const projectId = `real-daemon-${agentId}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
707+
await createProjectViaApi(page, projectId, name);
708+
try {
709+
await page.goto(`/projects/${projectId}`, { waitUntil: 'domcontentloaded' });
710+
} catch (error) {
711+
const message = error instanceof Error ? error.message : String(error);
712+
if (!/ERR_ABORTED|frame was detached/i.test(message)) throw error;
713+
}
725714
await waitForLoadingToClear(page);
726-
await setBrowserAgentConfig(page, agentId);
727-
await configureFakeAgent(page, agentId);
728715
await expectBrowserAgentConfig(page, agentId);
729716
await dismissPrivacyDialog(page);
730-
await openNewProjectModalFromProjects(page);
731-
await page.getByTestId('new-project-tab-prototype').click();
732-
await page.getByTestId('new-project-name').fill(name);
733-
await page.getByTestId('create-project').click();
734717
}
735718

736719
async function createByokOpenCodeProject(page: Page, name: string) {

0 commit comments

Comments
 (0)