mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-24 04:01:10 -04:00
9e0d3976e1
Co-authored-by: Frank <frank@anoma.ly> Co-authored-by: Aarav Sareen <96787824+arvsrn@users.noreply.github.com> Co-authored-by: Brendan Allan <git@brendonovich.dev> Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Co-authored-by: Jack <jack@anoma.ly> Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com> Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com> Co-authored-by: opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com> Co-authored-by: James Long <longster@gmail.com> Co-authored-by: Dustin Deus <deusdustin@gmail.com> Co-authored-by: starptech <starptech@starptechs-MBP.fritz.box> Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com> Co-authored-by: 𝓛𝓲𝓽𝓽𝓵𝓮 𝓕𝓻𝓪𝓷𝓴 <little-frank@opencord.local> Co-authored-by: Dax <mail@thdxr.com> Co-authored-by: usrnk1 <7547651+usrnk1@users.noreply.github.com> Co-authored-by: Jay <53023+jayair@users.noreply.github.com> Co-authored-by: runvip <164729189+runvip@users.noreply.github.com> Co-authored-by: opencode <opencode@sst.dev> Co-authored-by: Julian Coy <julian@ex-machina.co> Co-authored-by: Vladimir Glafirov <vglafirov@gitlab.com> Co-authored-by: Adam <2363879+adamdotdevin@users.noreply.github.com> Co-authored-by: Kit Langton <kit.langton@gmail.com> Co-authored-by: Simon Klee <hello@simonklee.dk> Co-authored-by: Jay <air@live.ca> Co-authored-by: David Hill <1879069+iamdavidhill@users.noreply.github.com>
122 lines
3.8 KiB
TypeScript
122 lines
3.8 KiB
TypeScript
import { test } from "@playwright/test"
|
|
import {
|
|
defineVisualRegions,
|
|
reportVisualStability,
|
|
startVisualProbe,
|
|
stopVisualProbe,
|
|
visualPlan,
|
|
} from "../../utils/visual-stability"
|
|
import {
|
|
assistantMessage,
|
|
partUpdated,
|
|
setupTimeline,
|
|
textPart,
|
|
toolPart,
|
|
userMessage,
|
|
waitForVisualSettle,
|
|
} from "./fixture"
|
|
|
|
const profiles = [
|
|
{ name: "edit", tool: "edit", input: { filePath: "src/edit.ts" } },
|
|
{
|
|
name: "multi patch",
|
|
tool: "apply_patch",
|
|
input: { files: ["src/a.ts", "src/b.ts", "src/old.ts", "src/moved.ts"] },
|
|
},
|
|
] as const
|
|
|
|
for (const profile of profiles) {
|
|
test(`stabilizes ${profile.name} pending to completed`, async ({ page }, testInfo) => {
|
|
const partID = `prt_file_matrix_${profiles.indexOf(profile)}`
|
|
const followingID = `prt_file_matrix_following_${profiles.indexOf(profile)}`
|
|
const timeline = await setupTimeline(page, {
|
|
messages: [
|
|
userMessage(),
|
|
assistantMessage(
|
|
[
|
|
toolPart(partID, profile.tool, "pending", profile.input),
|
|
textPart(followingID, `Following ${profile.name}`),
|
|
],
|
|
{ completed: false },
|
|
),
|
|
],
|
|
settings: { editToolPartsExpanded: true },
|
|
cpuRate: 4,
|
|
})
|
|
await waitForVisualSettle(page, [`[data-timeline-part-id="${partID}"]`, `[data-timeline-part-id="${followingID}"]`])
|
|
const regions = defineVisualRegions({
|
|
tool: { selector: `[data-timeline-part-id="${partID}"]`, closest: '[data-timeline-row="AssistantPart"]' },
|
|
following: {
|
|
selector: `[data-timeline-part-id="${followingID}"]`,
|
|
closest: '[data-timeline-row="AssistantPart"]',
|
|
},
|
|
})
|
|
await startVisualProbe(page, regions)
|
|
await timeline.send(partUpdated(toolPart(partID, profile.tool, "running", profile.input)), 180)
|
|
await timeline.send(partUpdated(completedPart(partID, profile)), 900)
|
|
const trace = await stopVisualProbe<keyof typeof regions>(page)
|
|
await reportVisualStability(
|
|
testInfo,
|
|
`file-${profile.name}`,
|
|
trace,
|
|
visualPlan(
|
|
regions,
|
|
[
|
|
{ type: "required", regions: ["tool", "following"] },
|
|
{ type: "unique", regions: ["tool", "following"] },
|
|
{ type: "stable", regions: ["tool", "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: ["tool", "following"] },
|
|
],
|
|
{ perMarker: true },
|
|
),
|
|
)
|
|
})
|
|
}
|
|
|
|
function completedPart(partID: string, profile: (typeof profiles)[number]) {
|
|
if (profile.tool === "edit") {
|
|
return toolPart(partID, profile.tool, "completed", profile.input, {
|
|
metadata: {
|
|
filediff: {
|
|
file: "src/edit.ts",
|
|
additions: 50,
|
|
deletions: 50,
|
|
before: source(50, false),
|
|
after: source(50, true),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
const files = [
|
|
patchFile("src/a.ts", "update"),
|
|
patchFile("src/b.ts", "add"),
|
|
patchFile("src/old.ts", "delete"),
|
|
{ ...patchFile("src/moved.ts", "move"), move: "src/new-place.ts" },
|
|
]
|
|
return toolPart(partID, profile.tool, "completed", profile.input, { metadata: { files } })
|
|
}
|
|
|
|
function patchFile(filePath: string, type: "add" | "update" | "delete" | "move") {
|
|
return {
|
|
filePath,
|
|
relativePath: filePath,
|
|
type,
|
|
additions: type === "delete" ? 0 : 20,
|
|
deletions: type === "add" ? 0 : 20,
|
|
before: type === "add" ? undefined : source(20, false),
|
|
after: type === "delete" ? undefined : source(20, true),
|
|
}
|
|
}
|
|
|
|
function source(count: number, changed: boolean) {
|
|
return Array.from(
|
|
{ length: count },
|
|
(_, index) => `export const value${index} = ${changed ? index + 1 : index}\n`,
|
|
).join("")
|
|
}
|