import { readdirSync, readFileSync } from 'node:fs' import { dirname, join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { describe, expect, it } from 'vitest' // SDK control refresh phase 1, fix round 1: dark-mode ink, hairlines and sizing. const stylesDir = resolve(dirname(fileURLToPath(import.meta.url)), '../../styles') const componentsDir = join(stylesDir, 'components') const css = (name: string) => readFileSync(join(componentsDir, name), 'utf-8') describe('dark-mode ink and hairline rules', () => { it('should find no light-only ink text color when scanning component styles', () => { const offenders = readdirSync(componentsDir) .filter(f => f.endsWith('.css')) .flatMap(f => css(f).split('\n').map((l, i) => ({ l, at: `${f}:${i + 1}` }))) .filter(({ l }) => /(^|[\s;{])color:\s*var\(--(color-primary-hover|mint-error-hover)\)/.test(l)) .map(({ at }) => at) expect(offenders).toEqual([]) }) it('should lift the ink aliases toward --text-primary when the theme is dark', () => { const dark = readFileSync(join(stylesDir, 'variables.css'), 'utf-8').match(/html\.dark \{[^}]*\}/)?.[0] ?? '' expect(dark).toMatch(/--_ink-primary: color-mix\(in srgb, var\(--color-primary\) 50%, var\(--text-primary\)\);[\s\S]*--_ink-error: color-mix\(in srgb, var\(--mint-error\) 50%, var\(--text-primary\)\);/) }) it.each([ ['batch-progress-list.css', 'mint-batch-progress'], ['dataframe.css', 'mint-dataframe'], ['fit-panel.css', 'mint-fit-panel'], ['jobs-status-tray.css', 'mint-jobs-tray'], ['molecule-input.css', 'mint-molecule-input'], ['reagent-list.css', 'mint-reagent-list'], ['sample-hierarchy-tree.css', 'mint-sample-tree'], ['sequence-input.css', 'mint-sequence-input'], ['step-wizard.css', 'mint-wizard'], ])('should draw %s hairlines with --border-color when the theme is dark', (file, root) => { expect(css(file)).toContain(`:where(html.dark) .${root} {\n --border-light: var(--border-color);\n}`) }) it('should stripe DataFrame rows with a tint that differs from the --bg-card surface', () => { expect(css('dataframe.css')).not.toMatch(/\.mint-dataframe__row--striped[^{]*\{[^}]*--bg-secondary/) }) it('should size timeline icons border-box so the dashed skipped ring keeps the nominal size', () => { expect(css('experiment-timeline.css')).toMatch(/\.mint-timeline__icon \{[^}]*box-sizing: border-box;/) }) })