Have considered adding an IFrame context manager? #1407
Replies: 3 comments 2 replies
-
There are a few ways to achieve this within BaseCase: New method for the context manager: (Can't use the old method name without breaking backwards compatibility.) from contextlib import contextmanager
@contextmanager
def cm_switch_to_frame(self, frame, timeout=None):
self.switch_to_frame(frame, timeout=timeout)
yield
self.switch_to_parent_frame() New class: class Frame(object):
def __init__(self, sb, frame, timeout=None):
self.sb = sb
self.frame = frame
self.timeout = timeout
def __enter__(self):
self.sb.switch_to_frame(self.frame, timeout=self.timeout)
def __exit__(self, type, value, traceback):
self.sb.switch_to_parent_frame() Here's an example test that combines both ways: from seleniumbase import BaseCase
class FrameTests(BaseCase):
def test_iframe_basics(self):
self.open("https://seleniumbase.io/w3schools/iframes.html")
with self.Frame(self, "iframeResult"):
self.assert_text("HTML Iframes", "h2")
with self.cm_switch_to_frame('[title*="Iframe"]'):
self.assert_text("This page is displayed in an iframe", "h1")
self.assert_text("Use CSS width & height to specify", "p")
with self.cm_switch_to_frame('[title*="Iframe"]'):
self.assert_text("seleniumbase.io/w3schools/iframes", "a")
self.click("button#runbtn")
self.switch_to_frame("iframeResult") # Go back inside 1st iframe
self.highlight('iframe[title="Iframe Example"]') I could theoretically implement this if useful. Thoughts? |
Beta Was this translation helpful? Give feedback.
-
I'm currently working on an optimal implementation for this. So far, two possible solutions: from contextlib import contextmanager
@contextmanager
def frame_switch(self, frame, timeout=None):
""" Context Manager for switching into iframes.
Usage example:
with self.frame_switch("iframe"):
# Perform actions here that should be done inside the iframe.
# Automatically calls switch_to_parent_frame() after "with" block.
"""
self.switch_to_frame(frame, timeout=timeout)
yield
self.switch_to_parent_frame()
class FrameSwitch(object):
""" Context Manager for switching into iframes.
Usage example:
with self.FrameSwitch(self, "iframe"):
# Perform actions here that should be done inside the iframe.
# Automatically calls switch_to_parent_frame() after "with" block.
"""
def __init__(self, sb, frame=None, timeout=None):
if not hasattr(sb, "browser"):
message = "Incorrect usage of FrameSwitch()!\n"
message += 'The first argument passed must be the sb "self".\n'
message += "Here's an example of correct usage:\n"
message += ' with self.FrameSwitch(self, "iframe"):\n'
message += " # Perform actions for inside the iframe.\n"
message += " # Automatically exits frame after the block.\n"
raise Exception(message)
if not frame:
raise Exception('Value of "frame" cannot be None!')
self.sb = sb
sb.switch_to_frame(frame, timeout=timeout)
def __enter__(self):
pass # Moving this code to __init__() allows calls without "with".
def __exit__(self, type, value, traceback):
self.sb.switch_to_parent_frame() Here's an example that uses both:
Each of the two solutions have their advantages and disadvantages. The |
Beta Was this translation helpful? Give feedback.
-
Work is complete: https://github.com/seleniumbase/SeleniumBase/releases/tag/v3.5.1 |
Beta Was this translation helpful? Give feedback.
-
I find that I need to call
switch_to_frame()
andswitch_to_default_content()
frequently when THERE are too many iframes.For example:
Have considered adding an IFrame context manager?Help us automatically call
switch_to_default_content()
For example:
Beta Was this translation helpful? Give feedback.
All reactions