源码快照 @ 2026-09-02 (source-only, 剔除非源码素材)
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { expect, test } from "vitest";
|
||||
import { createAndSelectWorkspace, evalIn, waitFor } from "@openwork/behaviors";
|
||||
import { createVisualEvidence, screenshot, validate } from "@openwork/test-evidence";
|
||||
import { desktop } from "@openwork/hosts";
|
||||
|
||||
const e2eTestsEnabled = process.env.OPENWORK_EVAL_E2E_TESTS === "1";
|
||||
const title = e2eTestsEnabled
|
||||
? "Library shows readiness state tabs"
|
||||
: "Library state tabs skipped: set OPENWORK_EVAL_E2E_TESTS=1 to opt in";
|
||||
const repoRoot = fileURLToPath(new URL("../..", import.meta.url));
|
||||
|
||||
test.skipIf(!e2eTestsEnabled)(title, async () => {
|
||||
await using app = await desktop({ name: "library-state-tabs" });
|
||||
await createAndSelectWorkspace(app, { path: repoRoot });
|
||||
await evalIn(app, `(() => {
|
||||
window.location.hash = "#/settings/general";
|
||||
return true;
|
||||
})()`);
|
||||
await waitFor(
|
||||
app,
|
||||
`[...document.querySelectorAll("button")].some((button) => button.textContent?.trim() === "Library")`,
|
||||
{ timeoutMs: 60_000, label: "Library settings navigation entry" },
|
||||
);
|
||||
const openedLibrary = await evalIn(app, `(() => {
|
||||
const button = [...document.querySelectorAll("button")]
|
||||
.find((entry) => entry.textContent?.trim() === "Library");
|
||||
if (!(button instanceof HTMLElement)) return false;
|
||||
button.click();
|
||||
return true;
|
||||
})()`);
|
||||
expect(openedLibrary).toBe(true);
|
||||
await waitFor(
|
||||
app,
|
||||
`window.location.hash.includes("/settings/extensions")
|
||||
&& [...document.querySelectorAll("h1, h2")].some((heading) => heading.textContent?.trim() === "Library")
|
||||
&& Boolean(document.querySelector('[role="tablist"][aria-label="Library state"]'))
|
||||
&& [...document.querySelectorAll('[role="tab"]')].some((tab) => tab.textContent?.trim() === "All")
|
||||
&& [...document.querySelectorAll('[role="tab"]')].some((tab) => (tab.textContent ?? "").includes("Ready to use"))`,
|
||||
{ timeoutMs: 60_000, label: "Library title and state tabs" },
|
||||
);
|
||||
|
||||
const headerHasConnectedCount = await evalIn(app, `(() => {
|
||||
const description = [...document.querySelectorAll("p")]
|
||||
.find((entry) => entry.textContent?.includes("Skills, connections, and tools your agent can use."));
|
||||
return /apps? connected/i.test(description?.parentElement?.textContent ?? "");
|
||||
})()`);
|
||||
expect(headerHasConnectedCount).toBe(false);
|
||||
const descriptionRenderedOnce = await evalIn(
|
||||
app,
|
||||
`document.body.innerText.split("Skills, connections, and tools your agent can use.").length - 1`,
|
||||
);
|
||||
expect(descriptionRenderedOnce).toBe(1);
|
||||
|
||||
const clickedReady = await evalIn(app, `(() => {
|
||||
const tab = [...document.querySelectorAll('[role="tab"]')]
|
||||
.find((entry) => (entry.textContent ?? "").includes("Ready to use"));
|
||||
if (!(tab instanceof HTMLElement)) return false;
|
||||
tab.click();
|
||||
return true;
|
||||
})()`);
|
||||
expect(clickedReady).toBe(true);
|
||||
await waitFor(
|
||||
app,
|
||||
`window.location.hash.endsWith("/extensions/ready")
|
||||
&& document.querySelectorAll("[data-inventory-group]").length > 0
|
||||
&& [...document.querySelectorAll("[data-inventory-group]")]
|
||||
.every((row) => row.getAttribute("data-inventory-group") === "ready")`,
|
||||
{ timeoutMs: 30_000, label: "Ready Library deep link and rows" },
|
||||
);
|
||||
|
||||
const hasNeedsSignin = await evalIn(
|
||||
app,
|
||||
`[...document.querySelectorAll('[role="tab"]')].some((tab) => (tab.textContent ?? "").includes("Needs your sign-in"))`,
|
||||
);
|
||||
if (hasNeedsSignin === true) {
|
||||
const clicked = await evalIn(app, `(() => {
|
||||
const tab = [...document.querySelectorAll('[role="tab"]')]
|
||||
.find((entry) => (entry.textContent ?? "").includes("Needs your sign-in"));
|
||||
if (!(tab instanceof HTMLElement)) return false;
|
||||
tab.click();
|
||||
return true;
|
||||
})()`);
|
||||
expect(clicked).toBe(true);
|
||||
await waitFor(
|
||||
app,
|
||||
`window.location.hash.includes("/extensions/needs-sign-in")
|
||||
&& document.querySelectorAll("[data-inventory-group]").length > 0
|
||||
&& [...document.querySelectorAll("[data-inventory-group]")]
|
||||
.every((row) => row.getAttribute("data-inventory-group") === "needs_signin")`,
|
||||
{ timeoutMs: 30_000, label: "only needs-signin Library rows" },
|
||||
);
|
||||
}
|
||||
|
||||
await using visualEvidence = createVisualEvidence("library-state-tabs");
|
||||
const shot = await screenshot(app);
|
||||
const seen = await validate(shot, ["A Library settings page shows state tabs with counts"]);
|
||||
expect(seen.ok, seen.why).toBe(true);
|
||||
await visualEvidence.recordScreenshot(shot, seen);
|
||||
});
|
||||
Reference in New Issue
Block a user