Repository navigation
feat(browser): let a project name its test-id attribute - #1395
Conversation
Signed-off-by: Siddheya Kulkarni <[email protected]>
|
Thanks for your first pull request to Reticle! A maintainer aims to review within two days. Before then, |
|
divshekhar
left a comment
There was a problem hiding this comment.
Thanks, the shape is right. One module owns the attribute, every site from #1376 goes through it, and with the default attribute nothing changes, so saved flows keep replaying. I also checked the wire side: testidFoundUnder is optional and the contract fingerprint doesn't cover hint fields, so older daemons and SDKs are fine. And init keeps the new .reticle.json key on a re-run.
There are two real bugs, two red checks, and a few smaller things.
Bugs
-
Secret redaction gets narrower. With
data-cyconfigured,<input data-testid="api-key">is no longer treated as sensitive, so its raw value goes out. I reproduced it:isSensitiveFieldreturns true on main and false on this branch. Indom/a11y.ts:361andobservers/field.ts:69, check the configured attribute andDEFAULT_TESTID_ATTR. Changing this setting should only ever widen redaction. Please add that exact case as a test. -
Some valid-looking names crash every query.
TESTID_ATTR_PATTERN(core/src/identity/testid-attribute.ts:24) accepts.and:. Withdata.testorxlink:foo,runQuerythrows "Invalid selector", and so doesclosest()in the DOM observer on every mutation. Tightening it to/^[a-zA-Z_][\w-]*$/fixes it. Add a test for both names. Injection itself is already handled:x],[onclickfalls back to the default.
Red checks
-
verify:server/src/surface/tools/tools.tsgoes from 997 to 1003 lines, over the 1000-line cap. Shorten thetestidFoundUnderdescription, or move the hint schema out of that file. -
unit-tests: the newtestid-attr.tsmakes 13 loose files inadapters/realm/browser/src/dom, andserver/src/guards/harness/flat-directories-are-recorded.test.ts:347records 12. Either bump that count with a one-line reason next to it, or put the file in a subfolder.
Smaller
-
Next.js and Remix ignore the setting. The
.reticle.jsonsetting only reaches the SDK through the Vite plugin's generated connect. The Next adapter (adapters/build/next/index.cjs) already reads.reticle.json, so passingtestIdAttributethrough there is a small change. If you'd rather not, say "Vite only" in the changes file, inconnect-options.tsand in the hint text attools.ts:511. -
The miss hint skips
data-testid. Inquery.ts:714, when another attribute is configured, also checkDEFAULT_TESTID_ATTR. Otherwise a project that switches attributes gets no hint when its old flows miss. -
The wiring has no tests. Deleting
setTestIdAttr(options.testIdAttribute)(reticle.ts:428) or the forwarding inconnect-args.ts:74wouldn't fail anything. AconnectArgstest, plus one whereconnect({ testIdAttribute })makes a query resolve, would cover both.
The red install-gate is a cancelled duplicate run, not your change. #1385 and #1171 also touch query.ts and a11y.ts, so expect a rebase depending on which lands first.
Signed-off-by: Siddheya Kulkarni <[email protected]>
divshekhar
left a comment
There was a problem hiding this comment.
Nice work. I went through all seven points, deleting each fix to check the tests go red. Six are done properly: the pattern, the line cap, the dom/addressing/ move, the hint fallback, both wiring tests, and the a11y.ts side of redaction. CI is green too.
Two small things left:
-
field.tschecks both attributes now, but nothing tests it. I deleted theDEFAULT_TESTID_ATTRcheck atfield.ts:72and all 1816 browser tests still passed. This test inobservers/field.test.ts, inside the redaction block, covers it. It passes on your branch and fails with that check removed:it('still redacts a data-testid secret after data-cy is configured', () => { setTestIdAttr('data-cy'); // reset with setTestIdAttr(undefined) in afterEach const { events } = page('<input data-testid="api-key" value="s3cret" />'); const input = document.querySelector('input'); if (null === input) throw new Error('no input'); fire(input, 'change'); expect(events[0]?.data['value']).toBeUndefined(); expect(events[0]?.data['redacted']).toBe(true); });
-
connect-options.ts:38still says "Normally supplied by the build plugin". Make it say it comes from the Vite plugin only, and that Next.js, Remix and manual setups pass it here, to match the changes file.
Also, the comment at review/mark-anchor.ts:12 ("Attribute names — defined locally…") doesn't describe anything anymore. Please delete it.
After those, I'll merge it.
Signed-off-by: Siddheya Kulkarni <[email protected]>
Signed-off-by: Siddheya Kulkarni <[email protected]>
divshekhar
left a comment
There was a problem hiding this comment.
Thanks. I checked the new field test by deleting the DEFAULT_TESTID_ATTR check in field.ts, and it fails, so the redaction fix is covered now. The comment is fixed and the stale one is gone. Merging.
Brings in the project-chosen test-id attribute (#1395) and init's no-package.json refactor (#1396). Two budgets recorded with their measurements: first load 248,736 B (ceiling 249,700) and the all-tools output-schema surface 146,174 B (budget 146,400). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: Divyanshu Shekhar <[email protected]>
What & why
The
testidlocator only readdata-testid, so apps that mark controls withdata-test-subj(Elastic UI) ordata-cy(Cypress) got "matched no element" on a button that was on screen.testIdAttributeoption:.reticle.json-> read by@reticlehq/vite-plugin(or set onreticle()/connect()directly) ->setTestIdAttrin the SDK. An invalid attribute name falls back todata-testid.dom/testid-attr.ts, replacing the hard-codeddata-testidcopies.hint.testidFoundUndernaming the alternative attribute (data-test-subj,data-cy,data-test,data-qa,data-e2e) that holds the value. It never widens matching.Not addressed: the separate
role: "button", name: "Next page"miss on anaria-labelbutton; it needs a minimal EuiDataGrid repro.Closes #1376
How it was verified
query.testid-attribute.test.ts: configured attribute resolves, default unchanged, near-miss names the attribute, advertised testids follow the setting, invalid name ignored.readConfiguredTestIdAttributetests in vite-plugin.Gates run
pnpm lint && pnpm typecheck && pnpm test:unit(~2 min — always)pnpm test:e2e(~8 min) — touched the tool surface,core, an observer, or telemetrypnpm gate:install(~15 min) — touchedreticle init,vite-plugin,next, orbabel-pluginpnpm test:e2e:desktop(~3 min) — touchedadapters/realm/electron,adapters/realm/tauri, or desktop captureChecklist
git commit -s) — CI's DCO check fails the PR without it. Already pushed?git rebase --signoff origin/main && git push --force-with-leaseany, no free strings (wire strings live in@reticlehq/core), no non-null!console.logor internal tracking codes left in the diff.changes/(never editCHANGELOG.md— that file is assembled at release time, and editing it is what makes PRs conflict; format in.changes/README.md)docs/telemetry.md) and are covered by a test