fix(e2e): match an email template tab on its whole name, not a prefix #353

Merged
bermudalamb merged 1 commits from fix/email-template-tab-name-collision into main 2026-09-11 10:04:43 -05:00
Owner

Fixes the only genuine failure in the first CI run after the runner was unblocked. Everything else failing in run 985 is #154.

strict mode violation: getByRole('tab', { name: /Email address changed/ })
resolved to 2 elements

The cause

AdminEmails built an unanchored regex from each label, so a template whose name merely began with another's matched both. #337 added "Email address changed by the shop" alongside "Email address changed" and broke the assertion above it.

The failure named the assertion rather than the new template, which is what makes this worth more than a rename. Same shape as the switch locator that silently retargeted in #317: a loose locator keeps passing until something new is added nearby, then fails somewhere that says nothing about the cause.

The fix

The locator, not the label. One helper builds a matcher anchored at both ends, allowing only the optional Customised suffix a tab carries once its template has been edited, and escaping the label because these are copy and copy acquires brackets and full stops eventually.

Both railTab and customisedTab go through it, and callers pass plain strings instead of assembling regexes at each call site.

The new template is added to the list the test walks, which it should have had in #337.

Testing

Verified the matcher against every real label and every colliding pair:

Label Against Matches
Email address changed Email address changed yes
Email address changed Email address changed by the shop no
Email address changed Email address changed Customised yes
Email address changed by the shop Email address changed no
Password reset Password resetting no

A customised-only match still rejects an unedited tab. Frontend tsc and lint clean.

🤖 Generated with Claude Code

Fixes the only genuine failure in the first CI run after the runner was unblocked. Everything else failing in run 985 is #154. ``` strict mode violation: getByRole('tab', { name: /Email address changed/ }) resolved to 2 elements ``` ## The cause `AdminEmails` built an **unanchored** regex from each label, so a template whose name merely *began* with another's matched both. #337 added "Email address changed by the shop" alongside "Email address changed" and broke the assertion above it. The failure named the assertion rather than the new template, which is what makes this worth more than a rename. Same shape as the switch locator that silently retargeted in #317: a loose locator keeps passing until something new is added nearby, then fails somewhere that says nothing about the cause. ## The fix The locator, not the label. One helper builds a matcher anchored at both ends, allowing only the optional `Customised` suffix a tab carries once its template has been edited, and escaping the label because these are copy and copy acquires brackets and full stops eventually. Both `railTab` and `customisedTab` go through it, and callers pass plain strings instead of assembling regexes at each call site. The new template is added to the list the test walks, which it should have had in #337. ## Testing Verified the matcher against every real label and every colliding pair: | Label | Against | Matches | |---|---|---| | Email address changed | Email address changed | yes | | Email address changed | Email address changed by the shop | **no** | | Email address changed | Email address changed Customised | yes | | Email address changed by the shop | Email address changed | **no** | | Password reset | Password resetting | **no** | A customised-only match still rejects an unedited tab. Frontend `tsc` and lint clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bermudalamb added 1 commit 2026-09-11 10:01:40 -05:00
fix(e2e): match an email template tab on its whole name, not a prefix
Linting / lint (pull_request) Successful in 3m47s
SonarQube Analysis / sonarqube (pull_request) Canceled after 0s
c2ee0b0c5d
CI failed on a test nobody had touched:

    strict mode violation: getByRole('tab', { name: /Email address changed/ })
    resolved to 2 elements

The locators in AdminEmails built an unanchored regex from the label, so a template whose name merely began with another's matched both. #337 added "Email address changed by the shop" alongside "Email address changed" and broke the assertion above it.

The failure named the assertion rather than the new template, which is what made it worth more than a rename. It is the same shape as the switch locator that silently retargeted in #317: a loose locator that keeps passing until something new is added nearby, and then fails somewhere that says nothing about the cause.

So the fix is the locator rather than the label. One helper now builds a matcher anchored at both ends, allowing only the optional "Customised" suffix a tab carries once its template has been edited, and escaping the label because these are copy and copy acquires brackets and full stops eventually. Both railTab and customisedTab go through it, and callers pass plain strings instead of assembling regexes at each call site.

The new template is added to the list the test walks, which is what it should have had in #337.

Verified the matcher against every real label plus the pairs that collide, including that a customised-only match still rejects an unedited tab. Frontend tsc and lint clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bermudalamb merged commit b82b989cc8 into main 2026-09-11 10:04:43 -05:00
bermudalamb deleted branch fix/email-template-tab-name-collision 2026-09-11 10:04:43 -05:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bermudalamb/redefined-designs#353