How to handle frames, nested frames in PLaywright Java
Things to notice
Unlike in Selenium, We don’t have to switch to frame and return to main page again.
We just capture the frame, and using it as a reference, capture the element or nested frame inside of it like a chain.
Warning
Belowis the old way, so don’t use it. Instead of that use frameLocator.
Frame frame = page.frame("//iframe[@id='mce_0_ifr']");
Instead of that use frameLocator.
FrameLocator firstFrame= page.frameLocator("//iframe[@id='firstFr']");
There are two types of elements in frames
Elements within one frame.
Elements within multiple/nested frames.
Elements within one frame.
First identify and store the frame using FrameLocator to a vatiable called myFrame and using relevant to it, locate the element that inside of the frame.
FrameLocator myFrame= page.frameLocator("//iframe[@id='mce_0_ifr']");
// Then related to the frame write the locator of element that I want to interact.
Locator textFieldBody= myFrame.locator("//body[@id='tinymce']");
textFieldBody.type("Typed inside of the text field of Imframe");
Also without declaring a frame variable you can directly define the locator for the same element like below.
Locator textFieldBodyDirect=page.frameLocator("//iframe[@id='mce_0_ifr']").locator("//body[@id='tinymce']");
textFieldBodyDirect.type("Handle the element in the frame in one go");
Elements within multiple/nested frames.
First we have to locate the first frame.
FrameLocator firstFrame= page.frameLocator("//iframe[@id='firstFr']");
Then capture the frame that inside of above captured frame.
FrameLocator nestedSecondFrame= firstFrame.frameLocator("//iframe[@class='has-background-white']");
Then using second frame nestedSecondFrame, related to that we can capture the email element inside of it.
Locator emailInsideOfTwoFrames=nestedSecondFrame.locator("//input[@name='email']");
emailInsideOfTwoFrames.type("johndoe@yahoo.co.uk");
Offical documentation
This is a good tutorial too
Full code is as per below.
package com.sam.scripts;
import com.microsoft.playwright.*;
import org.testng.annotations.Test;
import java.util.List;
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
/* References
https://playwright.dev/java/docs/frames
https://www.youtube.com/watch?v=EWI5E0ito5A&list=PLZMWkkQEwOPliOm7TkV0Ndg45cJPDthDC&index=7&ab_channel=LambdaTest
We don't have to switch to frame and return to main page again.
*/
public class FramesExample {
@Test
public void firstTest() throws InterruptedException {
Playwright playwright = Playwright.create();
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
// This line creates a new page object within the browser instance. The page object represents a single web page that can be navigated, interacted with, and tested.(It's kind of tab but exactly a tab.)
Page page = browser.newPage();
// This code instructs the page object to navigate to the specified URL
page.navigate("https://the-internet.herokuapp.com/");
System.out.println(page.title());
assertThat(page).hasTitle("The Internet");
// Wait for the element to be available Wait are optional.
page.waitForSelector("//a[contains(@href, '/frames')]");
// Click the element
page.click("//a[contains(@href, '/frames')]");
// How to handle a single frame and interact with an element within it.
// Go to Iframe example
page.click("a[href='/iframe']");
// get all the frames in the page to a list.
List<Frame> frames = page.frames();
System.out.println("No.of frames available: "+frames.size());
// In Playwright we don't have to switch to the frame. we just have to locate the frame.
FrameLocator myFrame= page.frameLocator("//iframe[@id='mce_0_ifr']");
// Then related to the frame write the locator of element that I want to interact.
Locator textFieldBody= myFrame.locator("//body[@id='tinymce']");
textFieldBody.click();
textFieldBody.clear();
textFieldBody.type("Typed inside of the text field of Imframe");
// Or you can define the Locator inside of the frame using frame in one go with just one Locator variable.
Locator textFieldBodyDirect=page.frameLocator("//iframe[@id='mce_0_ifr']").locator("//body[@id='tinymce']");
textFieldBodyDirect.click();
textFieldBodyDirect.clear();
textFieldBodyDirect.type("Handle the element in the frame in one go");
// How to handle Nested frames, frame within a frame.
page.navigate("https://letcode.in/frame");
// There first name and last name are inside of just 1 frame.
// Let's get the First frame to a locator,
FrameLocator firstFrame= page.frameLocator("//iframe[@id='firstFr']");
// Below first name element is inside the frame
Locator firstName= firstFrame.locator("//input[@name='fname']");
firstName.type("Hello First name");
Locator lastName= firstFrame.locator("//input[@name='lname']");
lastName.type("Hello Last name");
// Email field is inside of the above firstFrame
FrameLocator nestedSecondFrame= firstFrame.frameLocator("//iframe[@class='has-background-white']");
// Now let's enter the values at Enter email is in Email fild.
Locator emailInsideOfTwoFrames=nestedSecondFrame.locator("//input[@name='email']");
emailInsideOfTwoFrames.type("johndoe@yahoo.co.uk");
// optional codes to get an idea about frame content of the page.
List<Frame> multipleFrames = page.frames();
System.out.println("No.of frames available: "+multipleFrames.size());
// Print all the URLS of frame
multipleFrames.forEach(frame -> System.out.println(frame.url()));
/* every iframe element has a unique URL. The URL of an iframe element is the URL of the page that is embedded in the iframe.
Example <iframe src="https://www.google.com"></iframe> in Facebook page we can add a link to google.
url means src value of iframe
The src value is the attribute that specifies the URL
<iframe _ngcontent-serverapp-c66="" src="frameUI" id="firstFr" name="firstFr"></iframe>
*/
Thread.sleep(24000);
// Frame frame is old way don't use it Frame frame = page.frame("//iframe[@id='mce_0_ifr']");
page.close();
// Closes the browser window(s) associated with the browser instance.
browser.close();
// playwright.close() command is used to close the page that is currently open in the Chromium browse
playwright.close();
}
}