Files
sm-seo-plugin/tests/elements/css.ts
Jakub Zych dcfbdc05ed 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.
2026-10-27 13:26:59 +01:00

28 lines
1.1 KiB
TypeScript

/// <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
}