opencode/packages/app/component-tests/plugin-graph.spec.ts

61 lines
2.1 KiB
TypeScript

import { expect, sourceURL, story } from "../../stories/playwright/story"
import type { Entry } from "@opencode/plugin/gui/host"
const source = (path: string) => sourceURL(new URL(path, import.meta.url))
const modules = {
fixture: source("./plugin-host.fixture.tsx"),
builtins: source("../../gui-plugins/src/renderer.ts"),
}
story.beforeEach(async ({ mount }) => {
// Any story loads the app; the fixture mounts the real host beside it.
await mount("ui-line-comment--editor")
})
// Built-ins read each other's contracts at runtime with `ctx.use`, so each must keep working without any other. Every
// row boots the real host with one built-in disabled; the first row disables nothing.
story("built-ins: each activates without each other built-in", async ({ page }) => {
const outcomes = await page.evaluate(async (modules) => {
const [{ mountPlugins, until }, { builtins }] = await Promise.all([
import(modules.fixture),
import(modules.builtins),
])
// The window this host serves has no OS, so OS-specific built-ins are left out as the app leaves them out.
const composition: readonly Entry[] = builtins
const definitions = composition.filter((definition) => !definition.os)
const rows = ["", ...definitions.map((definition) => definition.id)]
const results = []
for (const disabled of rows) {
const host = mountPlugins({ definitions, disabled: disabled ? [disabled] : [] })
host.release()
await until(() => host.ready())
results.push({
disabled,
results: definitions.flatMap((definition) =>
definition.id === disabled
? []
: [
{
id: definition.id,
status: host.status(definition.id),
failure: host.failure(definition.id)?.error ?? null,
},
],
),
})
host.unmount()
}
return results
}, modules)
expect(outcomes).toEqual(
outcomes.map((outcome) => ({
...outcome,
results: outcome.results.map((item) => ({ id: item.id, status: "active", failure: null })),
})),
)
})