test: element backstops
vitest + happy-dom tests of the UI-SPEC backstops: E1 status thresholds (29/30 characters, 580/581 px; 119/120 and 920/921 for descriptions) with a mocked measureText and the counter's wrap contract; the E2 grammar over every directive combination, the emitted values and the stacking contract with unclipped en and pl labels; the E3 effective title, word-boundary truncation and keyphrase stem matching; each E4 lint rule and a clean file; E6 apply gating. happy-dom has no layout engine, so the narrow-width rows check the stylesheet's layout contract.
This commit is contained in:
27
tests/elements/css.ts
Normal file
27
tests/elements/css.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/// <reference types="node" />
|
||||
import { readFileSync } from 'node:fs'
|
||||
|
||||
// The element stylesheet for layout backstops. Vitest stubs CSS imports, so
|
||||
// the file is read from disk (vitest runs from the plugin root). happy-dom
|
||||
// has no layout engine: the backstops check the layout contract instead.
|
||||
|
||||
export const css = readFileSync(`${process.cwd()}/assets/src/elements/styles.css`, 'utf8')
|
||||
|
||||
/** The declarations of every rule (outside @media) whose selector list names selector. */
|
||||
export function rule(selector: string, sheet = css): Record<string, string> {
|
||||
const out: Record<string, string> = {}
|
||||
const body = sheet.replace(/\/\*[\s\S]*?\*\//g, '').replace(/@media[^{]*\{(?:[^{}]*\{[^{}]*\})*[^{}]*\}/g, '')
|
||||
for (const match of body.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
|
||||
const selectors = match[1].split(',').map((s) => s.trim())
|
||||
if (!selectors.includes(selector)) {
|
||||
continue
|
||||
}
|
||||
for (const decl of match[2].split(';')) {
|
||||
const colon = decl.indexOf(':')
|
||||
if (colon > 0) {
|
||||
out[decl.slice(0, colon).trim()] = decl.slice(colon + 1).trim()
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user