Skip to content

ci: add weekly selector health canary for x.com bundle identifiers#4

Open
digitalby wants to merge 1 commit intomainfrom
feat/ci-selector-health
Open

ci: add weekly selector health canary for x.com bundle identifiers#4
digitalby wants to merge 1 commit intomainfrom
feat/ci-selector-health

Conversation

@digitalby
Copy link
Copy Markdown
Owner

Why

Twitter/X silently rotates data-testid values. 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 loads https://x.com/jack/status/20 (a public status URL; the login-walled x.com/ root is missing most SPA chunks), captures every JS response, and greps for proxy identifiers listed in selectors.json.
  • .github/workflows/selector-health.yml -- runs weekly (0 9 * * 1), on workflow_dispatch, and on push to main when the tool or workflow file changes. On failure it opens, or edits if already open, a single rolling Selector health check failing issue via gh.

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 own querySelector call. 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-testid rename where the component keeps its name. Documented in tools/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_CARET for a bogus string produces exit 1 with the correct missing-selector report.

OK  [critical] tweet-article            hits=1/1
OK  [critical] three-dot-menu           hits=3/1
OK  [high]     app-bar-back             hits=12/3
OK  [high]     user-name                hits=54/10
OK  [high]     user-avatar-container-   hits=1/1
OK  [high]     quote-tweet              hits=98/10
OK  [high]     user-cell                hits=13/5
OK  [medium]   retweet                  hits=274/10
OK  [medium]   unretweet                hits=22/3

CI cannot run until merged because workflow_dispatch and path-filtered push require the workflow file to exist on the default branch.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant