Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ jobs:
fi
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# ubuntu-latest ships shellcheck. install.sh is served at berthd.app/install.
- run: shellcheck site/install.sh scripts/build-release.sh scripts/build-tmux.sh scripts/publish.sh scripts/mac-release.sh scripts/linux-release.sh
- run: shellcheck site/install.sh scripts/build-release.sh scripts/build-tmux.sh scripts/publish.sh scripts/mac-release.sh scripts/linux-release.sh scripts/release-leadline-helper.sh
# The release tests (warnings and errors; their style is their own).
- run: shellcheck -x -S warning scripts/release-check.sh scripts/fresh-user-test.sh scripts/linux-box-test.sh scripts/upgrade-test.sh scripts/release-test/common.sh scripts/release-test/macos/lib.sh scripts/release-test/macos/launchctl scripts/release-test/linux/lib.sh scripts/release-test/linux/fake-chromium
- run: sh -n site/install.sh && dash -n site/install.sh
Expand Down
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ endif
# berth-leadline is the box-side helper that records what code did in
# development: queries, traces and logs (internal/leadline/API.md). It is
# built like berthd, static and without cgo, for every box platform and for
# a Mac that is its own box, side by side in bin/. Nothing installs it yet:
# it is not part of `all`, of the app or of a release.
# a Mac that is its own box, side by side in bin/. It is not part of `all`,
# of the app or of Shipyard's own releases: the Leadline plugin's manifest
# names these builds by checksum, and Shipyard installs the one for a box
# when the plugin's helper is turned on there (internal/box/helpers.go).
# scripts/release-leadline-helper.sh builds them with this target, lists
# them in site/plugins/ and uploads them to a release of their own.
.PHONY: leadline
leadline:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GO) build -trimpath -ldflags="$(LDFLAGS)" -o $(BIN)/berth-leadline-linux-amd64 ./cmd/berth-leadline
Expand Down
95 changes: 95 additions & 0 deletions app/e2e/a11y-scenes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -567,5 +567,100 @@ export const scenes: Scene[] = [
await expect(app.page.getByRole("dialog")).toBeVisible();
},
},
// Leadline's panels (plugins/leadline) on the mock helper's fixtures
// (src/lib/mock-helper.ts): a list with a row's detail open beside it.
{
id: "leadline-queries",
async run(app, theme) {
const p = await leadline(app, theme, "devl/checkout-fix", "Queries");
await p.getByTestId("leadline-row").filter({ hasText: "FROM order_items" }).click();
await expect(p.getByTestId("leadline-detail").getByTestId("leadline-traces").first()).toBeVisible();
},
},
{
id: "leadline-traces",
async run(app, theme) {
const p = await leadline(app, theme, "devl/checkout-fix", "Traces");
await p.getByTestId("leadline-row").filter({ hasText: "POST /api/checkout" }).first().click();
await p.getByTestId("leadline-span").filter({ hasText: "INSERT INTO orders" }).click();
await expect(p.getByTestId("leadline-span-info")).toBeVisible();
},
},
{
id: "leadline-logs",
async run(app, theme) {
const p = await leadline(app, theme, "devl/checkout-fix", "Logs");
await p.getByTestId("leadline-row").filter({ hasText: "webhook failed" }).first().click();
await expect(p.getByTestId("leadline-log-info")).toBeVisible();
},
},
{
id: "leadline-endpoints",
async run(app, theme) {
const p = await leadline(app, theme, "devl/checkout-fix", "Endpoints");
await p.getByTestId("leadline-row").filter({ hasText: "webhooks" }).click();
await expect(p.getByTestId("leadline-detail").getByTestId("leadline-traces").first()).toBeVisible();
},
},
{
id: "leadline-screen",
async run(app, theme) {
await app.open({ theme });
// Its sidebar item starts under More: the palette's command is there
// once the plugin has loaded.
const input = app.page.getByRole("combobox", { name: "Search sessions, worktrees and commands" });
const command = app.page.getByRole("option", { name: /^Show Leadline/ });
await expect(async () => {
if (!(await input.isVisible())) await app.page.keyboard.press("Meta+k");
await input.fill("Show Leadline");
if (!(await command.isVisible())) await app.page.keyboard.press("Escape");
await expect(command).toBeVisible({ timeout: 500 });
}).toPass();
await command.click();
await expect(app.page.getByTestId("leadline-heard").first()).toBeVisible();
},
},
{
id: "leadline-off",
extra: true,
async run(app, theme) {
const p = await leadline(app, theme, "gpu/ci-flake", "Queries");
await p.getByRole("button", { name: "Turn on…" }).click();
await expect(app.page.getByRole("alertdialog")).toBeVisible();
},
},
{
id: "leadline-nothing-yet",
extra: true,
async run(app, theme) {
const p = await leadline(app, theme, "devl/qa-deck", "Traces");
await expect(p.getByTestId("leadline-notice")).toContainText("Nothing from qa-deck yet");
},
},
{
id: "leadline-send",
extra: true,
async run(app, theme) {
const p = await leadline(app, theme, "devl/checkout-fix", "Endpoints");
await p.getByRole("button", { name: "Send this failing endpoint to the agent" }).click();
await expect(app.page.getByTestId("leadline-send").getByRole("textbox")).toBeVisible();
},
},
];

// leadline opens one of Leadline's panels in a worktree, once the plugin
// has loaded and the "+" menu lists it.
async function leadline(app: App, theme: string, wt: string, title: string) {
await app.open({ theme });
await app.openWorktree(wt);
const option = app.page.getByRole("option", { name: new RegExp(`^${title}`) });
await expect(async () => {
if (!(await option.isVisible())) await app.page.getByRole("button", { name: "New tab" }).click();
await expect(option).toBeVisible({ timeout: 1000 });
}).toPass();
await option.click();
const p = app.page.locator(`[data-testid=leadline][data-leadline=${title.toLowerCase()}]:visible`);
await expect(p.getByTestId("leadline-row").or(p.getByTestId("leadline-notice")).first()).toBeVisible();
return p;
}

4 changes: 3 additions & 1 deletion app/e2e/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import { type BrowserContext, expect, type Locator, type Page, test as base } fr
// attachment-chip, panel with data-panel, browser-pane with data-mode,
// chat-background, settings-nav-<id>, settings-<id>, theme-option with
// data-theme-id, plugin-row and market-plugin with data-plugin,
// market-error, zoom-hud), and the attributes the app already keys on
// market-error, zoom-hud, leadline with data-leadline and data-state, and
// its leadline-row, -detail, -notice, -box), and the attributes the app
// already keys on
// (data-tab, data-ws, data-group, data-tab-strip, data-pane-area).

export const live = process.env.BERTH_E2E_LIVE === "1";
Expand Down
Loading
Loading