import { createRawSnippet } from "svelte";
import { describe, expect, it } from "vitest";
import PageHeading from "../src/composites/PageHeading.svelte";
import { pageHeading } from "../src/composites/page-heading.variants";
import HeadingContractFailures from "./fixtures/HeadingContractFailures.svelte";
import TitlingSurfacesConsumer from "./fixtures/TitlingSurfacesConsumer.svelte";
import { expectLayoutReadiness } from "./layout-readiness";
import { classes, classesOf, render, rendered } from "./mount";
const actions = createRawSnippet(() => ({
render: () => '',
}));
describe("the deliberately failing page heading fixture", () => {
it("breaks the document outline by starting the page at h2", () => {
const root = render(HeadingContractFailures);
const headings = [...root.querySelectorAll("h1, h2, h3, h4, h5, h6")];
expect(headings.map((heading) => heading.tagName)).toEqual(["H2", "H3"]);
expect(root.querySelector("h1")).toBeNull();
});
});
describe("PageHeading", () => {
it("owns the page title as exactly one h1 and keeps subordinate content caller-owned", () => {
const element = rendered(
render(PageHeading, {
title: "Deployments",
description: "Manage releases across environments.",
actions,
}),
);
expect(element.querySelectorAll("h1")).toHaveLength(1);
expect(element.querySelector("h1")?.textContent).toBe("Deployments");
expect(element.querySelector("h2, h3, h4, h5, h6")).toBeNull();
expect(element.querySelector("p")?.textContent).toBe("Manage releases across environments.");
});
it("preserves native action focus order", () => {
const secondary = createRawSnippet(() => ({
render: () =>
'Help',
}));
const element = rendered(render(PageHeading, { title: "Deployments", actions: secondary }));
const controls = [...element.querySelectorAll("a, button")];
expect(controls.map((control) => control.textContent)).toEqual(["Help", "Create"]);
controls[0]!.focus();
expect(document.activeElement).toBe(controls[0]);
controls[1]!.focus();
expect(document.activeElement).toBe(controls[1]);
});
it("routes spacing through Density and inherits every nested appearance axis", () => {
const root = render(TitlingSurfacesConsumer);
const element = root.querySelector("[data-page-heading]")!;
expect(classes(element)).toEqual(classesOf(pageHeading().root()));
expect(classes(element).has("gap-[var(--reddb-spatial-gap-lg)]")).toBe(true);
expect(element.closest('[data-theme="base"][data-color-scheme="dark"][data-density="compact"]'))
.not.toBeNull();
expect(element.hasAttribute("data-theme")).toBe(false);
expect(element.hasAttribute("data-color-scheme")).toBe(false);
expect(element.hasAttribute("data-density")).toBe(false);
});
it("wraps actions below the title before squeezing the identity column", () => {
const element = rendered(render(PageHeading, { title: "Deployments", description: "Every rollout" }));
const identity = element.querySelector("h1")!.parentElement!;
expect(classes(element).has("flex-wrap")).toBe(true);
expect(classes(identity).has("flex-[1_1_20rem]")).toBe(true);
expect(classes(identity).has("flex-1")).toBe(false);
});
it("inherits the page ground while retaining its structural boundary", () => {
const element = rendered(render(PageHeading, { title: "Deployments" }));
const contract = classes(element);
expect(contract.has("bg-transparent")).toBe(true);
expect(contract.has("bg-elevation-sunken-surface")).toBe(false);
expect(contract.has("border-b")).toBe(true);
expect(contract.has("border-elevation-sunken-border")).toBe(true);
});
it("ships showcase, consumer, distributed export, and readiness evidence", () => {
expectLayoutReadiness("page-heading", "PageHeading");
});
});