Files
WRNexusJS/packages/captcha/test/component.test.ts
T
ClintchizandClaude Opus 5 06433e4ac4
Quality / quality (ubuntu-latest) (push) Failing after 10m1s
Quality / quality (windows-latest) (push) Canceled after 0s
chore(release): publish db 0.8.21, cli 0.8.65 and seven in-flight packages
Carries the rollback refusal in db and the matching CLI message, together
with the auth, captcha, csr, dev-server, dev-toolbar, ui and validation
changes that were already in the working tree, since publishing stages
from it and those files would otherwise ship without being recorded here.

  @wrnexus/auth        0.8.28 -> 0.8.29
  @wrnexus/captcha     0.8.15 -> 0.8.16
  @wrnexus/cli         0.8.64 -> 0.8.65
  @wrnexus/csr         0.8.37 -> 0.8.38
  @wrnexus/db          0.8.20 -> 0.8.21
  @wrnexus/dev-server  0.8.60 -> 0.8.61
  @wrnexus/dev-toolbar 0.8.17 -> 0.8.18
  @wrnexus/ui          0.8.75 -> 0.8.76
  @wrnexus/validation  0.8.12 -> 0.8.13

Also declares Event among the browser globals captcha's client asset
already lists, which was the last lint failure, and reformats four files.
typecheck, lint, 1998 tests and format:check all pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 10:17:09 +05:30

81 lines
2.9 KiB
TypeScript

import { expect, test } from "bun:test";
import { readFile } from "node:fs/promises";
import { join } from "node:path";
import { parse } from "@wrnexus/syntax";
const componentPath = join(import.meta.dir, "../components/Captcha.wrn");
const clientPath = join(import.meta.dir, "../assets/client/captcha.js");
test("Captcha.wrn parses and exposes the full public contract", async () => {
const source = await readFile(componentPath, "utf8");
const ast = parse(source);
expect(ast.kind).toBe("component");
expect(ast.name).toBe("Captcha");
for (const prop of [
"provider",
"siteKey",
"type",
"action",
"presentation",
"difficulty",
"disturbance",
"imageStyle",
"allowedStyles",
"excludedStyles",
"randomizeStyle",
"size",
"color",
"class",
"showListen",
"resetOnError",
]) {
expect(source).toContain(`${prop} =`);
}
for (const event of [
"ready",
"challenge",
"input",
"verify",
"success",
"failure",
"expired",
"refresh",
"audioStart",
"audioEnd",
"error",
]) {
expect(source).toContain(`@event ${event} = function`);
}
expect(source).toContain("data-captcha-disturbance='{disturbance}'");
expect(source).toContain("data-captcha-image-style='{imageStyle}'");
expect(source).toContain("data-captcha-allowed-styles='{allowedStyles}'");
expect(source).toContain("data-captcha-excluded-styles='{excludedStyles}'");
expect(source).toContain("data-captcha-randomize-style='{randomizeStyle}'");
expect(source).toContain("data-captcha-show-listen='{showListen}'");
expect(source).toContain("data-captcha-reset-on-error='{resetOnError}'");
expect(source).toContain("data-captcha-not-robot-button");
expect(source).toContain("data-[captcha-size=compact]");
expect(source).toContain("data-[captcha-size=compact]:max-w-xs");
expect(source).toContain("group-data-[captcha-size=compact]/captcha:max-h-24");
expect(source).toContain("group-data-[captcha-size=compact]/captcha:h-8");
expect(source).toContain("group-data-[captcha-size=compact]/captcha:hidden");
expect(source).toContain("[data-captcha-footer]");
expect(source).toContain("display: contents");
expect(source).toContain("order: -1");
expect(source).toContain("data-[captcha-size=big]");
expect(source).toContain("{...attrs}");
expect(source).toContain("--wrn-");
expect(source).not.toMatch(/=\{/);
expect(source).toContain('data-wrnexus-runtime="captcha"');
expect(source).not.toContain("<script");
expect(source).not.toContain("captcha.js");
expect(source).not.toContain("lifecycle {");
});
test("CAPTCHA response tokens remain visible to enhanced form serializers", async () => {
const source = await readFile(clientPath, "utf8");
expect(source).toContain('input.setAttribute("value", state.responseToken)');
expect(source).toContain('new Event("input", { bubbles: true })');
expect(source).toContain('new Event("change", { bubbles: true })');
});