Skip to content
Development

Six small UI items, and the two near-misses hiding inside them

By Victor Da Luz
sveltecsstestingdev-loggreenhouse

A batch of six small UI-review items landed on Greenhouse: a duplicated icon, an inconsistent count badge, an unstyled dropdown, missing dialog motion, a locale switch that drops your current view, and one dead-looking CSS block. Five were exactly as described. One turned out not to be dead at all, and fixing a completely unrelated one nearly took thirty-nine tests down with it.

The straightforward five

A folder icon SVG was pasted into four different places across two files. Not three, like the review said, once I actually grepped for the path data instead of trusting the count. Pulled it into one small component.

A count badge on the dashboard’s zones was announced to screen readers as an orphaned number with no context (“3”, with nothing saying three of what), while the same badge on the kanban board was hidden from screen readers entirely. Two different fixes applied inconsistently over time. Folded the count into each heading’s accessible name instead (“Ripe today, 3 items”), which needed a real pluralized, translated string rather than a hardcoded one - the same lesson I’d already learned the hard way on the iOS side.

Then: styled the one remaining unstyled dropdown in the app, added fade-in/fade-out motion to every native dialog with one shared CSS rule instead of copy-pasting it into seven files, and fixed the locale switcher. That last one reloads the whole window to apply a new language, and it used to always land you back on the home screen regardless of what you had open. Now it remembers and restores it.

The one that wasn’t actually dead

The sixth item was a CSS block that forces light or dark mode via a data-theme attribute, flagged as dead because nothing in the app’s UI ever sets that attribute. Grep-confirmed, even.

Except before deleting it I ran the test suite that exercises it, out of habit more than suspicion, and found a real-browser accessibility test that deliberately sets data-theme itself. That’s the only way to check color contrast in both light and dark mode without depending on whatever theme the machine running the tests happens to be in.

Deleting the CSS wouldn’t have thrown an error. It would have quietly made that test stop testing dark mode at all, with no red X to notice. “Grep-confirmed dead” only checked application code. It never checked test code, and I’ve deleted dead code for the wrong reason before.

The one that broke everything else

The locale-switch fix needed localStorage to remember the open view across a full page reload. Completely ordinary code, first line I wrote. It broke thirty-nine unrelated tests across three files the instant it ran.

Node 25 ships its own native localStorage, on by default. Without a specific file path configured for it, that native version exists but is silently non-functional: present, but every method missing. It sits in front of jsdom’s own working localStorage in the test environment, so any code that touches the global gets the broken one.

The fix wasn’t a jsdom config flag. I tried that first and it didn’t help, because the origin was never the actual problem. It was patching the test setup file with a small in-memory stand-in, the same way a <dialog> compatibility gap was already patched there for an older jsdom version.

Lesson

Neither of those two would have shown up by reading the diff. Both only showed up by running the existing test suite before assuming a change was safe - which is the cheapest possible check and the one easiest to skip on a batch of items that all look like one-liners.

Related reading

Development

The cancel button that didn't cancel

Escape looked like it worked in every manual click-through. Writing the regression test forced the real event order - and the stray blur that saved what should have been thrown away.

Read