Skip to content

Commit 9ecb529

Browse files
authored
Merge pull request #3875 from seleniumbase/handling-invisible-iframes
Handling invisible iframes
2 parents 539d412 + 63302f3 commit 9ecb529

File tree

6 files changed

+23
-10
lines changed

6 files changed

+23
-10
lines changed

help_docs/method_summary.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ self.set_window_position(x, y)
161161
self.maximize_window()
162162
self.minimize_window()
163163
self.reset_window_size()
164-
self.switch_to_frame(frame="iframe", timeout=None)
164+
self.switch_to_frame(frame="iframe", timeout=None, invisible=False)
165165
self.switch_to_default_content()
166166
self.switch_to_parent_frame()
167167
with self.frame_switch(frame, timeout=None):

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ setuptools~=70.2;python_version<"3.10"
55
setuptools>=80.9.0;python_version>="3.10"
66
wheel>=0.45.1
77
attrs>=25.3.0
8-
certifi>=2025.6.15
8+
certifi>=2025.7.9
99
exceptiongroup>=1.3.0
1010
websockets~=13.1;python_version<"3.9"
1111
websockets>=15.0.1;python_version>="3.9"

seleniumbase/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "4.40.2"
2+
__version__ = "4.40.3"

seleniumbase/fixtures/base_case.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3591,15 +3591,16 @@ def reset_window_size(self):
35913591
self.set_window_rect(x, y, width, height)
35923592
self.__demo_mode_pause_if_active(tiny=True)
35933593

3594-
def switch_to_frame(self, frame="iframe", timeout=None):
3594+
def switch_to_frame(self, frame="iframe", timeout=None, invisible=False):
35953595
"""Wait for an iframe to appear, and switch to it. This should be
35963596
usable as a drop-in replacement for driver.switch_to.frame().
35973597
The iframe identifier can be a selector, an index, an id, a name,
35983598
or a web element, but scrolling to the iframe first will only occur
35993599
for visible iframes with a string selector.
36003600
@Params
36013601
frame - the frame element, name, id, index, or selector
3602-
timeout - the time to wait for the alert in seconds """
3602+
timeout - the time to wait for the alert in seconds
3603+
invisible - if True, the iframe can be invisible """
36033604
self.__check_scope()
36043605
if not timeout:
36053606
timeout = settings.LARGE_TIMEOUT
@@ -3649,7 +3650,9 @@ def switch_to_frame(self, frame="iframe", timeout=None):
36493650
time.sleep(0.035)
36503651
if self.undetectable:
36513652
time.sleep(0.035)
3652-
page_actions.switch_to_frame(self.driver, frame, timeout)
3653+
page_actions.switch_to_frame(
3654+
self.driver, frame, timeout, invisible=invisible
3655+
)
36533656
self.wait_for_ready_state_complete()
36543657
if self.__needs_minimum_wait():
36553658
time.sleep(0.015)

seleniumbase/fixtures/page_actions.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,14 +1572,17 @@ def wait_for_and_switch_to_alert(driver, timeout=settings.LARGE_TIMEOUT):
15721572
timeout_exception(Exception, message)
15731573

15741574

1575-
def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT):
1575+
def switch_to_frame(
1576+
driver, frame, timeout=settings.SMALL_TIMEOUT, invisible=False
1577+
):
15761578
"""
15771579
Wait for an iframe to appear, and switch to it. This should be
15781580
usable as a drop-in replacement for driver.switch_to.frame().
15791581
@Params
15801582
driver - the webdriver object (required)
15811583
frame - the frame element, name, id, index, or selector
15821584
timeout - the time to wait for the alert in seconds
1585+
invisible - if True, the iframe can be invisible
15831586
"""
15841587
_reconnect_if_disconnected(driver)
15851588
start_ms = time.time() * 1000.0
@@ -1596,7 +1599,10 @@ def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT):
15961599
by = "xpath"
15971600
else:
15981601
by = "css selector"
1599-
if is_element_visible(driver, frame, by=by):
1602+
if (
1603+
is_element_visible(driver, frame, by=by)
1604+
or (invisible and is_element_present(driver, frame, by=by))
1605+
):
16001606
with suppress(Exception):
16011607
element = driver.find_element(by=by, value=frame)
16021608
driver.switch_to.frame(element)
@@ -1608,8 +1614,12 @@ def switch_to_frame(driver, frame, timeout=settings.SMALL_TIMEOUT):
16081614
plural = "s"
16091615
if timeout == 1:
16101616
plural = ""
1611-
message = "Frame {%s} was not visible after %s second%s!" % (
1617+
presence = "visible"
1618+
if invisible:
1619+
presence = "present"
1620+
message = "Frame {%s} was not %s after %s second%s!" % (
16121621
frame,
1622+
presence,
16131623
timeout,
16141624
plural,
16151625
)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@
153153
'setuptools>=80.9.0;python_version>="3.10"',
154154
'wheel>=0.45.1',
155155
'attrs>=25.3.0',
156-
"certifi>=2025.6.15",
156+
"certifi>=2025.7.9",
157157
"exceptiongroup>=1.3.0",
158158
'websockets~=13.1;python_version<"3.9"',
159159
'websockets>=15.0.1;python_version>="3.9"',

0 commit comments

Comments
 (0)