Download packages/app/e2e/performance/timeline-stability/interaction.spec.ts from SaylorTwift/opencode: direct link, hf CLI and curl.
- Browser
- Download file 9.54 kB
-
https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/app/e2e/performance/timeline-stability/interaction.spec.ts
- Command line
-
hf download hf://SaylorTwift/opencode/packages/app/e2e/performance/timeline-stability/interaction.spec.ts
-
curl -L -o interaction.spec.ts https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/app/e2e/performance/timeline-stability/interaction.spec.ts
9.54 kB
| import { expect, test } from "@playwright/test" | |
| import { | |
| defineVisualRegions, | |
| reportVisualStability, | |
| startVisualProbe, | |
| stopVisualProbe, | |
| visualPlan, | |
| } from "../../utils/visual-stability" | |
| import { assistantMessage, setupTimeline, shell, textPart, toolPart, userMessage, waitForVisualSettle } from "./fixture" | |
| test("expands and collapses a long completed shell without overlap", async ({ page }, testInfo) => { | |
| const shellID = "prt_interaction_01_shell" | |
| const followingID = "prt_interaction_02_following" | |
| await setupTimeline(page, { | |
| messages: [ | |
| userMessage(), | |
| assistantMessage([shell(shellID, "completed", lines(50)), textPart(followingID, "Following shell expansion")]), | |
| ], | |
| settings: { shellToolPartsExpanded: false }, | |
| cpuRate: 4, | |
| seedHistory: true, | |
| }) | |
| const trigger = page.locator(`[data-timeline-part-id="${shellID}"] [data-slot="collapsible-trigger"]`) | |
| await waitForVisualSettle(page, [`[data-timeline-part-id="${shellID}"]`, `[data-timeline-part-id="${followingID}"]`]) | |
| const regions = defineVisualRegions({ | |
| shell: { selector: `[data-timeline-part-id="${shellID}"]`, closest: '[data-timeline-row="AssistantPart"]' }, | |
| following: { selector: `[data-timeline-part-id="${followingID}"]`, closest: '[data-timeline-row="AssistantPart"]' }, | |
| }) | |
| const plan = visualPlan(regions, [ | |
| { type: "required", regions: ["shell", "following"] }, | |
| { type: "unique", regions: ["shell", "following"] }, | |
| { type: "stable", regions: ["shell", "following"] }, | |
| { type: "opacity", regions: "all" }, | |
| { type: "continuity", regions: "all" }, | |
| { type: "motion", regions: "all", maxPositionReversals: 0 }, | |
| { type: "label-stability", regions: "all" }, | |
| { type: "preserve-bottom-anchor" }, | |
| { type: "flow", regions: ["shell", "following"] }, | |
| ]) | |
| await startVisualProbe(page, regions) | |
| await trigger.click() | |
| await expect(trigger).toHaveAttribute("aria-expanded", "true") | |
| await page.waitForTimeout(500) | |
| const expanded = await stopVisualProbe<keyof typeof regions>(page) | |
| await reportVisualStability(testInfo, "shell-expand", expanded, plan) | |
| await startVisualProbe(page, regions) | |
| await trigger.click() | |
| await expect(trigger).toHaveAttribute("aria-expanded", "false") | |
| await page.waitForTimeout(500) | |
| const collapsed = await stopVisualProbe<keyof typeof regions>(page) | |
| await reportVisualStability(testInfo, "shell-collapse", collapsed, plan) | |
| }) | |
| test("expands and collapses a completed context group without overlap", async ({ page }, testInfo) => { | |
| const ids = [ | |
| "prt_interaction_01_read", | |
| "prt_interaction_02_glob", | |
| "prt_interaction_03_grep", | |
| "prt_interaction_04_list", | |
| ] | |
| const group = `[data-timeline-part-ids="${ids.join(",")}"]` | |
| const followingID = "prt_interaction_context_following" | |
| await setupTimeline(page, { | |
| messages: [ | |
| userMessage(), | |
| assistantMessage([ | |
| toolPart(ids[0]!, "read", "completed", { filePath: "src/a.ts" }), | |
| toolPart(ids[1]!, "glob", "completed", { path: ".", pattern: "**/*.ts" }), | |
| toolPart(ids[2]!, "grep", "completed", { path: ".", pattern: "stable" }), | |
| toolPart(ids[3]!, "list", "completed", { path: "src" }), | |
| textPart(followingID, "Following context expansion"), | |
| ]), | |
| ], | |
| cpuRate: 4, | |
| seedHistory: true, | |
| }) | |
| const trigger = page.locator(`${group} [data-slot="collapsible-trigger"]`) | |
| await waitForVisualSettle(page, [group, `[data-timeline-part-id="${followingID}"]`]) | |
| for (const [name, expanded] of [ | |
| ["context-expand", true], | |
| ["context-collapse", false], | |
| ["context-reexpand", true], | |
| ] as const) { | |
| const regions = defineVisualRegions({ | |
| context: { selector: group, closest: '[data-timeline-row="AssistantPart"]' }, | |
| following: { | |
| selector: `[data-timeline-part-id="${followingID}"]`, | |
| closest: '[data-timeline-row="AssistantPart"]', | |
| }, | |
| }) | |
| await startVisualProbe(page, regions) | |
| await trigger.click() | |
| await expect(trigger).toHaveAttribute("aria-expanded", String(expanded)) | |
| await page.waitForTimeout(500) | |
| const trace = await stopVisualProbe<keyof typeof regions>(page) | |
| await reportVisualStability( | |
| testInfo, | |
| name, | |
| trace, | |
| visualPlan(regions, [ | |
| { type: "required", regions: ["context", "following"] }, | |
| { type: "unique", regions: ["context", "following"] }, | |
| { type: "stable", regions: ["context", "following"] }, | |
| { type: "opacity", regions: "all" }, | |
| { type: "continuity", regions: "all" }, | |
| { type: "motion", regions: "all", maxPositionReversals: 0 }, | |
| { type: "label-stability", regions: "all" }, | |
| { type: "preserve-bottom-anchor" }, | |
| { type: "flow", regions: ["context", "following"] }, | |
| ]), | |
| ) | |
| } | |
| }) | |
| test("expands and collapses an edit diff without moving twice", async ({ page }, testInfo) => { | |
| const editID = "prt_interaction_edit" | |
| const followingID = "prt_interaction_edit_following" | |
| await setupTimeline(page, { | |
| messages: [ | |
| userMessage(), | |
| assistantMessage([ | |
| toolPart( | |
| editID, | |
| "edit", | |
| "completed", | |
| { filePath: "src/edit.ts" }, | |
| { | |
| metadata: { | |
| filediff: { | |
| file: "src/edit.ts", | |
| additions: 40, | |
| deletions: 40, | |
| before: source(40, false), | |
| after: source(40, true), | |
| }, | |
| }, | |
| }, | |
| ), | |
| textPart(followingID, "Following edit expansion"), | |
| ]), | |
| ], | |
| settings: { editToolPartsExpanded: false }, | |
| cpuRate: 4, | |
| seedHistory: true, | |
| }) | |
| const trigger = page.locator(`[data-timeline-part-id="${editID}"] [data-slot="collapsible-trigger"]`).first() | |
| await waitForVisualSettle(page, [`[data-timeline-part-id="${editID}"]`, `[data-timeline-part-id="${followingID}"]`]) | |
| const regions = defineVisualRegions({ | |
| edit: { selector: `[data-timeline-part-id="${editID}"]`, closest: '[data-timeline-row="AssistantPart"]' }, | |
| following: { selector: `[data-timeline-part-id="${followingID}"]`, closest: '[data-timeline-row="AssistantPart"]' }, | |
| }) | |
| await startVisualProbe(page, regions) | |
| await trigger.click() | |
| await expect(trigger).toHaveAttribute("aria-expanded", "true") | |
| await page.waitForTimeout(900) | |
| const trace = await stopVisualProbe<keyof typeof regions>(page) | |
| await reportVisualStability( | |
| testInfo, | |
| "edit-expand", | |
| trace, | |
| visualPlan(regions, [ | |
| { type: "required", regions: ["edit", "following"] }, | |
| { type: "unique", regions: ["edit", "following"] }, | |
| { type: "stable", regions: ["edit", "following"] }, | |
| { type: "opacity", regions: "all" }, | |
| { type: "continuity", regions: "all" }, | |
| { type: "motion", regions: "all", maxPositionReversals: 0, maxReversals: 1 }, | |
| { type: "label-stability", regions: "all" }, | |
| { type: "preserve-bottom-anchor" }, | |
| { type: "flow", regions: ["edit", "following"] }, | |
| ]), | |
| ) | |
| }) | |
| test("shows all and expands historical diff summary without overlap", async ({ page }, testInfo) => { | |
| const firstUser = userMessage(undefined, { | |
| summary: { | |
| diffs: Array.from({ length: 12 }, (_, index) => ({ | |
| file: `src/diff-${index}.ts`, | |
| additions: 1, | |
| deletions: 1, | |
| patch: `@@ -1 +1 @@\n-export const value = ${index}\n+export const value = ${index + 1}`, | |
| })), | |
| }, | |
| }) | |
| const nextUserID = "msg_2000_diff_interaction_user" | |
| await setupTimeline(page, { | |
| messages: [ | |
| firstUser, | |
| assistantMessage(), | |
| userMessage(undefined, { id: nextUserID, created: 1700000010000 }), | |
| assistantMessage([], { | |
| id: "msg_2001_diff_interaction_assistant", | |
| parentID: nextUserID, | |
| created: 1700000011000, | |
| }), | |
| ], | |
| cpuRate: 4, | |
| }) | |
| const scroller = page.locator(".scroll-view__viewport", { has: page.locator("[data-timeline-row]") }) | |
| await scroller.evaluate((element) => (element.scrollTop = 0)) | |
| const diff = page.locator('[data-timeline-row="DiffSummary"]') | |
| const following = page.locator(`[data-message-id="${nextUserID}"]`).first() | |
| await expect(diff).toBeVisible() | |
| const regions = defineVisualRegions({ | |
| diff: { selector: '[data-timeline-row="DiffSummary"]' }, | |
| following: { selector: `[data-message-id="${nextUserID}"]` }, | |
| }) | |
| await startVisualProbe(page, regions) | |
| await page.getByText(/show all/i).click() | |
| await page.waitForTimeout(500) | |
| await diff.locator('[data-slot="session-turn-diff-trigger"]').first().click() | |
| await page.waitForTimeout(900) | |
| const trace = await stopVisualProbe<keyof typeof regions>(page) | |
| await reportVisualStability( | |
| testInfo, | |
| "diff-summary-expand", | |
| trace, | |
| visualPlan(regions, [ | |
| { type: "required", regions: ["diff", "following"] }, | |
| { type: "unique", regions: ["diff", "following"] }, | |
| { type: "stable", regions: ["diff", "following"] }, | |
| { type: "opacity", regions: "all" }, | |
| { type: "continuity", regions: "all" }, | |
| { type: "motion", regions: "all", maxPositionReversals: 1, maxReversals: 2 }, | |
| { type: "label-stability", regions: "all" }, | |
| { type: "flow", regions: ["diff", "following"] }, | |
| ]), | |
| ) | |
| }) | |
| function lines(count: number) { | |
| return Array.from({ length: count }, (_, index) => `line ${index + 1}`).join("\n") | |
| } | |
| function source(count: number, changed: boolean) { | |
| return Array.from( | |
| { length: count }, | |
| (_, index) => `export const value${index} = ${changed ? index + 1 : index}\n`, | |
| ).join("") | |
| } | |