Selector System Overview
This document explains how user-related DOM selectors are managed, structured, and tested within the project.
📦 selectorMetadata.ts
: The Source of Truth
All selectors are defined in selectorMetadata.ts
. Each selector has:
selector
: A CSS selector stringcontexts
: One or more pages it appears ondescription
(optional): Clarifies purposesmoketest
(optional, default = true): If false, the selector is excluded from CI smoketests
Example:
{
selector: '.channel-root--watch h1.tw-title',
contexts: ['channelWatch'],
description: 'Live stream view title',
}
🧠 Context Definitions
Context | Meaning |
---|---|
homepage | Twitch front page after load |
sidebarCollapsed | Same as homepage , but nav is collapsed |
channelWatch | The initial landing page when clicking a live stream |
channelHome | The full profile view after clicking the channel name |
⚙️ selectors.ts
: Auto-Generated for Extension Use
This file flattens and deduplicates all selectors across all contexts:
export const USERNAME_SELECTORS = Array.from(
new Set(SELECTOR_METADATA.map(meta => meta.selector))
);
Used by the extension’s content script for note display and interaction.
🧪 selector-check.ts
: Context-Aware Smoketests
This script performs a CI smoketest that:
- Visits each relevant Twitch context
- Runs only the selectors assigned to that context
- Compares results to
last-smoketest.json
- Fails CI if any selector previously
true
is nowfalse
Smoketests automatically skip any selector marked smoketest: false
.
➕ How to Add a New Selector
- Add a new object to
selectorMetadata.ts
- Assign appropriate
contexts
- Optionally provide a
description
andsmoketest: false
if it should be excluded from testing - No need to touch
selectors.ts
or the smoketest logic — it’s all dynamic - Run
npm run smoketest
and review output
🔍 Debugging Tips
- You can run the smoketest manually with:
npm run smoketest
- If a selector isn’t being found:
- Open the live site in Chrome DevTools
- Paste your selector in
document.querySelector(...)
to confirm - Consider adding
scrollIntoViewIfNeeded()
or waiting for delayed DOM load