ci: add weekly selector health canary for x.com bundle identifiers#4
ci: add weekly selector health canary for x.com bundle identifiers#4
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e16b23a5dc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| navError = err.message; | ||
| } | ||
|
|
||
| await browser.close(); |
There was a problem hiding this comment.
Wait for bundle reads before closing the browser
The script closes Chromium immediately after navigation, but bundle collection happens in an async page.on('response') handler and those response.text() reads are never awaited. On slower or larger JS responses, closing the context can make response.text() fail, and the catch block silently drops those bundles, which undercounts needles and can trigger false critical/high failures in CI. Track pending response-read promises and await them before closing the browser.
Useful? React with 👍 / 👎.
Why
Twitter/X silently rotates
data-testidvalues. Today breakage is only caught when a hotkey stops working and gets reported. This adds an automated canary that fires when the x.com bundle stops shipping identifiers tied to the selectors our userscripts depend on.What
tools/selector-health/-- Playwright loadshttps://x.com/jack/status/20(a public status URL; the login-walledx.com/root is missing most SPA chunks), captures every JS response, and greps for proxy identifiers listed inselectors.json..github/workflows/selector-health.yml-- runs weekly (0 9 * * 1), onworkflow_dispatch, and on push tomainwhen the tool or workflow file changes. On failure it opens, or edits if already open, a single rollingSelector health check failingissue viagh.Honest scope
The object-literal form
"data-testid":"X"does not appear in the compiled bundle because React sets testIDs dynamically via props. Only[data-testid="tweet"]survives as a literal, thanks to Twitter's ownquerySelectorcall. Everything else is tracked via proxy identifiers (TWEET_CARET,QuoteTweet,UserCell,appBarBack,UserName,UserAvatar-Container-,retweet,unretweet).This catches structural renames and feature removals. It does not catch a silent
data-testidrename where the component keeps its name. Documented intools/selector-health/README.md.Verification
Local run: 9/9 needles pass with counts 1 to 274 against thresholds 1 to 10. Corruption test: swapping
TWEET_CARETfor a bogus string produces exit 1 with the correct missing-selector report.CI cannot run until merged because
workflow_dispatchand path-filtered push require the workflow file to exist on the default branch.