test(ai-toolbar): split coverage and add fallback failure cases
This commit is contained in:
101
tests/ai-toolbar-layout.test.ts
Normal file
101
tests/ai-toolbar-layout.test.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import {
|
||||
getMatchingClassTokens,
|
||||
registerAIToolbarTestHooks,
|
||||
renderToolbarMarkup,
|
||||
} from "./helpers/ai-toolbar-test-helpers";
|
||||
|
||||
registerAIToolbarTestHooks();
|
||||
|
||||
describe("AI toolbar layout contracts", () => {
|
||||
test("desktop composer uses a dedicated multi-column branch while mobile stays single-column", async () => {
|
||||
const desktopMarkup = await renderToolbarMarkup();
|
||||
const mobileMarkup = await renderToolbarMarkup({}, { isMobile: true });
|
||||
const desktopLayoutTokens = getMatchingClassTokens(
|
||||
desktopMarkup,
|
||||
(tokens) =>
|
||||
tokens.includes("grid") &&
|
||||
tokens.some((token) => token.startsWith("grid-cols-[minmax(0,0.7fr)")),
|
||||
);
|
||||
const mobileLayoutTokens = getMatchingClassTokens(
|
||||
mobileMarkup,
|
||||
(tokens) => tokens.includes("grid") && tokens.includes("gap-3"),
|
||||
);
|
||||
|
||||
expect(desktopLayoutTokens).toHaveLength(1);
|
||||
expect(desktopMarkup).toContain("Keyboard shortcuts");
|
||||
expect(desktopMarkup).toContain("Attachments");
|
||||
expect(mobileLayoutTokens).toHaveLength(1);
|
||||
expect(mobileMarkup).not.toContain("Keyboard shortcuts");
|
||||
expect(
|
||||
mobileLayoutTokens[0].some((token) => token.startsWith("grid-cols-")),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test("example prompts render as a masonry-style cluster below the textarea", async () => {
|
||||
const markup = await renderToolbarMarkup();
|
||||
const masonryColumns = getMatchingClassTokens(
|
||||
markup,
|
||||
(tokens) => tokens.some((token) => token.startsWith("columns-")),
|
||||
);
|
||||
const masonryWrappers = getMatchingClassTokens(
|
||||
markup,
|
||||
(tokens) => tokens.includes("break-inside-avoid"),
|
||||
);
|
||||
const promptButtons = getMatchingClassTokens(
|
||||
markup,
|
||||
(tokens) =>
|
||||
tokens.includes("justify-start") &&
|
||||
tokens.includes("text-left") &&
|
||||
tokens.includes("whitespace-normal"),
|
||||
);
|
||||
|
||||
expect(markup).toContain("Try:");
|
||||
expect(markup).toContain(
|
||||
"Lunch with Maya next Thursday at 12:30pm at Toma, remind me 30 minutes before.",
|
||||
);
|
||||
expect(markup).toContain(
|
||||
"Project sync tomorrow from 9am to 10am on Google Meet with a weekly repeat.",
|
||||
);
|
||||
expect(markup).toContain(
|
||||
"Dentist appointment on May 14 at 3pm at Smile Studio, add confirmation #A4821.",
|
||||
);
|
||||
expect(masonryColumns).toHaveLength(1);
|
||||
expect(masonryColumns[0]).toEqual(
|
||||
expect.arrayContaining(["columns-2", "gap-2"]),
|
||||
);
|
||||
expect(masonryWrappers).toHaveLength(3);
|
||||
expect(promptButtons).toHaveLength(3);
|
||||
});
|
||||
|
||||
test("attachments render as a separate surfaced panel with count badge, picker, and empty state", async () => {
|
||||
const markup = await renderToolbarMarkup();
|
||||
|
||||
expect(markup).toContain("Attachments");
|
||||
expect(markup).toContain("0 files");
|
||||
expect(markup).toContain("Attach images");
|
||||
expect(markup).toContain(
|
||||
"Drop or paste images here to pair them with the prompt.",
|
||||
);
|
||||
});
|
||||
|
||||
test("attachment previews render in a stacked grid instead of a multi-column strip", async () => {
|
||||
const markup = await renderToolbarMarkup({
|
||||
imagePreviews: ["blob:first", "blob:second"],
|
||||
});
|
||||
const previewGridTokens = getMatchingClassTokens(
|
||||
markup,
|
||||
(tokens) => tokens.includes("grid") && tokens.includes("gap-2"),
|
||||
);
|
||||
const multiColumnPreviewPattern =
|
||||
/(?:^|\s)(?:[a-z]+:)*(?:grid-cols-(?:\[[^\]]+\]|\S+)|grid-flow-col|auto-cols-(?:\[[^\]]+\]|\S+)|columns-(?:\[[^\]]+\]|\S+)|overflow-x-auto|flex-row)/;
|
||||
|
||||
expect(markup).toContain("Attached image 1");
|
||||
expect(markup).toContain("Attached image 2");
|
||||
expect(
|
||||
previewGridTokens.some(
|
||||
(tokens) => !tokens.join(" ").match(multiColumnPreviewPattern),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user