Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com> Co-authored-by: opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com> Co-authored-by: Aarav Sareen <96787824+arvsrn@users.noreply.github.com> Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com> Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Co-authored-by: Aiden Cline <rekram1-node@users.noreply.github.com> Co-authored-by: opencode <opencode@sst.dev> Co-authored-by: Jay <53023+jayair@users.noreply.github.com> Co-authored-by: David Hill <1879069+iamdavidhill@users.noreply.github.com> Co-authored-by: BB84 <110078428+BB-84C@users.noreply.github.com> Co-authored-by: Aiden Cline <aidenpcline@gmail.com> Co-authored-by: Dax <mail@thdxr.com> Co-authored-by: Brendan Allan <git@brendonovich.dev> Co-authored-by: Jay V <air@live.ca> Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com> Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Co-authored-by: Dustin Deus <deusdustin@gmail.com> Co-authored-by: Frank <frank@anoma.ly> Co-authored-by: usrnk1 <7547651+usrnk1@users.noreply.github.com> Co-authored-by: Jack <jack@anoma.ly> Co-authored-by: Sebastian <hasta84@gmail.com> Co-authored-by: Jérôme Benoit <jerome.benoit@sap.com> Co-authored-by: Test User <test@test.com> Co-authored-by: Simon Klee <hello@simonklee.dk> Co-authored-by: Rahul A Mistry <149420892+ProdigyRahul@users.noreply.github.com> Co-authored-by: Qiping Li <liqiping1991@gmail.com> Co-authored-by: liqiping <liqiping@msh.team> Co-authored-by: OpeOginni <107570612+OpeOginni@users.noreply.github.com> Co-authored-by: Matthias Reso <13337103+mreso@users.noreply.github.com> Co-authored-by: tobwen <1864057+tobwen@users.noreply.github.com> Co-authored-by: Daniel Polito <danielbpolito@gmail.com> Co-authored-by: opencode <noreply@opencode.ai> Co-authored-by: Devin R Leopold <devin.leopold@gmail.com> Co-authored-by: Zach Bruggeman <mail@bruggie.com> Co-authored-by: Zach Bruggeman <zbruggeman@ramp.com> Co-authored-by: Kit Langton <kit.langton@gmail.com> Co-authored-by: David Siewert <david1gruppenplan@gmail.com> Co-authored-by: Andrei Dziahel <develop7@develop7.info> Co-authored-by: adityachaudhary99 <adityaachaudhary2003@gmail.com> Co-authored-by: Vladimir Glafirov <vglafirov@gitlab.com> Co-authored-by: Matt Carey <mcarey@cloudflare.com>
113 lines
3.6 KiB
TypeScript
113 lines
3.6 KiB
TypeScript
import { expect, test } from "@playwright/test"
|
|
import {
|
|
defineVisualRegions,
|
|
reportVisualStability,
|
|
startVisualProbe,
|
|
stopVisualProbe,
|
|
visualPlan,
|
|
} from "../../utils/visual-stability"
|
|
import {
|
|
assistantMessage,
|
|
partUpdated,
|
|
setupTimeline,
|
|
textPart,
|
|
toolPart,
|
|
userMessage,
|
|
waitForVisualSettle,
|
|
} from "./fixture"
|
|
|
|
test("adds patch files incrementally without resetting outer expansion", async ({ page }, testInfo) => {
|
|
const patchID = "prt_incremental_01_patch"
|
|
const followingID = "prt_incremental_02_following"
|
|
const first = patchFile("src/a.ts", "update")
|
|
const timeline = await setupTimeline(page, {
|
|
messages: [
|
|
userMessage(),
|
|
assistantMessage(
|
|
[
|
|
toolPart(patchID, "apply_patch", "running", { files: [first.filePath] }, { metadata: { files: [first] } }),
|
|
textPart(followingID, "Following incremental patch"),
|
|
],
|
|
{ completed: false },
|
|
),
|
|
],
|
|
settings: { editToolPartsExpanded: true },
|
|
cpuRate: 4,
|
|
seedHistory: true,
|
|
})
|
|
const trigger = page.locator(`[data-timeline-part-id="${patchID}"] [data-slot="collapsible-trigger"]`).first()
|
|
await expect(trigger).toHaveAttribute("aria-expanded", "true")
|
|
await waitForVisualSettle(page, [`[data-timeline-part-id="${patchID}"]`, `[data-timeline-part-id="${followingID}"]`])
|
|
const regions = defineVisualRegions({
|
|
patch: { selector: `[data-timeline-part-id="${patchID}"]`, closest: '[data-timeline-row="AssistantPart"]' },
|
|
following: { selector: `[data-timeline-part-id="${followingID}"]`, closest: '[data-timeline-row="AssistantPart"]' },
|
|
})
|
|
await startVisualProbe(page, regions)
|
|
const second = patchFile("src/b.ts", "add")
|
|
const third = patchFile("src/old.ts", "delete")
|
|
await timeline.send(
|
|
partUpdated(
|
|
toolPart(
|
|
patchID,
|
|
"apply_patch",
|
|
"running",
|
|
{ files: [first.filePath, second.filePath] },
|
|
{ metadata: { files: [first, second] } },
|
|
),
|
|
),
|
|
240,
|
|
)
|
|
await timeline.send(
|
|
partUpdated(
|
|
toolPart(
|
|
patchID,
|
|
"apply_patch",
|
|
"completed",
|
|
{ files: [first.filePath, second.filePath, third.filePath] },
|
|
{ metadata: { files: [first, second, third] } },
|
|
),
|
|
),
|
|
800,
|
|
)
|
|
const trace = await stopVisualProbe<keyof typeof regions>(page)
|
|
await reportVisualStability(
|
|
testInfo,
|
|
"incremental-patch",
|
|
trace,
|
|
visualPlan(
|
|
regions,
|
|
[
|
|
{ type: "required", regions: ["patch", "following"] },
|
|
{ type: "unique", regions: ["patch", "following"] },
|
|
{ type: "stable", regions: ["patch", "following"] },
|
|
{ type: "opacity", regions: "all" },
|
|
{ type: "continuity", regions: "all" },
|
|
{ type: "motion", regions: ["following"], maxPositionReversals: 0 },
|
|
{ type: "label-stability", regions: "all" },
|
|
{ type: "preserve-bottom-anchor" },
|
|
{ type: "flow", regions: ["patch", "following"] },
|
|
],
|
|
{ perMarker: true },
|
|
),
|
|
)
|
|
await expect(trigger).toHaveAttribute("aria-expanded", "true")
|
|
await expect(page.locator('[data-scope="apply-patch"] [data-type="delete"]')).toBeVisible()
|
|
})
|
|
|
|
function patchFile(filePath: string, type: "add" | "update" | "delete") {
|
|
return {
|
|
filePath,
|
|
relativePath: filePath,
|
|
type,
|
|
additions: type === "delete" ? 0 : 4,
|
|
deletions: type === "add" ? 0 : 3,
|
|
before: type === "add" ? undefined : source(false),
|
|
after: type === "delete" ? undefined : source(true),
|
|
}
|
|
}
|
|
|
|
function source(changed: boolean) {
|
|
return Array.from({ length: 12 }, (_, index) => `export const value${index} = ${changed ? index + 1 : index}\n`).join(
|
|
"",
|
|
)
|
|
}
|