Ctrl K
ComunidadGuías…

packages/app/perf/composer.bench.ts

Rama dev · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// 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({
  // What a launch sets up: the large draft, or the prompt history. Cases with the same one share a launch.
  setupKey: (ctx) => (ctx.case.includes("history") ? "history" : "draft"),

  targets: {
    web: web({
      expect: { title: "OpenCode" },
      viewport: { width: 1440, height: 900 },
      async prepare(ctx) {
        const { setupKey, url } = ctx
        const server = new URL(url).origin
        const page = cached(ctx)

        if (setupKey === "draft") {
          await countDraftEncodes(page)

          return mockLargeDraft(page, server)
        }

        await mockStressTimeline(page, { server })
        await installProjects(page, [fixture.directory])

        // A static file first: setup seeds the history before the app opens its store.
        return { path: "/favicon.svg" }
      },
      url: ({ prepared }) => prepared.path,
    }),
  },

  async setup({ setupKey, page }) {
    if (setupKey === "history") {
      await page.eval(seedHistory)
      await page.goto("/", { until: '[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()
      },
    },
  },
})