diff --git a/package.json b/package.json index d4312893..a00504d9 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "slashed", + "type": "module", "version": "0.5.0-beta5", "description": "CSS framework", "style": "dist/slashed.full.css", diff --git a/playwright.config.js b/playwright.config.js index df3c64a1..4384700d 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -1,11 +1,11 @@ -const { defineConfig, devices } = require('@playwright/test'); +import { defineConfig, devices } from '@playwright/test'; // Token + a11y regression suite. No dev server — fixtures load the built // bundle / demo over file://. The framework leans on bleeding-edge CSS // (oklch relative colour, @property inherits, light-dark()), all within the // documented support floor for Chromium, Firefox, and WebKit — so the suite // runs on all three. -module.exports = defineConfig({ +export default defineConfig({ testDir: './tests', fullyParallel: true, reporter: 'list', diff --git a/plugins/SLASHED-for-WP/dist/slashed.essential.css b/plugins/SLASHED-for-WP/dist/slashed.essential.css index 8dc5a991..02c77162 100644 --- a/plugins/SLASHED-for-WP/dist/slashed.essential.css +++ b/plugins/SLASHED-for-WP/dist/slashed.essential.css @@ -3483,12 +3483,12 @@ neutralisation in accessibility.css if a consumer accidentally writes them outside the gate. - Browser support — animation-timeline is shipping in Chrome 115+ - and Firefox 145+ (expected Nov 2026, not yet released as of May 2026). - Safari does not yet support it - (tracked at WebKit bug 264057); on those engines the @supports - block below is skipped, so the rule falls back to a one-shot - time-driven animation playing once at --sf-duration-slow. + Browser support — animation-timeline ships in Chrome/Edge 115+. + Firefox keeps it behind a flag (the scroll-driven-animations + preference) and Safari has not shipped it (tracked at WebKit + bug 264057); on those engines the @supports block below is + skipped, so the rule falls back to a one-shot time-driven + animation playing once at --sf-duration-slow. animation-duration is set unconditionally because without it a non-supporting engine would default to 0s and snap to the end state instantly — there'd be no visible entrance at all. diff --git a/plugins/SLASHED-for-WP/dist/slashed.full.css b/plugins/SLASHED-for-WP/dist/slashed.full.css index a794e781..8fd1f4e2 100644 --- a/plugins/SLASHED-for-WP/dist/slashed.full.css +++ b/plugins/SLASHED-for-WP/dist/slashed.full.css @@ -3483,12 +3483,12 @@ neutralisation in accessibility.css if a consumer accidentally writes them outside the gate. - Browser support — animation-timeline is shipping in Chrome 115+ - and Firefox 145+ (expected Nov 2026, not yet released as of May 2026). - Safari does not yet support it - (tracked at WebKit bug 264057); on those engines the @supports - block below is skipped, so the rule falls back to a one-shot - time-driven animation playing once at --sf-duration-slow. + Browser support — animation-timeline ships in Chrome/Edge 115+. + Firefox keeps it behind a flag (the scroll-driven-animations + preference) and Safari has not shipped it (tracked at WebKit + bug 264057); on those engines the @supports block below is + skipped, so the rule falls back to a one-shot time-driven + animation playing once at --sf-duration-slow. animation-duration is set unconditionally because without it a non-supporting engine would default to 0s and snap to the end state instantly — there'd be no visible entrance at all. diff --git a/plugins/SLASHED-for-WP/dist/slashed.optimal.css b/plugins/SLASHED-for-WP/dist/slashed.optimal.css index 20c5bd93..c5f84ee0 100644 --- a/plugins/SLASHED-for-WP/dist/slashed.optimal.css +++ b/plugins/SLASHED-for-WP/dist/slashed.optimal.css @@ -3483,12 +3483,12 @@ neutralisation in accessibility.css if a consumer accidentally writes them outside the gate. - Browser support — animation-timeline is shipping in Chrome 115+ - and Firefox 145+ (expected Nov 2026, not yet released as of May 2026). - Safari does not yet support it - (tracked at WebKit bug 264057); on those engines the @supports - block below is skipped, so the rule falls back to a one-shot - time-driven animation playing once at --sf-duration-slow. + Browser support — animation-timeline ships in Chrome/Edge 115+. + Firefox keeps it behind a flag (the scroll-driven-animations + preference) and Safari has not shipped it (tracked at WebKit + bug 264057); on those engines the @supports block below is + skipped, so the rule falls back to a one-shot time-driven + animation playing once at --sf-duration-slow. animation-duration is set unconditionally because without it a non-supporting engine would default to 0s and snap to the end state instantly — there'd be no visible entrance at all. diff --git a/scripts/audit.js b/scripts/audit.js index 25ba121e..9584810c 100644 --- a/scripts/audit.js +++ b/scripts/audit.js @@ -24,14 +24,11 @@ * by the framework itself (warnings only) */ -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import { TOKEN_FILES, CLASS_FILES } from './registry-sources.js'; -const fs = require('node:fs'); -const path = require('node:path'); - -const ROOT = path.resolve(__dirname, '..'); - -const { TOKEN_FILES, CLASS_FILES } = require('./registry-sources'); +const ROOT = path.resolve(import.meta.dirname, '..'); // All framework source files — token files + class files + everything else // in core/ and optional/ — used for the unused-token cross-reference. diff --git a/scripts/bundle.js b/scripts/bundle.js index d5f34c64..bb4e54c6 100644 --- a/scripts/bundle.js +++ b/scripts/bundle.js @@ -1,16 +1,18 @@ #!/usr/bin/env node -const fs = require('fs'); -const path = require('path'); -const zlib = require('zlib'); +import fs from 'node:fs'; +import path from 'node:path'; +import zlib from 'node:zlib'; +import { createRequire } from 'node:module'; -const ROOT = path.resolve(__dirname, '..'); +const _require = createRequire(import.meta.url); +const ROOT = path.resolve(import.meta.dirname, '..'); const CONFIG_PATH = path.join(ROOT, 'bundle.config.json'); // lightningcss is a maintainer-only dev dependency. If it's missing (e.g. a // consumer cloned without dev deps), skip minification rather than fail. let lightningcss = null; -try { lightningcss = require('lightningcss'); } catch { /* optional */ } +try { lightningcss = _require('lightningcss'); } catch { /* optional */ } function sizeReport(buf) { const raw = buf.length; diff --git a/scripts/check-artifacts.js b/scripts/check-artifacts.js index c531dda2..2d1f0ebf 100644 --- a/scripts/check-artifacts.js +++ b/scripts/check-artifacts.js @@ -11,13 +11,11 @@ * To register a new build artifact, add an entry to scripts/artifacts.json. */ -'use strict'; +import { execSync, execFileSync } from 'node:child_process'; +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; -const { execSync, execFileSync } = require('child_process'); -const { readFileSync } = require('fs'); -const { resolve } = require('path'); - -const root = resolve(__dirname, '..'); +const root = resolve(import.meta.dirname, '..'); const artifacts = JSON.parse(readFileSync(resolve(root, 'scripts/artifacts.json'), 'utf8')); const mode = process.argv.includes('--check') ? 'check' : 'fix'; diff --git a/scripts/check-cheatsheet.js b/scripts/check-cheatsheet.js index 9b827404..824cfa09 100644 --- a/scripts/check-cheatsheet.js +++ b/scripts/check-cheatsheet.js @@ -23,12 +23,10 @@ * Usage: node scripts/check-cheatsheet.js */ -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; -const fs = require('node:fs'); -const path = require('node:path'); - -const ROOT = path.resolve(__dirname, '..'); +const ROOT = path.resolve(import.meta.dirname, '..'); const INV = path.join(ROOT, 'plugins', 'SLASHED-for-WP', 'integrations', 'bricks', 'data', 'inventory.json'); const SHEET = path.join(ROOT, 'plugins', 'SLASHED-for-WP', 'integrations', 'bricks', 'admin-app', 'src', 'lib', 'cheatsheet-data.js'); diff --git a/scripts/gen-bricks-inventory.js b/scripts/gen-bricks-inventory.js index bad9ea77..e723b2dd 100644 --- a/scripts/gen-bricks-inventory.js +++ b/scripts/gen-bricks-inventory.js @@ -15,16 +15,13 @@ * node scripts/gen-bricks-inventory.js */ -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import { TOKEN_FILES, CLASS_FILES } from './registry-sources.js'; -const fs = require('node:fs'); -const path = require('node:path'); - -const ROOT = path.resolve(__dirname, '..'); +const ROOT = path.resolve(import.meta.dirname, '..'); const OUT = path.join(ROOT, 'plugins', 'SLASHED-for-WP', 'integrations', 'bricks', 'data', 'inventory.json'); -const { TOKEN_FILES, CLASS_FILES } = require('./registry-sources'); - function stripComments(css) { return css.replace(/\/\*[\s\S]*?\*\//g, ''); } diff --git a/scripts/gen-class-hints.js b/scripts/gen-class-hints.js index 659000c7..31bc4dec 100644 --- a/scripts/gen-class-hints.js +++ b/scripts/gen-class-hints.js @@ -16,12 +16,10 @@ * node scripts/gen-class-hints.js --check — exit 1 if file is stale */ -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; -const fs = require('node:fs'); -const path = require('node:path'); - -const ROOT = path.resolve(__dirname, '..'); +const ROOT = path.resolve(import.meta.dirname, '..'); const OUT = path.join(ROOT, 'plugins', 'SLASHED-for-WP', 'data', 'classes-hints.json'); // Files to parse, in generation order. Must match FILE_META in gen-class-reference.js. diff --git a/scripts/gen-class-reference.js b/scripts/gen-class-reference.js index 917012c1..7074cd04 100644 --- a/scripts/gen-class-reference.js +++ b/scripts/gen-class-reference.js @@ -6,14 +6,11 @@ * The reference is derived from source so it never drifts. */ -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import { CLASS_FILES } from './registry-sources.js'; -const fs = require('node:fs'); -const path = require('node:path'); - -const ROOT = path.resolve(__dirname, '..'); - -const { CLASS_FILES } = require('./registry-sources'); +const ROOT = path.resolve(import.meta.dirname, '..'); const FILE_META = { 'core/layout.css': { title: 'Layout primitives', prefix: 'sf-' }, diff --git a/scripts/gen-token-reference.js b/scripts/gen-token-reference.js index e6239b84..de71a822 100644 --- a/scripts/gen-token-reference.js +++ b/scripts/gen-token-reference.js @@ -2,14 +2,11 @@ /* Generates docs/tokens.md from the token source files. Run: npm run docs:tokens The reference is derived from source so it never drifts. */ -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import { TOKEN_FILES } from './registry-sources.js'; -const fs = require('fs'); -const path = require('path'); - -const ROOT = path.resolve(__dirname, '..'); - -const { TOKEN_FILES } = require('./registry-sources'); +const ROOT = path.resolve(import.meta.dirname, '..'); const FILE_TITLES = { 'core/tokens.css': 'Core tokens', diff --git a/scripts/registry-sources.js b/scripts/registry-sources.js index 676fc076..0eae4b05 100644 --- a/scripts/registry-sources.js +++ b/scripts/registry-sources.js @@ -1,5 +1,3 @@ -'use strict'; - /** * Canonical source-file lists for the SLASHED registry. * @@ -34,4 +32,4 @@ const CLASS_FILES = [ 'optional/theme-example.css', ]; -module.exports = { TOKEN_FILES, CLASS_FILES }; +export { TOKEN_FILES, CLASS_FILES }; diff --git a/scripts/version-sync.js b/scripts/version-sync.js index 45b5fb05..54561e69 100644 --- a/scripts/version-sync.js +++ b/scripts/version-sync.js @@ -4,12 +4,10 @@ // Run after every version bump: npm run version-sync // Wired into .release-it.json hooks so it executes automatically during releases. -'use strict'; +import fs from 'node:fs'; +import path from 'node:path'; -const fs = require('fs'); -const path = require('path'); - -const ROOT = path.resolve(__dirname, '..'); +const ROOT = path.resolve(import.meta.dirname, '..'); function readFile(rel) { return fs.readFileSync(path.join(ROOT, rel), 'utf8'); diff --git a/scripts/zip-plugin.js b/scripts/zip-plugin.js index 9853b1ce..970242f4 100644 --- a/scripts/zip-plugin.js +++ b/scripts/zip-plugin.js @@ -21,11 +21,12 @@ * output already lives in assets/. */ -const fs = require('fs'); -const path = require('path'); -const { execSync, execFileSync } = require('child_process'); +import fs from 'node:fs'; +import path from 'node:path'; +import zlib from 'node:zlib'; +import { execSync, execFileSync } from 'node:child_process'; -const ROOT = path.resolve(__dirname, '..'); +const ROOT = path.resolve(import.meta.dirname, '..'); const OUTPUT = path.join(ROOT, 'dist', 'slashed.zip'); const STAGE = path.join(ROOT, '.tmp-plugin-stage'); const STAGE_PLUGIN = path.join(STAGE, 'slashed'); @@ -102,7 +103,6 @@ function main() { * Handles files and directories with DEFLATE compression. */ function createZipFromDir(sourceDir, outputPath, rootName) { - const zlib = require('zlib'); const files = []; function walk(dir, rel) { diff --git a/tests/a11y-patterns.spec.js b/tests/a11y-patterns.spec.js index 44ce63d7..47e53ae3 100644 --- a/tests/a11y-patterns.spec.js +++ b/tests/a11y-patterns.spec.js @@ -3,8 +3,8 @@ // .sr-only, .sr-only-focusable, .skip-link, // .sf-focus-parent, .sf-clickable-parent, // touch-target token, forced-colors, disabled cursor. -const { test, expect } = require('@playwright/test'); -const path = require('path'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; const BUNDLE = path.join(process.cwd(), 'dist', 'slashed.optimal.css'); diff --git a/tests/a11y.spec.js b/tests/a11y.spec.js index ece9461c..17c596c0 100644 --- a/tests/a11y.spec.js +++ b/tests/a11y.spec.js @@ -1,16 +1,16 @@ // @ts-check // Automated accessibility audit of the demo page with axe-core. // Catches WCAG regressions (contrast, ARIA, landmarks) in both themes. -const { test, expect } = require('@playwright/test'); -const { AxeBuilder } = require('@axe-core/playwright'); -const path = require('path'); -const { pathToFileURL } = require('url'); +import { test, expect } from '@playwright/test'; +import { AxeBuilder } from '@axe-core/playwright'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; // A focused fixture exercising real framework usage with correct semantics // (labelled forms, heading order, landmarks). The kitchen-sink demo.html // intentionally contains low-contrast helper text and unlabelled control // samples, so it is not a fair axe target; this fixture is. -const DEMO_URL = pathToFileURL(path.resolve(__dirname, 'a11y-fixture.html')).href; +const DEMO_URL = pathToFileURL(path.resolve(import.meta.dirname, 'a11y-fixture.html')).href; for (const theme of ['light', 'dark']) { test(`axe: no WCAG A/AA violations (${theme})`, async ({ page, browserName }) => { diff --git a/tests/auto-color.spec.js b/tests/auto-color.spec.js index a1d25f13..0a36a478 100644 --- a/tests/auto-color.spec.js +++ b/tests/auto-color.spec.js @@ -15,11 +15,11 @@ // // fixture.html loads dist/slashed.full.css, so both the `a:link` rules // (base) and the .sf-surface--* / .sf-link--* macros are present. -const { test, expect } = require('@playwright/test'); -const path = require('path'); -const { pathToFileURL } = require('url'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; -const FIXTURE = pathToFileURL(path.join(__dirname, 'fixture.html')).href; +const FIXTURE = pathToFileURL(path.join(import.meta.dirname, 'fixture.html')).href; const SURFACES = [ 'primary', 'secondary', 'tertiary', 'action', 'neutral', diff --git a/tests/behavior.spec.js b/tests/behavior.spec.js index dd15f69f..8ae36fb1 100644 --- a/tests/behavior.spec.js +++ b/tests/behavior.spec.js @@ -1,11 +1,11 @@ // @ts-check // Behavioural regression tests: reduced-motion, forced-colors, container // queries, and a sample of state-class effects. Loads the demo over file://. -const { test, expect } = require('@playwright/test'); -const path = require('path'); -const { pathToFileURL } = require('url'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; -const DEMO_URL = pathToFileURL(path.resolve(__dirname, '..', 'docs', 'demo.html')).href; +const DEMO_URL = pathToFileURL(path.resolve(import.meta.dirname, '..', 'docs', 'demo.html')).href; test.describe('Reduced motion', () => { test('transitions are neutralised under prefers-reduced-motion: reduce', async ({ page }) => { diff --git a/tests/bundle-size.spec.js b/tests/bundle-size.spec.js index b758f4d5..a858cf23 100644 --- a/tests/bundle-size.spec.js +++ b/tests/bundle-size.spec.js @@ -2,12 +2,12 @@ // Bundle-size regression guard. Fails if a built bundle's gzip size exceeds // its budget — catches accidental bloat. Budgets are deliberately loose // headroom over current sizes, tightened as the framework stabilises. -const { test, expect } = require('@playwright/test'); -const fs = require('fs'); -const path = require('path'); -const zlib = require('zlib'); +import { test, expect } from '@playwright/test'; +import fs from 'node:fs'; +import path from 'node:path'; +import zlib from 'node:zlib'; -const DIST = path.resolve(__dirname, '..', 'dist'); +const DIST = path.resolve(import.meta.dirname, '..', 'dist'); // gzip kB budgets per minified bundle. const BUDGETS = { diff --git a/tests/color-semantic.spec.js b/tests/color-semantic.spec.js index 035e191e..9577d90d 100644 --- a/tests/color-semantic.spec.js +++ b/tests/color-semantic.spec.js @@ -2,12 +2,12 @@ // Verifies semantic colour-token pairs meet WCAG contrast requirements // and that the palette scale and surface hierarchy are coherent. // Runs in both light and dark themes. -const { test, expect } = require('@playwright/test'); -const path = require('path'); -const { pathToFileURL } = require('url'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; // fixture.html loads slashed.full.css (includes tokens.palette.css) -const FIXTURE = pathToFileURL(path.join(__dirname, 'fixture.html')).href; +const FIXTURE = pathToFileURL(path.join(import.meta.dirname, 'fixture.html')).href; // ── Serialisable in-browser helpers ───────────────────────────── // Functions passed directly to page.evaluate() must be self-contained diff --git a/tests/container-queries.spec.js b/tests/container-queries.spec.js index 91845ce6..982f904a 100644 --- a/tests/container-queries.spec.js +++ b/tests/container-queries.spec.js @@ -4,8 +4,8 @@ // below 30em, between 30em–48em, and above 48em (1em = 16px by default). // setupInContainer pins font-size to 16px so em-based CQ thresholds are stable // across browsers (WebKit 26+ resolves em against inherited font-size, not 16px). -const { test, expect } = require('@playwright/test'); -const path = require('path'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; const BUNDLE = path.join(process.cwd(), 'dist', 'slashed.essential.css'); diff --git a/tests/coverage.spec.js b/tests/coverage.spec.js index 525f5ed6..64af3582 100644 --- a/tests/coverage.spec.js +++ b/tests/coverage.spec.js @@ -1,7 +1,7 @@ // @ts-check -const { test, expect } = require('@playwright/test'); -const fs = require('fs'); -const path = require('path'); +import { test, expect } from '@playwright/test'; +import fs from 'node:fs'; +import path from 'node:path'; /** * Selector inventory coverage test. diff --git a/tests/demo-a11y-panel.spec.js b/tests/demo-a11y-panel.spec.js index 59b70c7b..e67f6af4 100644 --- a/tests/demo-a11y-panel.spec.js +++ b/tests/demo-a11y-panel.spec.js @@ -2,11 +2,11 @@ // Verifies the demo's live accessibility-report panel renders contrast grades // for every key colour pair in both modes, and recomputes when the brand // colours change. -const { test, expect } = require('@playwright/test'); -const path = require('path'); -const { pathToFileURL } = require('url'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; -const DEMO_URL = pathToFileURL(path.resolve(__dirname, '..', 'docs', 'demo.html')).href; +const DEMO_URL = pathToFileURL(path.resolve(import.meta.dirname, '..', 'docs', 'demo.html')).href; test.describe('Live accessibility report', () => { test('renders a grade for every pair in light and dark', async ({ page }) => { diff --git a/tests/demo-visual.spec.js b/tests/demo-visual.spec.js index f2a0f5cc..d473ccce 100644 --- a/tests/demo-visual.spec.js +++ b/tests/demo-visual.spec.js @@ -3,11 +3,11 @@ // Tests colors, shapes, shadows, layouts, grids, print, typography, // spacing, radius, motion states, accessibility, and all layout primitives. -const { test, expect } = require('@playwright/test'); -const path = require('path'); -const { pathToFileURL } = require('url'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; -const DEMO_URL = pathToFileURL(path.resolve(__dirname, '..', 'docs', 'demo.html')).href; +const DEMO_URL = pathToFileURL(path.resolve(import.meta.dirname, '..', 'docs', 'demo.html')).href; // Helper: resolve a CSS custom property value on an element async function getComputedProp(locator, prop) { diff --git a/tests/layers.spec.js b/tests/layers.spec.js index aca130e8..a1ab7b89 100644 --- a/tests/layers.spec.js +++ b/tests/layers.spec.js @@ -1,6 +1,6 @@ // @ts-check -const { test, expect } = require('@playwright/test'); -const path = require('path'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; /** * Layer ordering invariant test. diff --git a/tests/layout.spec.js b/tests/layout.spec.js index f4e168ba..28ddf4f1 100644 --- a/tests/layout.spec.js +++ b/tests/layout.spec.js @@ -1,7 +1,7 @@ // @ts-check // Behavioural tests for core/layout.css — every layout primitive. -const { test, expect } = require('@playwright/test'); -const path = require('path'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; const BUNDLE = path.join(process.cwd(), 'dist', 'slashed.essential.css'); diff --git a/tests/link-contrast.spec.js b/tests/link-contrast.spec.js index 60bb958e..c91dec1f 100644 --- a/tests/link-contrast.spec.js +++ b/tests/link-contrast.spec.js @@ -4,11 +4,11 @@ // range of brand `--sf-color-action` overrides (moderate-chroma hues). // Very high-chroma hues (saturated yellow/green) are a documented exception // and intentionally not asserted here. -const { test, expect } = require('@playwright/test'); -const path = require('path'); -const { pathToFileURL } = require('url'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; -const DEMO_URL = pathToFileURL(path.resolve(__dirname, 'a11y-fixture.html')).href; +const DEMO_URL = pathToFileURL(path.resolve(import.meta.dirname, 'a11y-fixture.html')).href; // Moderate brand colours someone might plausibly set as their action colour. const OVERRIDES = [ diff --git a/tests/macros.spec.js b/tests/macros.spec.js index 94037e13..f1af5689 100644 --- a/tests/macros.spec.js +++ b/tests/macros.spec.js @@ -2,8 +2,8 @@ // Behavioural tests for core/macros.css. // Each macro is exercised against a synthetic fixture and its // observable effect verified via getComputedStyle / layout reads. -const { test, expect } = require('@playwright/test'); -const path = require('path'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; const BUNDLE = path.join(process.cwd(), 'dist', 'slashed.essential.css'); diff --git a/tests/print.spec.js b/tests/print.spec.js index c6fb9331..f60206dc 100644 --- a/tests/print.spec.js +++ b/tests/print.spec.js @@ -1,6 +1,6 @@ // @ts-check -const { test, expect } = require('@playwright/test'); -const path = require('path'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; /** * Print color preservation smoke test. diff --git a/tests/states-full.spec.js b/tests/states-full.spec.js index 1a5609e9..844562ea 100644 --- a/tests/states-full.spec.js +++ b/tests/states-full.spec.js @@ -1,7 +1,7 @@ // @ts-check // Full coverage of every .is-* class in core/states.css. -const { test, expect } = require('@playwright/test'); -const path = require('path'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; const BUNDLE = path.join(process.cwd(), 'dist', 'slashed.essential.css'); diff --git a/tests/token-api.spec.js b/tests/token-api.spec.js index f408418d..e2df25f2 100644 --- a/tests/token-api.spec.js +++ b/tests/token-api.spec.js @@ -15,15 +15,15 @@ // This test is pure-Node (no browser). It runs under @playwright/test // for consistency with the rest of the suite. -const { test, expect } = require('@playwright/test'); -const fs = require('fs'); -const path = require('path'); +import { test, expect } from '@playwright/test'; +import fs from 'node:fs'; +import path from 'node:path'; -const ROOT = path.resolve(__dirname, '..'); +const ROOT = path.resolve(import.meta.dirname, '..'); // Source files contributing to the public token surface. // Imported from scripts/registry-sources.js — the canonical single definition. -const { TOKEN_FILES } = require('../scripts/registry-sources'); +import { TOKEN_FILES } from '../scripts/registry-sources.js'; // Names declared inside @keyframes blocks and other contexts that // look like tokens but aren't custom properties on :root. The regex @@ -55,7 +55,7 @@ function declaredTokens() { } test('Token API: declared --sf-* names match the locked snapshot', () => { - const SNAPSHOT_PATH = path.join(__dirname, 'token-api.snapshot.json'); + const SNAPSHOT_PATH = path.join(import.meta.dirname, 'token-api.snapshot.json'); const current = declaredTokens(); if (!fs.existsSync(SNAPSHOT_PATH)) { diff --git a/tests/tokens.spec.js b/tests/tokens.spec.js index e81ef272..689b43d8 100644 --- a/tests/tokens.spec.js +++ b/tests/tokens.spec.js @@ -3,16 +3,16 @@ // dark and asserts the invariants behind the fixed bugs, plus a coverage // check that every declared --sf-* token resolves in both themes. -const { test, expect } = require('@playwright/test'); -const fs = require('fs'); -const path = require('path'); -const { pathToFileURL } = require('url'); +import { test, expect } from '@playwright/test'; +import fs from 'node:fs'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; -const ROOT = path.resolve(__dirname, '..'); -const FIXTURE = pathToFileURL(path.join(__dirname, 'fixture.html')).href; +const ROOT = path.resolve(import.meta.dirname, '..'); +const FIXTURE = pathToFileURL(path.join(import.meta.dirname, 'fixture.html')).href; // ---- Parse the declared token names from the source ---------------------- -const { TOKEN_FILES } = require('../scripts/registry-sources'); +import { TOKEN_FILES } from '../scripts/registry-sources.js'; // Tokens whose value is the `inherit` keyword resolve to empty at :root // (no parent to inherit from) — by design, so they're excluded from coverage. diff --git a/tests/typography.spec.js b/tests/typography.spec.js index 8ffe23e9..8fa456c3 100644 --- a/tests/typography.spec.js +++ b/tests/typography.spec.js @@ -2,11 +2,11 @@ // Typography, spacing, border-radius, and z-index token scale tests. // Tokens use clamp() / calc() — values are resolved via element styles // at a fixed 1200px viewport so comparisons are stable. -const { test, expect } = require('@playwright/test'); -const path = require('path'); -const { pathToFileURL } = require('url'); +import { test, expect } from '@playwright/test'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; -const FIXTURE = pathToFileURL(path.join(__dirname, 'fixture.html')).href; +const FIXTURE = pathToFileURL(path.join(import.meta.dirname, 'fixture.html')).href; const BUNDLE = path.join(process.cwd(), 'dist', 'slashed.essential.css'); async function setup(page, html) {