fix(platform): green the automations workbench i18n and lint gates - #3185
Merged
Conversation
The automations workbench landed with its switcher namespace missing from
the base locale, so `automations.switcher.*` rendered as raw keys and three
CI jobs went red on main:
- Unit: `usage-missing` flagged all four `t('switcher.*')` calls as
referenced-but-undefined, and `usage` flagged three keys defined but
never read.
- UI: the breadcrumb suites resolve real messages (they do not mock
`useT`), so eight assertions looked for an accessible name the switcher
could not produce.
- Lint: six oxlint errors in the new components.
Add the four `switcher` keys to en/de/fr, mirroring `projects.switcher`
key-for-key — same wording shape, same quoting, same placeholder. de-CH is
a sparse overlay with no `automations` block and needs none.
Drop `trigger.enabledBadge`, `trigger.disabledBadge` and
`bindings.orgBadge`. No component renders them: the trigger editor shows a
labelled Switch, the bindings panel shows a count badge, and its test
asserts the org badge is absent for an unbound automation. They are
leftovers from an earlier design, not missing UI.
For lint: give the three cleanup-returning effects an explicit
`return undefined` on their early-out, compare the two plain booleans
directly, and build the version menu items in a block body so the
conditional `trailing` no longer needs a spread inside `map`.
…class The automations spec builds its create-menu locator from `automations.list.createButton`, which is not in the catalog — the list labels that button `builder.new`. The spec failed all three Playwright retries on `messages key is not a string`. Point it at the key the component actually renders. The `usage-missing` check could not see this: it reads only `t` aliases bound by `useT`/`useTranslation` to a known namespace, and the e2e helper's `t` takes a whole key path. Widening its `scanRoots` to `tests` changes nothing for the same reason. So guard it where the reference lives — run every static `t()` literal in `tests/e2e/**` through the specs' own resolver. Same function, same catalog, so there is no second parser to drift. A missing key is now named in milliseconds instead of costing a Playwright shard. A floor on the reference count keeps the check from passing vacuously if the pattern stops matching.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
mainis red on four CI jobs. All of it traces to one landed change: theautomations workbench shipped its breadcrumb switcher without adding the
automations.switcher.*namespace to the base locale.What was failing
Unitlib/i18n/messages.test.ts— 4 referenced-but-undefined keys, 3 defined-but-unread keysUIautomation-breadcrumbs+automation-breadcrumb-switcher— 8 assertionsLintPlaywright (platform 4/16)automations.spec.ts— all 3 retries onmessages key is not a stringThe
UIfailures are the same defect, not a separate one. Those two suitesdon't mock
useT, so they resolve real messages — the switcher trigger couldnot produce the accessible name they look for, because
switcher.ariaLabeldidn't exist. Every other automations suite mocks
useTto echons.key,which is why they stayed green and hid it.
This is user-visible, not just a red gate: the switcher's title, search
placeholder, empty state and aria-label all rendered as raw key paths.
What this changes
Adds the four
switcherkeys toen,deandfr, mirroringprojects.switcherkey-for-key — the only existing instance of thiscomponent's contract. Same wording shape, same quoting convention (fr uses
double quotes around the apostrophe and a plain space before the colon,
matching its neighbours), same
{name}placeholder.de-CHis a sparseoverlay with no
automationsblock, so it needs nothing.Drops three dead keys —
trigger.enabledBadge,trigger.disabledBadge,bindings.orgBadge. Nothing renders them, and no hardcoded English stands intheir place: the trigger editor uses a labelled
Switch(
trigger.enabledLabel), the bindings panel a count badge(
bindings.countBadge), andproject-bindings-section.test.tsxasserts theorg badge is absent for an unbound automation. They're leftovers from an
earlier design. Flagging it explicitly in case one was meant as UI that never
got wired — say so and I'll build the badge instead.
Fixes the e2e locator key.
automations.spec.tslooked for a button namedautomations.list.createButton; the list labels that buttonbuilder.new.The spec now asks for the key the component renders.
Six lint fixes, all mechanical:
return undefinedon theirearly-out, matching the house pattern in
organization-settings.tsxandpreferences-settings.tsxenabled !== true→!enabled, andtrigger.blocked !== true→!trigger.blocked; both are non-optional booleans.trigger?.dirty === truestays — that one reaches through an optional chain
trailingis a ternary instead of a spread inside
mapNew guard
usage-missingcould not have caught the e2e break: it reads onlytaliasesbound by
useT/useTranslationto a known namespace, and the e2e helper'sttakes a whole key path. I tried widening its
scanRootstotestsfirst — itchanges nothing, for that same reason, so it isn't in this diff.
lib/i18n/e2e-keys.test.tsguards it where the reference actually lives: everystatic
t()literal undertests/e2e/**goes through the specs' own resolver.Same function, same catalog, so there's no second parser to drift. It currently
covers 333 references across 21 files, and a floor on that count keeps it from
passing vacuously if the pattern stops matching.
Verification
Each gate observed red before and green after, on this branch:
oxlint --type-aware: exit 1 onmain→ exit 0 herelib/i18n/: 2 failed / 22 passed → 50 passed (50)clientproject: 3439 passedtypecheck0 errors,oxfmt --checkcleanBoth new assertions mutation-tested: restoring the bad key fails the guard and
names it (
automations.list.createButton (specs/automations.spec.ts)), andbreaking the extraction pattern fails the floor.
One unrelated pre-existing failure remains in
app/components/ui/forms/date-picker.test.tsx(apointer-eventscomputed-style assertion). It fails identically on unmodified
mainand doesnot fail in CI, so it's out of scope here.