import { createTestSpace, env } from "@commonfabric/integration"; import { ShellIntegration } from "@commonfabric/integration/shell-utils"; import { afterAll, beforeAll, describe, it } from "@std/testing/bdd"; import { join } from "@std/path"; import { type DID, Identity } from "@commonfabric/identity"; import { initializePiecesController, PiecesController, } from "./pieces-controller.ts"; import { clickCfButtonAndWaitForText, waitForDisabled, waitForText, } from "./cfc-browser-helpers.ts"; const { API_URL, FRONTEND_URL } = env; const testComponents = [ { name: "cf-checkbox-cell", file: "examples/cf-checkbox-cell.tsx" }, ]; /** * Opens a piece's view in the browser. Each case that reads a rendered piece * calls this for itself, so that the case runs alone and so that whatever its * page reports while loading belongs to that case. */ const openPiece = async ( shell: ShellIntegration, spaceDid: DID, pieceId: string, identity: Identity, ) => { await shell.goto({ frontendUrl: FRONTEND_URL, view: { spaceDid, pieceId, }, identity, }); }; testComponents.forEach(({ name, file }) => { describe(`${name} integration test`, () => { const shell = new ShellIntegration(); shell.bindLifecycle(); let spaceDid: DID; let pieceId: string; let identity: Identity; let cc: PiecesController; beforeAll(async () => { identity = await Identity.generate({ implementation: "noble" }); spaceDid = await createTestSpace(identity); cc = await initializePiecesController({ space: spaceDid, apiUrl: new URL(API_URL), identity: identity, }); const piece = await cc.create( await Deno.readTextFile( join( import.meta.dirname!, "..", file, ), ), { start: false }, ); pieceId = piece.id; }); afterAll(async () => { if (cc) await cc.dispose(); }); it(`should load the ${name} piece`, async () => { await openPiece(shell, spaceDid, pieceId, identity); await shell.page().waitForSelector("cf-checkbox", { strategy: "pierce" }); }); it("should show disabled content initially", async () => { await openPiece(shell, spaceDid, pieceId, identity); await waitForText( shell.page(), "#feature-status", "⚠ Feature is disabled", ); }); it("toggles the bound content on and back off when the checkbox is clicked", async () => { // The first cf-checkbox in the piece is bound to the cell that // #feature-status reflects; the click helper settles the view, clicks // the host element once, and waits for the bound text to update. One // case covers both clicks: the second click's expectation is the state // the first click leaves. The helper returns without clicking when the // text it waits for is already present, so each step asserts the state // it starts from, and the first step asserts it here. await openPiece(shell, spaceDid, pieceId, identity); await waitForText( shell.page(), "#feature-status", "⚠ Feature is disabled", ); await clickCfButtonAndWaitForText( shell.page(), "cf-checkbox", "#feature-status", "✓ Feature is enabled!", ); await clickCfButtonAndWaitForText( shell.page(), "cf-checkbox", "#feature-status", "⚠ Feature is disabled", ); }); }); }); // `waitForDisabled` resolves a control's disabled state from an inner