Skip to content

[atoms] Report elements a scroller can bring into view as scrollable - #18228

Open
giri256 wants to merge 2 commits into
SeleniumHQ:trunkfrom
giri256:atoms-scrollable-into-view
Open

giri256 wants to merge 2 commits into
SeleniumHQ:trunkfrom
giri256:atoms-scrollable-into-view

Conversation

@giri256

@giri256 giri256 commented Oct 22, 2026 •

Copy link
Copy Markdown

🔗 Related Issues

Reported against ChromeDriver as https://issues.chromium.org/issues/42321530 (Get Element Text returns an empty string for one row of a table). There is no Selenium issue for it yet.

💥 What does this PR do?

bot.dom.getOverflowState() returns HIDDEN when an overflow:hidden ancestor clips the element, even when a scroll container between the element and that ancestor can scroll the element into view. This happens when the scroll container is taller (or wider) than the overflow:hidden ancestor, which is common in GWT-style layouts:

<div style="overflow:hidden; height:100px">
  <div style="overflow:auto; height:150px">   <!-- taller than its clipping parent -->
    ...
    <td>15</td>   <!-- below 100px but above 150px: reported HIDDEN -->
    ...
    <td>16</td>   <!-- below 150px: overflows the scroller, reported SCROLL -->
  </div>
</div>

Elements in the band that the outer div clips but the scroll container does not are reported as HIDDEN, so isDisplayed() is false and getText() returns "". Elements further down overflow the scroll container itself, are reported as SCROLL and keep their text. With the page attached to the Chromium bug, ChromeDriver returns text for rows 1-14 and 16-33 of a table and "" for row 15.

With this change, when an overflow:hidden ancestor clips the element, getOverflowState() returns SCROLL if a scroll container between the two can still scroll in the needed direction (forward for elements past the right/bottom edge, backward for elements before the left/top edge) and is not hidden itself. Otherwise it still returns HIDDEN.

🔧 Implementation Notes

  • While walking up the overflow parents, the containers that the element does not overflow and whose overflow-x/overflow-y is auto or scroll are remembered per axis, closest first. When an overflow:hidden container hides the element, the closest remembered scroller on each hidden axis that can still scroll in the needed direction decides the result. If that scroller is itself HIDDEN, the element stays HIDDEN.
  • A scroller whose content fits (or that is already scrolled to the end) does not count, so elements that no scrolling can reveal stay HIDDEN.
  • Alternative considered: only fixing getVisibleText. Rejected because isShown() has the same false negative, and the W3C Get Element Text and Is Element Displayed definitions both go through this function.

Tests: three new tests in javascript/atoms/test/overflow_test.html. They cover vertical and horizontal scrollers, a scroller that is already scrolled down, a scroller that cannot scroll, and a scroller that is itself hidden. I ran the atom test pages in headless Chrome 156 with a small harness that serves the tree the way the Bazel test server does (/filez/_main/), not through Bazel:

  • Without the fix, overflow_test.html fails the 2 new positive tests (Expected: "scroll", Actual: "hidden"); with the fix, all 26 tests pass.
  • The other atom test pages give the same results with and without the fix. shown_test, text_test, text_shadow_test, scrolling_test, click_test, clientrect_test, frame_scroll_test, interactable_size_test and window_scroll_into_view_test pass. The *_typescript_test pages need Bazel's TypeScript output and were not run.

Chromium carries the same change in third_party/selenium-atoms/patch.diff with regenerated atoms and a ChromeDriver test: https://chromium-review.googlesource.com/c/chromium/src/+/8635549. There, the Chromium bug's page returns text for all 33 rows.

🤖 AI assistance

  • No substantial AI assistance used
  • AI assisted (complete below)
    • Tool(s): Claude Code (Claude Opus 5.5)
    • What was generated: the dom.js change, the tests, the commit message and this description. The PR was opened by the agent on the account owner's instruction.
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

None known. Chromium will drop its copy of the change from patch.diff once it updates the atoms to a Selenium revision that includes this.

🔄 Types of changes

  • Bug fix (backwards compatible)

bot.dom.getOverflowState() returns HIDDEN when an overflow:hidden
ancestor clips the element, even when a scroll container between the
element and that ancestor can scroll the element into view. This
happens when the scroll container is taller (or wider) than the
ancestor: elements in the band that the ancestor clips but the scroll
container does not are reported as HIDDEN, so isDisplayed() returns
false and getText() returns an empty string for them, while elements
further down overflow the scroll container itself and are reported as
SCROLL.

When an overflow:hidden ancestor clips the element, now return SCROLL
if a scroll container between them can still scroll in the needed
direction and is not hidden itself.

Reported against ChromeDriver as
https://issues.chromium.org/issues/42321530
@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@selenium-ci selenium-ci added the B-atoms JavaScript chunks generated by Google closure label Oct 22, 2026
@CLAassistant

CLAassistant commented Oct 22, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

This branch has not been deployed

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

Labels

B-atoms JavaScript chunks generated by Google closure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants