8b8e5214f9
Put the compact board trigger in the chat header, keep the sheet above the composer on iOS, and align onboarding messages with the intake card on the session column. Co-authored-by: Cursor <cursoragent@cursor.com>
41 lines
3.1 KiB
TypeScript
41 lines
3.1 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import test from "node:test";
|
|
|
|
const readProjectFile = (path: string) => readFileSync(new URL(`../${path}`, import.meta.url), "utf8");
|
|
const globalStyles = readProjectFile("src/app/globals.css");
|
|
const messageRowSource = readProjectFile("src/components/chat-message-row.tsx");
|
|
|
|
test("aligns the session transcript and composer to one readable column", () => {
|
|
assert.match(globalStyles, /--session-column-width:\s*760px/);
|
|
assert.match(globalStyles, /\.conversation:not\(\.is-empty\):not\(\.is-rectification\) \.message-list\s*\{[^}]*width:\s*min\(calc\(var\(--session-column-width\)/);
|
|
assert.match(globalStyles, /\.conversation:not\(\.is-empty\):not\(\.is-rectification\) \+ \.composer-wrap \.composer[^\{]*\{[^}]*width:\s*min\(var\(--session-column-width\),\s*100%\)/);
|
|
assert.match(globalStyles, /\.conversation:not\(\.is-empty\):not\(\.is-rectification\) \+ \.composer-wrap \.composer-footer[^\{]*\{[^}]*width:\s*min\(var\(--session-column-width\),\s*100%\)/);
|
|
});
|
|
|
|
test("keeps onboarding transcript and intake card on the same session column", () => {
|
|
const pageSource = readProjectFile("src/app/page.tsx");
|
|
assert.match(pageSource, /\$\{!profileComplete \? " is-onboarding" : ""\}/);
|
|
assert.match(globalStyles, /\.conversation\.is-onboarding \.welcome \{[\s\S]*width:\s*min\(calc\(var\(--session-column-width\) \+ \(var\(--session-column-gutter\) \* 2\)\), 100%\)/);
|
|
assert.match(globalStyles, /\.conversation\.is-onboarding\.is-empty \.welcome \{[\s\S]*width:\s*min\(var\(--session-column-width\), 100%\)/);
|
|
assert.match(globalStyles, /\.conversation\.is-onboarding \.onboarding-card,\s*\n\.conversation\.is-onboarding \.onboarding-card\.birth-time-transition-card \{[\s\S]*width:\s*100%;[\s\S]*max-width:\s*none/);
|
|
assert.match(globalStyles, /\.conversation\.is-onboarding-form \.welcome \{[\s\S]*padding:\s*var\(--space-6\) var\(--session-column-gutter\) var\(--space-8\)/);
|
|
});
|
|
|
|
test("keeps message motion restrained and honors reduced-motion preferences", () => {
|
|
assert.match(messageRowSource, /gsap\.matchMedia\(\)/);
|
|
assert.match(messageRowSource, /prefers-reduced-motion:\s*no-preference/);
|
|
assert.match(messageRowSource, /duration:\s*0\.18/);
|
|
assert.match(messageRowSource, /ease:\s*"cubic-bezier\(\.22,\s*1,\s*\.36,\s*1\)"/);
|
|
assert.match(messageRowSource, /clearProps:\s*"opacity,transform,visibility"/);
|
|
});
|
|
|
|
test("lets model controls fit their labels and keeps the stop action on-brand", () => {
|
|
assert.match(globalStyles, /\.model-selector-trigger\s*\{[^}]*width:\s*fit-content/);
|
|
assert.match(globalStyles, /\.model-selector-popup\s*\{[^}]*width:\s*max-content[^}]*min-width:\s*180px[^}]*max-width:\s*min\(420px,/);
|
|
assert.match(globalStyles, /\.model-selector-copy b\s*\{[^}]*overflow:\s*visible[^}]*white-space:\s*normal/);
|
|
assert.doesNotMatch(globalStyles, /\.model-selector-copy b\s*\{[^}]*text-overflow:\s*ellipsis/);
|
|
assert.match(globalStyles, /\.composer \.composer-stop\s*\{[^}]*background:\s*var\(--color-action\)/);
|
|
assert.match(globalStyles, /\.composer \.composer-stop:not\(:disabled\):hover\s*\{[^}]*background:\s*var\(--color-action-hover\)/);
|
|
});
|