mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-14 20:21:39 +03:00
103 lines
3.4 KiB
TypeScript
103 lines
3.4 KiB
TypeScript
// The composer with a lot in it: a 44,000-character saved draft, and a long prompt history with screenshots. At
|
||
// 1440×900.
|
||
import { bench, web } from "@hona/strobe"
|
||
import { fixture, mockStressTimeline } from "../e2e/utils/session-fixture"
|
||
import { countDraftEncodes, draftEnd, mockLargeDraft, recalled, seedHistory } from "./fixtures/composer"
|
||
import { installProjects } from "./fixtures/home"
|
||
import { cached } from "./fixtures/mock"
|
||
|
||
const composer = '[data-component="composer-editor"]'
|
||
|
||
const newSession = '[data-component="new-session"] [data-component="composer-editor"][contenteditable="true"]'
|
||
|
||
const typed = " Keep the existing error handling and add coverage."
|
||
|
||
export default bench({
|
||
targets: {
|
||
web: web({
|
||
expect: { title: "OpenCode" },
|
||
viewport: { width: 1440, height: 900 },
|
||
async prepare({ case: name, playwright, mock, url }) {
|
||
const server = new URL(url).origin
|
||
const page = cached(playwright.page, mock)
|
||
|
||
if (!name.includes("history")) {
|
||
await countDraftEncodes(page)
|
||
|
||
return mockLargeDraft(page, server)
|
||
}
|
||
|
||
await seedHistory(page, server)
|
||
await mockStressTimeline(page, { server })
|
||
await installProjects(page, [fixture.directory])
|
||
|
||
return { path: "/" }
|
||
},
|
||
url: ({ prepared }) => prepared.path,
|
||
}),
|
||
},
|
||
|
||
async setup({ case: name, page }) {
|
||
if (name.includes("history")) {
|
||
await page.waitFor('[data-action="home-new-session"]', { timeout: 60_000 })
|
||
await page.idle()
|
||
|
||
return
|
||
}
|
||
|
||
// The caret at the end of the large draft.
|
||
await page.waitFor(composer, { text: draftEnd, timeout: 60_000 })
|
||
await page.click(composer)
|
||
await page.press("ControlOrMeta+End")
|
||
await page.idle()
|
||
},
|
||
|
||
cases: {
|
||
// Each keystroke changes the draft and saves it; `count.draft.encode` is how many times the draft was encoded.
|
||
"type in a large draft": {
|
||
primary: "main.work",
|
||
metrics: ["interaction.p95", "count.draft.encode"],
|
||
async run({ page }) {
|
||
await page.type(composer, typed, { delay: 50 })
|
||
await page.idle()
|
||
},
|
||
async reset({ page }) {
|
||
for (let step = 0; step < typed.length; step++) await page.press("Backspace")
|
||
await page.idle()
|
||
},
|
||
},
|
||
|
||
// Twenty caret moves: each saves the caret position, not the text.
|
||
"move the cursor in a large draft": {
|
||
primary: "main.work",
|
||
metrics: ["interaction.p95", "count.draft.encode"],
|
||
async run({ page }) {
|
||
for (let step = 0; step < 20; step++) await page.press("ArrowLeft", { until: "frame" })
|
||
await page.idle()
|
||
},
|
||
async reset({ page }) {
|
||
await page.press("ControlOrMeta+End")
|
||
await page.idle()
|
||
},
|
||
},
|
||
|
||
// A new session's composer loads the history (counted: the run waits until the page settles), then ArrowUp
|
||
// recalls the newest prompt and its screenshot.
|
||
"recall a prompt from history": {
|
||
primary: "main.work",
|
||
metrics: ["run.duration"],
|
||
async run({ page }) {
|
||
await page.click('[data-action="home-new-session"]', { until: newSession })
|
||
await page.idle()
|
||
await page.press("ArrowUp")
|
||
await page.waitFor(newSession, { text: recalled })
|
||
await page.idle()
|
||
},
|
||
async reset({ page }) {
|
||
await page.goto("/", { until: '[data-action="home-new-session"]', timeout: 60_000 })
|
||
await page.idle()
|
||
},
|
||
},
|
||
},
|
||
})
|