mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-30 13:35:12 +02:00
test(control-pane): derive the a11y palette from the rendered view
CodeRabbit correctly noted that hard-coding #2ea043 and #ff7b72 in the test decoupled the contrast assertions from the colors the view actually renders, so a palette change could leave them passing. The test now reads the legend glyphs, the legend colors, the riskColor() returns, and the body background back out of the rendered HTML, and asserts that the legend and canvas palettes agree before checking any ratio. Verified both directions: a mismatched canvas color fails the palette check, and a full revert to #3fb950 fails the luminance check at 1.01:1. Extends the coverage to the traffic level and the body background, which were previously unchecked. Co-Authored-By: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
@@ -31,13 +31,35 @@ function contrastRatio(left, right) {
|
||||
return (lighter + 0.05) / (darker + 0.05);
|
||||
}
|
||||
|
||||
const clear = '#2ea043';
|
||||
const resolution = '#ff7b72';
|
||||
const BACKGROUND = html.match(/body \{[^}]*background: (#[0-9a-f]{6})/)[1];
|
||||
|
||||
// Read the palette back out of the rendered view instead of hard-coding it, so
|
||||
// a colour change cannot leave these contrast assertions quietly passing.
|
||||
const legend = [...html.matchAll(
|
||||
/<span class="shape" style="color:(#[0-9a-f]{6})">([\u25cf\u25a0\u25b2])<\/span>/g
|
||||
)].map(match => ({ color: match[1], glyph: match[2] }));
|
||||
|
||||
assert.strictEqual(legend.length, 3, 'the legend should declare three risk levels');
|
||||
assert.deepStrictEqual(legend.map(entry => entry.glyph), ['\u25cf', '\u25a0', '\u25b2'],
|
||||
'clear, traffic, and resolution should be marked circle, square, and triangle');
|
||||
|
||||
const [clear, traffic, resolution] = legend.map(entry => entry.color);
|
||||
|
||||
// The legend and the canvas must agree, otherwise the operator reads a different
|
||||
// colour from the one the marker is drawn in.
|
||||
const riskColorBody = html.match(/function riskColor\(risk\) \{([\s\S]*?)\n \}/)[1];
|
||||
const canvasColors = [...riskColorBody.matchAll(/return '(#[0-9a-f]{6})';/g)].map(match => match[1]);
|
||||
assert.deepStrictEqual(canvasColors, [resolution, traffic, clear],
|
||||
'the legend palette and the riskColor palette must match');
|
||||
|
||||
// Clear and resolution must stay separable when hue is unavailable, so their
|
||||
// relative luminances have to differ by more than the ~1.05:1 that used to
|
||||
// collapse "clear" and "steer now" into the same grey.
|
||||
assert.ok(contrastRatio(clear, resolution) >= 1.3,
|
||||
`clear and resolution must differ by luminance, got ${contrastRatio(clear, resolution).toFixed(2)}:1`);
|
||||
assert.ok(contrastRatio(clear, '#0b0e14') >= 4.5,
|
||||
'the clear marker must still meet 4.5:1 against the page background');
|
||||
assert.ok(contrastRatio(resolution, '#0b0e14') >= 4.5,
|
||||
'the resolution marker must still meet 4.5:1 against the page background');
|
||||
for (const level of legend) {
|
||||
assert.ok(contrastRatio(level.color, BACKGROUND) >= 4.5,
|
||||
`the ${level.color} marker must meet 4.5:1 against the page background, got ${contrastRatio(level.color, BACKGROUND).toFixed(2)}:1`);
|
||||
}
|
||||
|
||||
console.log('Results: Passed: 12, Failed: 0');
|
||||
console.log('Results: Passed: 15, Failed: 0');
|
||||
|
||||
Reference in New Issue
Block a user