Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions frontend/src/v2/__tests__/signalTokens.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ describe('D223 Signal tokens in v2.css', () => {
const asCssReadsIt = (text: string): string => text.replace(/\/\*[\s\S]*?\*\//g, ' ');

test('no comment in v2.css ends early', () => {
// The scan still sees a stray `*/`, and it keeps the declarations, so an
// empty result can't pass for a clean one.
expect(asCssReadsIt('/* quotes --a-*/--b-* here */ x: 1;')).toContain('*/');
expect(asCssReadsIt(css)).toContain('--v2-ink-2:');
expect(asCssReadsIt(css)).not.toContain('*/');
});

Expand Down
31 changes: 11 additions & 20 deletions frontend/src/v2/__tests__/v2-layout-invariants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ describe('v2 layout invariants (CSS rule presence)', () => {
// forcing a third column past a 390px viewport.
// The desktop declaration shares its rule with the buttons, so it is not
// eligible for ruleBody's exact-selector helper.
expect(v2).toMatch(/\.v2-activity__queue-actions,\n\.v2-activity__queue-row button,[\s\S]*?\{\n\s*display: flex;[\s\S]*?gap: 6px;/);
expect(v2).toMatch(/\.v2-activity__queue-actions,\n\.v2-activity__queue-row button \{\n\s*display: flex;[\s\S]*?gap: 6px;/);
expect(v2).toMatch(/@media \(max-width: 640px\)[\s\S]*?\.v2-activity__queue-actions \{ grid-column: 2; \}[\s\S]*?\.v2-activity__queue-actions \{ flex-wrap: wrap; \}/);
expect(v2).toMatch(/@media \(max-width: 640px\)[\s\S]*?\.v2-root \.v2-activity__queue-actions button \{ min-height: 44px; \}/);
// Every non-option card act is 32 tall at desktop, level with the options (ux-lead 67327):
Expand Down Expand Up @@ -1802,16 +1802,11 @@ describe('v2 layout invariants (CSS rule presence)', () => {
// The recap is a feature-wide page, but it is still reachable at 390px.
// The zero-min grid tracks are the load-bearing no-horizontal-overflow
// rule; jsdom cannot observe the scrollbar they prevent.
expect(ruleBody(v2, '.v2-activity__agent-grid'))
.toContain('repeat(2, minmax(0, 1fr))');
expect(ruleBody(v2, '.v2-activity__queue-row'))
.toContain('28px minmax(0, 1fr) auto');
expect(v2).toMatch(/@media \(max-width: 640px\)[\s\S]*?\.v2-activity__agent-grid \{[\s\S]*?grid-template-columns: minmax\(0, 1fr\)/);
expect(v2).toMatch(/@media \(max-width: 640px\)[\s\S]*?\.v2-activity__queue-row \{[\s\S]*?28px minmax\(0, 1fr\)/);
// Board rows do not inherit the queue icon column. At 390px that left
// only one character of a task title — an overflow-free but unusable
// primary identifier, which violates the craft baseline rule.
expect(v2).toMatch(/@media \(max-width: 640px\)[\s\S]*?\.v2-activity__board-row \{[\s\S]*?grid-template-columns: minmax\(0, 1fr\)/);
// The agent grid and board rows this also pinned are gone from the page,
// and their rules with them (TASK-758).
});

test('Activity queue actions distinguish an action from the thread handoff', () => {
Expand Down Expand Up @@ -2125,16 +2120,14 @@ describe('v2 layout invariants (CSS rule presence)', () => {
});

describe('Signal chat + inspector color contract (TASK-124)', () => {
// The composer's send and mode buttons left with the old composer (TASK-758).
const filledControls = [
'.v2-root button.v2-chat__send',
'.v2-root button.v2-chat__send--execute',
'.v2-root button.v2-chat__mode-option--active',
'.v2-root button.v2-first-run__hello',
'.v2-syscard__cta',
'.v2-root button.v2-approval__btn--approve',
];

test('all six ordinary filled controls use ink, never cobalt', () => {
test('every ordinary filled control uses ink, never cobalt', () => {
for (const selector of filledControls) {
const rule = selectorRuleBody(v2, selector);
expect(rule).toContain('var(--v2-ink)');
Expand Down Expand Up @@ -2260,7 +2253,7 @@ describe('v2 layout invariants (CSS rule presence)', () => {
expect(accentHoverDeclarations).toEqual([]);
});

test('the nine allowed cobalt marks remain explicit', () => {
test('the allowed cobalt marks remain explicit', () => {
for (const selector of [
'.v2-thread-card__dot',
'.v2-thread-card--addressed .v2-thread-card__count',
Expand All @@ -2270,7 +2263,6 @@ describe('v2 layout invariants (CSS rule presence)', () => {
'.v2-root button.v2-approval__result-link',
'.v2-root button.v2-chat__new-pod-copy',
'.v2-root .v2-chat__new-pod-error button',
'.v2-chat__composer-input-wrap:focus-within',
]) {
expect(selectorRuleBody(v2, selector)).toContain('var(--v2-accent');
}
Expand Down Expand Up @@ -2411,19 +2403,18 @@ describe('v2 layout invariants (CSS rule presence)', () => {
});

test('zh-CN: body copy takes line-height 1.6 and a 12px floor under :lang(zh) (TASK-055)', () => {
// Measured in a real browser: .v2-msg__content rendered Chinese at 1.55,
// the composer hint at 1.45/11px. CJK glyphs fill the em box, so Latin
// leading leaves no white between lines and 11px is below legibility.
// Measured in a real browser: .v2-msg__content rendered Chinese at 1.55.
// CJK glyphs fill the em box, so Latin leading leaves no white between
// lines and 11px is below legibility. (The old composer hint this also
// named is gone from the composer, and its rule with it: TASK-758.)
// Each selector's zh rule, wherever its surface file put it: the D223
// lifts split the shared :lang(zh) lists by surface.
const zhBlock = (sel: string): string => {
const at = v2.search(new RegExp(`\\.v2-root:lang\\(zh\\) ${sel.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?=[,\\s{])`));
expect(at).toBeGreaterThan(-1);
return v2.slice(at, v2.indexOf('}', at));
};
for (const sel of ['.v2-msg__content', '.v2-chat__composer-hint']) {
expect(zhBlock(sel)).toContain('line-height: 1.6');
}
expect(zhBlock('.v2-msg__content')).toContain('line-height: 1.6');
expect(ruleBody(v2, '.v2-root:lang(zh) .v2-workspace-inspector__empty')).toContain('line-height: 1.6');
for (const sel of ['.v2-workspace-inspector__actor', '.v2-workspace-inspector__task-meta']) {
expect(zhBlock(sel)).toContain('font-size: 12px');
Expand Down
26 changes: 2 additions & 24 deletions frontend/src/v2/__tests__/v2-type-floors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,18 +114,10 @@ const ALLOWLIST: string[] = [
'.v2-avatar', // 11.0px — no-mono-family
'.v2-avatar--md', // 11.0px — no-mono-family
'.v2-avatar--sm', // 10.0px — no-mono-family
'.v2-chat__avatars-more', // 11.0px — no-mono-family
'.v2-chat__composer-footer', // 11.0px — no-mono-family
'.v2-chat__composer-hint', // 11.0px — no-mono-family
'.v2-chat__composer-hint kbd', // 10.5px — mono-below-floor
'.v2-chat__mode-toggle--header .v2-chat__mode-option', // 11.5px — no-mono-family
// Split in two by the D223 chat lift (S3d): the status half moved to chat/chat-states.css.
'.v2-chat__new-pod-action-text', // 11.0px — no-mono-family
// Split in two by the D223 chat lift (S3d): the status half moved to
// chat/chat-states.css, and the action-text half left with TASK-758.
'.v2-chat__new-pod-status', // 11.0px — no-mono-family
'.v2-chat__new-pod-error', // 11.0px — no-mono-family
'.v2-chat__title-mark', // 11.0px — no-mono-family
'.v2-msg__file-icon', // 10.0px — no-mono-family
'.v2-msg__file-size', // 11.0px — no-mono-family
'.v2-msg__lead-badge', // 10.0px — mono-below-floor
'.v2-msg__reaction-count', // 11.0px — no-mono-family
'.v2-msg__reaction-error', // 11.0px — no-mono-family
Expand All @@ -144,19 +136,11 @@ const ALLOWLIST: string[] = [
// TASK-169 took `.v2-byo__stat-label` (11.0px, no family) to mono 500 11px
// with item 2, so its entry left this burn-down list rather than being
// updated in place.
'.v2-runtime-host', // 9.5px — no-mono-family
'.v2-runtime-mono', // 9.5px — no-mono-family
'.v2-runtime-mono__byo', // 8.5px — no-mono-family
'.v2-runtime-pill', // 11.0px — no-mono-family
'.v2-runtime-pill__mono', // 10.0px — no-mono-family
'.v2-runtime-row__byo', // 9.0px — no-mono-family
'.v2-runtime-row__label', // 10.5px — no-mono-family
// unassigned
// R05 took `.v2-connect__number` (11.0px, no family) to mono 500 11.5px
// with the Connect lift, so its entry left this list.
'.v2-approval__badge', // 10.5px — mono-below-floor
'.v2-approval__time', // 11.5px — no-mono-family
'.v2-filter-count', // 11.0px — no-mono-family
'.v2-invite-card__meta', // 11.0px — no-mono-family
'.v2-invite-link', // 11.0px — no-mono-family
'.v2-invite-manage__empty', // 11.0px — no-mono-family
Expand All @@ -167,14 +151,8 @@ const ALLOWLIST: string[] = [
'.v2-lang-switch__check', // 11.0px — no-mono-family
'.v2-mention-item__sub', // 11.0px — no-mono-family
'.v2-modal__error', // 11.0px — no-mono-family
'.v2-modal__hint--muted', // 11.0px — no-mono-family
'.v2-pods__create-error', // 11.0px — no-mono-family
'.v2-pods__discover-meta', // 11.0px — no-mono-family
'.v2-pods__item-icon', // 11.0px — no-mono-family
'.v2-pods__item-time', // 11.0px — no-mono-family
'.v2-pods__section-chevron', // 11.0px — no-mono-family
'.v2-pods__status', // 10.0px — no-mono-family
'.v2-role-chip', // 10.5px — no-mono-family
'.v2-root button.v2-admin-users__inline-copy', // 11.0px — no-mono-family
'.v2-root button.v2-invite-manage__action, .v2-invite-manage__action', // 11.0px — no-mono-family
'.v2-syscard__time', // 11.5px — no-mono-family
Expand Down
Loading
Loading