Handling Iframes using Python and Playwright
Learn how to work with iframes and nested iframes using Microsoft’s automation library.
Inline frames (more commonly known as an iframe) are used for displaying 3rd party content or embedding new pages within the content of a web page. In the world of test automation, iframes can be difficult to work with.
Selenium requires an engineer to use the switch_to
method to change the driver’s focus to the frame itself. Once done performing actions, the driver needs to be re-focused to the main page using switch_to.default_content()
. While this is not a difficult workflow, it certainly can be a hassle to continue switching between frames whenever an action needs to be taken.
Cypress does not natively handle iframes. This is due to the fact that the cy
prefix used in all Cypress commands will traverse the DOM until a #document
has been located. Once located, traversal will end. Custom code (or the cypress-iframe plugin) is required in order to use Cypress with iframes.
Playwright on the other hand, makes working with iframes simple and intuitive. In this tutorial, we will learn how to use Playwright with both conventional iframes and nested iframes. We will use the DemoQA Frames and Nested Frames pages as the focus for our tests.
Getting Started
You will need to install the following packages for this tutorial:
- Pytest
- Playwright
I personally recommend using the pytest-playwright
library as it comes with a bunch of useful fixtures and methods for automated testing, such as screenshot on failure and simplified page creation.
Selector Methods
Playwright provides engineers with three options for selecting iframes:
- element_handle.content_frame()
- page.frame()
- page.frames[i]
Engineers should use page.frame()
when an iframe has a uniquename
or url
attribute. Should an iframe have neither, then the element_handle.content_frame()
method should be used along with a selector for the frame’s parent element.
The page.frames[i]
property should be used in instances where an iframe has no unique attributes or parent element. The property will list all active frames on the page which can be indexed for a specific frame. I would not recommend using this method unless you do not have access to application source code and cannot use the previous two methods.
Focusing on an Iframe
The DemoQA Frames page contains two iframes, one in the center-left of the page and one in the bottom left.
The iframes on the DemoQA Frames page do not have unique url
attributes, nor do they feature name
attributes. We will use the element_handle.content_frame()
method for locating them as they do have unique selectors for their parent elements.
We now have access to the first frame on the page. Playwright assertions can be used with the ElementHandles frame_one
and heading
in order to write Pytest assertions.
Nested Frames
Playwright provides an additional method for selecting frames within existing iframes using the frame.child_frame[i]
property. The property returns a list of all child frames within an iframe on the page. Similar to the page.frames[i]
property, this is useful for when a child iframe does not have a unique name
or url
attribute, or a parent element with a unique locator strategy.
The child iframe on the DemoQA Nested Frames page does not have any unique locator strategies so we must use the frame.child_frame[i]
property in order to select it.
The child iframe contains a body
element and a single p
element with the text “Child Iframe”. We can use this for crafting Playwright assertions in order to build Pytest assertion statements.
Verification
The above tests may be run in your terminal using the following commands (if using pytest-playwright
):
pytest
for a headless runpytest --headful
for headful
If you have chosen not to use the pytest-playwright
library, you can run the tests in a headful state by adding headless=False
when initializing the browser:
browser = {browser_type}.launch(headless=False)
Project Directory
Your directory should resemble the following upon completion of this tutorial:
tests
|__ test_frames.py.gitignore
README.md
requirements.txt
Summary
Playwright allows engineers to write neat and readable test code for finding and taking action against iframes. Unlike Playwright’s competitors within the automation space, engineers do not need to write out custom code or keep track of driver focus when working with inline frame elements.
Jonathan Thompson is a Senior Quality Engineer specializing in test automation. He currently resides in Raleigh, NC with his wife and a Goldendoodle named Winston. You can connect with him on LinkedIn, or follow him on either Twitter (@jacks_elsewhere) or Github (ThompsonJonM).