Skip to content

Phase 5: selectors module with multi-strategy fallbacks#7

Merged
froggychips merged 1 commit into
mainfrom
review/phase-5-selectors
May 19, 2026
Merged

Phase 5: selectors module with multi-strategy fallbacks#7
froggychips merged 1 commit into
mainfrom
review/phase-5-selectors

Conversation

@froggychips

Copy link
Copy Markdown
Owner

Summary

X часто переименовывает data-testid атрибуты, content_script завязан на них в 6+ местах. После каждого редизайна расширение тихо ломается: пустые ответы, неработающий compose.

Введён selectors.jswindow.TTASelectors с цепочками fallback-стратегий + ring-buffer счётчиком успеха каждого уровня.

Что добавлено

  • selectors.jsTTASelectors.{findTweetText, findTweetAnchor, findAuthorLink, findAccountSwitcher, findProfileLink, findComposeBox, findDmComposers}. Каждая идёт по цепочке: testid → семантика (ARIA/lang/dir) → структура.
  • Selector health — каждый успешный/проваленный поиск пишется в ring-buffer (200 последних попыток) в chrome.storage.local.tta_selector_health. Если уровень 1 стабильно проваливается — это сигнал что X сменил DOM. UI-баннер на эту диагностику оставлен на следующую итерацию (PR-8).
  • manifestselectors.js грузится перед content_script.js (один isolated world, top-level вижен).
  • content_script.jsgetTweetText, getAuthorId, detectActiveHandle, insertIntoComposer, scan() теперь через TTASelectors.*. Inline-querySelector в attachToTweet (где нужно отфильтровать quoted-блок) переведён на fallback-chain руками.

Test plan

  • Базовый flow: твит → текст → reply → context — без регрессий.
  • DevTools на x.com → chrome.storage.local.get('tta_selector_health', console.log) → видны счётчики l1/l2/l3/miss.
  • В DevTools удалить data-testid у одного твита → fallback-стратегия 2 находит текст → tweetText.l2 инкрементируется.
  • DM compose работает (findDmComposers находит элементы по testid или по aria-label).
  • Аккаунт-switcher определяет handle (через findAccountSwitcher или findProfileLink).

🤖 Generated with Claude Code

X (Twitter) часто переименовывает data-testid атрибуты, а content_script
завязан на них в 6+ местах. После очередного редизайна расширение тихо
ломается — пользователь видит пустые ответы вместо ошибки.

- Добавлен src-like модуль selectors.js: window.TTASelectors с функциями
  findTweetText, findTweetAnchor, findAuthorLink, findAccountSwitcher,
  findProfileLink, findComposeBox, findDmComposers. Каждая идёт по
  цепочке стратегий: testid → семантика (ARIA/lang/dir) → структура.
- Каждый успешный/проваленный поиск пишется в ring-buffer счётчика
  selector health (chrome.storage.local.tta_selector_health). Если l1
  стабильно проваливается — это сигнал что X сменил DOM. UI-баннер
  оставлен на следующую итерацию; диагностика читается из storage.
- manifest content_scripts.js: selectors.js загружается перед
  content_script.js, поэтому TTASelectors доступен сразу.
- content_script.js: getTweetText, getAuthorId, detectActiveHandle,
  insertIntoComposer и scan() переведены на TTASelectors.*. Старый
  inline querySelector('[data-testid="tweetText"]') в attachToTweet
  заменён на fallback-chain (нужно было отфильтровать quoted-блок).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@froggychips froggychips merged commit 76d367f into main May 19, 2026
@froggychips froggychips deleted the review/phase-5-selectors branch May 19, 2026 08:13

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

Copy link
Copy Markdown

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: 086daa6893

ℹ️ 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".

Comment thread selectors.js
Comment on lines +109 to +110
el = $(r, 'textarea');
if (el) { record('composeBox', 'l3'); return el; }

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 Avoid matching TweAI's own textarea as the X composer

When the native reply composer has not mounted synchronously after article.querySelector('[data-testid="reply"]')?.click(), this generic textarea fallback can match the .tta-compose-input textarea that buildBlock() always inserts inside the same article. Because insertIntoComposer() treats that as success, it skips quickInsert(), so the generated reply is written into the extension prompt box instead of the X reply composer in that timing case.

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