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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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