# Browser Edge Case Registry Curated list of known browser automation edge cases with symptoms, causes, and fixes. --- ## Scroll Issues ### #1: LinkedIn Nested Scroll Container | Attribute | Value | |-----------|-------| | **Site** | LinkedIn (linkedin.com/feed) | | **Symptom** | `browser_scroll()` returns `{ok: true}` but page doesn't move | | **Root Cause** | Content is in a nested scrollable div (`overflow: scroll`), not the main window | | **Detection** | `document.querySelectorAll('*')` with `overflow: scroll/auto` has large candidates | | **Fix** | JavaScript finds largest scrollable container, uses `container.scrollBy()` | | **Code** | `bridge.py:808-891` - smart scroll with container detection | | **Verified** | 2026-04-03 ✓ | ### #2: Twitter/X Lazy Loading | Attribute | Value | |-----------|-------| | **Site** | Twitter/X (x.com) | | **Symptom** | Infinite scroll doesn't load new content | | **Root Cause** | Lazy loading requires content to be visible before loading more | | **Detection** | Scroll position at bottom but no new `[data-testid="tweet"]` elements | | **Fix** | Add `wait_for_selector` between scroll calls with 1s delay | | **Code** | Test file: `tests/test_x_page_load_repro.py` | | **Verified** | - | ### #3: Modal/Dialog Scroll Container | Attribute | Value | |-----------|-------| | **Site** | Any site with modal dialogs | | **Symptom** | Scroll scrolls background page, not modal content | | **Root Cause** | Modal has its own scroll container with `overflow: scroll` | | **Detection** | Visible element with `position: fixed` and scrollable content | | **Fix** | Find visible modal container (highest z-index scrollable), scroll that | | **Code** | - | | **Verified** | - | --- ## Click Issues ### #4: Element Covered by Overlay | Attribute | Value | |-----------|-------| | **Site** | SPAs, sites with loading overlays | | **Symptom** | Click succeeds but no action triggered | | **Root Cause** | Element is covered by transparent overlay, tooltip, or iframe | | **Detection** | `document.elementFromPoint(x, y) !== target` | | **Fix** | Wait for overlay to disappear, or use JavaScript `element.click()` | | **Code** | `bridge.py:394-591` - JavaScript click as primary | | **Verified** | - | ### #5: React Synthetic Events | Attribute | Value | |-----------|-------| | **Site** | React applications | | **Symptom** | CDP click doesn't trigger React handler | | **Root Cause** | React uses synthetic events that don't respond to CDP events | | **Detection** | Site uses React (check for `__reactFiber$` or `data-reactroot`) | | **Fix** | Use JavaScript `element.click()` as primary method | | **Code** | `bridge.py:394-591` - JavaScript-first click | | **Verified** | - | ### #6: Shadow DOM Elements | Attribute | Value | |-----------|-------| | **Site** | Components using Shadow DOM, Lit elements | | **Symptom** | `querySelector` can't find element | | **Root Cause** | Element is inside a shadow root, not main DOM tree | | **Detection** | `element.shadowRoot !== null` on parent elements | | **Fix** | Use piercing selector (`host >>> target`) or traverse shadow roots | | **Code** | See SKILL.md P6 pattern | | **Verified** | 2026-04-03 ✓ | --- ## Input Issues ### #7: ContentEditable / Rich Text Editors | Attribute | Value | |-----------|-------| | **Site** | Rich text editors (Notion, Slack web, etc.) | | **Symptom** | `browser_type()` doesn't insert text | | **Root Cause** | Element is `contenteditable`, not an `` or `