test(web): align e2e anchors and goldens with the unified tool-row expand

This commit is contained in:
imccyu
2026-07-31 02:16:28 +08:00
parent 5d29a8aff3
commit 8933d63143
11 changed files with 62 additions and 41 deletions

View File

@@ -107,7 +107,8 @@ describe('web e2e: Cordis tools use the generic row variants', () => {
const mountRow = page.locator('[data-tool="cordis_mount"]').filter({ hasText: 'Mount temporary Plugin' }).first() const mountRow = page.locator('[data-tool="cordis_mount"]').filter({ hasText: 'Mount temporary Plugin' }).first()
await mountRow.waitFor({ timeout: 10_000 }) await mountRow.waitFor({ timeout: 10_000 })
await mountRow.locator('button[aria-expanded]').click() // The whole summary row is the expand toggle (unified tool-row interaction).
await mountRow.locator('[aria-expanded]').first().click()
await expect.poll(() => mountRow.locator('pre.shiki').textContent(), { timeout: 10_000 }) await expect.poll(() => mountRow.locator('pre.shiki').textContent(), { timeout: 10_000 })
.toContain(MOUNT_CODE) .toContain(MOUNT_CODE)

View File

@@ -180,11 +180,13 @@ describe('web e2e: navigation & panes over a rich seeded session', () => {
await bashRow.waitFor({ timeout: 15_000 }) await bashRow.waitFor({ timeout: 15_000 })
const frame = page.locator('[style*="grid-template-columns"]').first() const frame = page.locator('[style*="grid-template-columns"]').first()
expect(await frame.getAttribute('data-details-collapsed')).toBe('true') expect(await frame.getAttribute('data-details-collapsed')).toBe('true')
// The row click is the card's expand toggle (unified tool-row
// interaction); it must not drive layout geometry either way.
await bashRow.click() await bashRow.click()
await expect.poll(() => frame.getAttribute('data-details-collapsed'), { timeout: 5_000 }).toBe('true') await expect.poll(() => frame.getAttribute('data-details-collapsed'), { timeout: 5_000 }).toBe('true')
// The card's own controls are outside the summary row and must not open // The card's own controls are outside the summary row and must not open
// details either — the terminal card is read in place. // details either — the expanded terminal card is read in place.
await page.locator('[data-sample="bash-global"] ~ [data-terminal] [class*="_copyButton_"]').first().click() await page.locator('[data-sample="bash-global"] ~ div [data-terminal] [class*="_copyButton_"]').first().click()
await expect.poll(() => frame.getAttribute('data-details-collapsed'), { timeout: 5_000 }).toBe('true') await expect.poll(() => frame.getAttribute('data-details-collapsed'), { timeout: 5_000 }).toBe('true')
// Read summaries are host-open file links; they also must not open details. // Read summaries are host-open file links; they also must not open details.
const fileLink = page.locator('[data-variant="read"] button').first() const fileLink = page.locator('[data-variant="read"] button').first()
@@ -196,10 +198,14 @@ describe('web e2e: navigation & panes over a rich seeded session', () => {
it.skipIf(MODE === 'record')('renders the bash row as a terminal card in the real browser', async () => { it.skipIf(MODE === 'record')('renders the bash row as a terminal card in the real browser', async () => {
onTestFailed(() => saveFailureShot(page, 'web-e2e-navigation-terminal')) onTestFailed(() => saveFailureShot(page, 'web-e2e-navigation-terminal'))
await page.getByRole('tab', { name: 'Chat' }).click() await page.getByRole('tab', { name: 'Chat' }).click()
// The card is resident in the keyed bash row (no expand gesture): the // The card is expand-gated behind the whole-row toggle (the unified
// recorded command's own output sits in the message flow, derived from the // tool-row interaction): open it if a previous case left it collapsed.
// logged call/result presentations alone. // Expanded, the recorded command's own output sits in the message flow,
const card = page.locator('[data-sample="bash-global"] ~ [data-terminal], [data-sample="bash-global"] [data-terminal]').first() // derived from the logged call/result presentations alone.
const bashRow = page.locator('[data-sample="bash-global"]').first()
await bashRow.waitFor({ timeout: 15_000 })
if (await bashRow.getAttribute('aria-expanded') !== 'true') await bashRow.click()
const card = page.locator('[data-sample="bash-global"] ~ div [data-terminal]').first()
await card.waitFor({ timeout: 15_000 }) await card.waitFor({ timeout: 15_000 })
// Real layout, not jsdom's stub (which computes no geometry at all): // Real layout, not jsdom's stub (which computes no geometry at all):
// squeeze the output pane below its content width and the line must keep // squeeze the output pane below its content width and the line must keep

View File

@@ -15,13 +15,15 @@
- img - img
- img - img
- text: "Think The user wants me to write a single `run_code` program that:" - text: "Think The user wants me to write a single `run_code` program that:"
- button: - button "Code Run bash echo and catch missing file read":
- img - img
- img - img
- text: Code Run bash echo and catch missing file read - text: Code Run bash echo and catch missing file read
- img - img
- text: Bash Echo CODE_ROUND_OK Read - text: Bash Echo CODE_ROUND_OK
- button "missing.txt" - 'button "Read Error: cannot read \"{{cwd}}/workspace/missing.txt\": not found"':
- img
- text: "Read Error: cannot read \"{{cwd}}/workspace/missing.txt\": not found"
- button "Think The program ran successfully. Let me now reply DONE as instructed.": - button "Think The program ran successfully. Let me now reply DONE as instructed.":
- img - img
- img - img

View File

@@ -15,27 +15,30 @@
- img - img
- img - img
- text: "Think The user wants me to:" - text: "Think The user wants me to:"
- button: - button "Inspect temporary":
- img - img
- img - img
- text: Inspect temporary - text: Inspect temporary
- 'button "Think Good, no temporary plugins running. Now step 2: call cordis_mount with the exact code."': - 'button "Think Good, no temporary plugins running. Now step 2: call cordis_mount with the exact code."':
- img - img
- img - img
- text: "Think Good, no temporary plugins running. Now step 2: call cordis_mount with the exact code." - text: "Think Good, no temporary plugins running. Now step 2: call cordis_mount with the exact code."
- button [expanded]: - 'button "Mount temporary Plugin return { name: \"snapshot-noop\", apply(ctx) {} }" [expanded]':
- img - img
- text: Mount temporary Plugin typescript - text: "Mount temporary Plugin return { name: \"snapshot-noop\", apply(ctx) {} }"
- text: typescript
- button "复制" - button "复制"
- code: "return { name: \"snapshot-noop\", apply(ctx) {} }" - code: "return { name: \"snapshot-noop\", apply(ctx) {} }"
- text: OUT Temporary Plugin dyn-1 is running (plugin "snapshot-noop"; available until unmounted or DSH restarts).
- button "Inspect"
- 'button "Think The id is \"dyn-1\". Now step 3: call cordis_unmount with that id."': - 'button "Think The id is \"dyn-1\". Now step 3: call cordis_unmount with that id."':
- img - img
- img - img
- text: "Think The id is \"dyn-1\". Now step 3: call cordis_unmount with that id." - text: "Think The id is \"dyn-1\". Now step 3: call cordis_unmount with that id."
- button: - button "Unmount temporary Plugin dyn-1":
- img - img
- img - img
- text: Unmount temporary Plugin dyn-1 - text: Unmount temporary Plugin dyn-1
- button "Think All three calls succeeded. I should now reply exactly \"CORDIS_UI_DONE\" and stop.": - button "Think All three calls succeeded. I should now reply exactly \"CORDIS_UI_DONE\" and stop.":
- img - img
- img - img

View File

@@ -15,10 +15,10 @@
- img - img
- img - img
- text: Think The user wants me to run a simple bash command and reply with "DONE". - text: Think The user wants me to run a simple bash command and reply with "DONE".
- img - button "Bash Echo the test string":
- text: Bash Echo the test string 已完成 workspace echo WEB_E2E_OK - img
- button "复制" - img
- text: WEB_E2E_OK - text: Bash Echo the test string
- button "Think The command executed successfully and output \"WEB_E2E_OK\". I just need to reply with \"DONE\".": - button "Think The command executed successfully and output \"WEB_E2E_OK\". I just need to reply with \"DONE\".":
- img - img
- img - img

View File

@@ -16,12 +16,16 @@
- img - img
- img - img
- text: Think The user wants me to read a.txt and b.txt, then reply with "DONE". Let me do both reads in parallel. - text: Think The user wants me to read a.txt and b.txt, then reply with "DONE". Let me do both reads in parallel.
- img - button "Read a.txt":
- text: Read - img
- button "a.txt" - img
- img - text: Read
- text: Read - button "a.txt"
- button "b.txt" - button "Read b.txt":
- img
- img
- text: Read
- button "b.txt"
- button "Think Both files have been read. a.txt contains \"alpha\" and b.txt contains \"beta\". I'll now reply with DONE as instructed.": - button "Think Both files have been read. a.txt contains \"alpha\" and b.txt contains \"beta\". I'll now reply with DONE as instructed.":
- img - img
- img - img

View File

@@ -25,10 +25,10 @@
- button "在新对话中分支": - button "在新对话中分支":
- img - img
- text: {{clock}} - text: {{clock}}
- button: - 'button "Tool call exit_plan_mode · # Add `--greeting` flag to CLI"':
- img - img
- img - img
- text: "Tool call exit_plan_mode · # Add `--greeting` flag to CLI" - text: "Tool call exit_plan_mode · # Add `--greeting` flag to CLI"
- 'button "Think The plan was approved. The user''s last instruction says: \"Once the plan is approved, reply with the single word DONE and stop.\" So I should just reply with DONE and stop."': - 'button "Think The plan was approved. The user''s last instruction says: \"Once the plan is approved, reply with the single word DONE and stop.\" So I should just reply with DONE and stop."':
- img - img
- img - img

View File

@@ -15,10 +15,10 @@
- img - img
- img - img
- text: Think The user wants me to use the ask_user_question tool with specific parameters. Let me do exactly that. - text: Think The user wants me to use the ask_user_question tool with specific parameters. Let me do exactly that.
- button: - button "Ask question 1/1 answered":
- img - img
- img - img
- text: Ask question 1/1 answered - text: Ask question 1/1 answered
- button "Think The user answered \"Blue\". I should now reply with the single word DONE and stop.": - button "Think The user answered \"Blue\". I should now reply with the single word DONE and stop.":
- img - img
- img - img

View File

@@ -15,12 +15,16 @@
- img - img
- img - img
- text: Think The user wants me to read a.txt and b.txt, then reply with "DONE". Let me do both reads in parallel. - text: Think The user wants me to read a.txt and b.txt, then reply with "DONE". Let me do both reads in parallel.
- img - button "Read a.txt":
- text: Read - img
- button "a.txt" - img
- img - text: Read
- text: Read - button "a.txt"
- button "b.txt" - button "Read b.txt":
- img
- img
- text: Read
- button "b.txt"
- button "Think Both files have been read. a.txt contains \"alpha\" and b.txt contains \"beta\". I'll now reply with DONE as instructed.": - button "Think Both files have been read. a.txt contains \"alpha\" and b.txt contains \"beta\". I'll now reply with DONE as instructed.":
- img - img
- img - img

View File

@@ -15,10 +15,10 @@
- img - img
- img - img
- text: Think The user wants me to use the ask_user_question tool to ask them a specific question with the given parameters. Let me do exactly that. - text: Think The user wants me to use the ask_user_question tool to ask them a specific question with the given parameters. Let me do exactly that.
- button: - button "Ask question waiting":
- img - img
- img - img
- text: Ask question waiting - text: Ask question waiting
- region "Ready to continue?": - region "Ready to continue?":
- text: Checkpoint - text: Checkpoint
- heading "Ready to continue?" [level=2] - heading "Ready to continue?" [level=2]

View File

@@ -15,10 +15,11 @@
- img - img
- img - img
- text: Think The user wants me to use the ask_user_question tool to ask them a specific question with the given parameters. Let me do exactly that. - text: Think The user wants me to use the ask_user_question tool to ask them a specific question with the given parameters. Let me do exactly that.
- button: - button "Ask question 1/1 answered":
- img - img
- img - img
- text: "Ask question 1/1 answered 插话 Interjection: include the word BANANA in your final reply." - text: Ask question 1/1 answered
- text: "插话 Interjection: include the word BANANA in your final reply."
- button "Think The user selected \"Yes\" and wants me to include the word \"BANANA\" in my final reply. Let me acknowledge their answer.": - button "Think The user selected \"Yes\" and wants me to include the word \"BANANA\" in my final reply. Let me acknowledge their answer.":
- img - img
- img - img