In this article, we will discuss in detail how we can handle iframes in Playwright. We will look into two examples, one for simple iframe and one for nested iframes. Let’s further deep dive by automating the below scenarios.
Simple Iframe:
1. Go to https://the-internet.herokuapp.com/iframe
2. Write the text ‘Testersdock.com’ within the text editor
3. Validate that the text was inputted correctly
Nested Iframe:
1. Go to https://the-internet.herokuapp.com/nested_frames
2. Validate the texts in all 4 iframes – LEFT, MIDDLE, RIGHT, BOTTOM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import {test, expect} from '@playwright/test' test.describe( 'Example to demonstrate testing of simple and nested iframes in Playwright', () => { test('Simple iframe - Input text in the text editor which is inside an iframe', async ({ page, }) => { await page.goto('http://the-internet.herokuapp.com/iframe') const textarea = await page.frameLocator('#mce_0_ifr').locator('#tinymce') await textarea.fill('Testersdock.com') await expect(textarea).toHaveText('Testersdock.com') }) test('Nested iframe - Assert texts from each iframes', async ({page}) => { await page.goto('https://the-internet.herokuapp.com/nested_frames') const topframe = await page.frameLocator('[name="frame-top"]') const leftframebody = await topframe .frameLocator('[name="frame-left"]') .locator('body') await expect(leftframebody).toHaveText('LEFT') const middleframebody = await topframe .frameLocator('[name="frame-middle"]') .locator('body') await expect(middleframebody).toHaveText('MIDDLE') const rightframebody = await topframe .frameLocator('[name="frame-right"]') .locator('body') await expect(rightframebody).toHaveText('RIGHT') const bottomframebody = await page .frameLocator('[name="frame-bottom"]') .locator('body') await expect(bottomframebody).toHaveText('BOTTOM') }) }) |
1 2 3 4 5 6 7 8 | test('Simple iframe - Input text in the text editor which is inside an iframe', async ({ page, }) => { await page.goto('http://the-internet.herokuapp.com/iframe') const textarea = await page.frameLocator('#mce_0_ifr').locator('#tinymce') await textarea.fill('Testersdock.com') await expect(textarea).toHaveText('Testersdock.com') }) |
await page.goto(‘http://the-internet.herokuapp.com/iframe’) – Opens the webpage on a browser.
const textarea = await page.frameLocator(‘#mce_0_ifr’).locator(‘#tinymce’) – Using frameLocator we are first retrieving the iframe and then using locator we are accessing the text area and saving everything in textarea variable.
await textarea.fill(‘Testersdock.com’) – Using locator.fill we are writing the text Testersdock.com inside the text area.
await expect(textarea).toHaveText(‘Testersdock.com’) – Using the expect assertion, we are asserting the text Testersdock.com.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | test('Nested iframe - Assert texts from each iframes', async ({page}) => { await page.goto('https://the-internet.herokuapp.com/nested_frames') const topframe = await page.frameLocator('[name="frame-top"]') const leftframebody = await topframe .frameLocator('[name="frame-left"]') .locator('body') await expect(leftframebody).toHaveText('LEFT') const middleframebody = await topframe .frameLocator('[name="frame-middle"]') .locator('body') await expect(middleframebody).toHaveText('MIDDLE') const rightframebody = await topframe .frameLocator('[name="frame-right"]') .locator('body') await expect(rightframebody).toHaveText('RIGHT') const bottomframebody = await page .frameLocator('[name="frame-bottom"]') .locator('body') await expect(bottomframebody).toHaveText('BOTTOM') }) |
await page.goto(‘https://the-internet.herokuapp.com/nested_frames’) – Opens the webpage on a browser.
const topframe = await page.frameLocator(‘[name=”frame-top”]’) || const leftframebody = await topframe.frameLocator(‘[name=”frame-left”]’).locator(‘body’) || await expect(leftframebody).toHaveText(‘LEFT’) – To understand this let’s look into the HTML structure of the webpage below.
Now, as yow can see the iframe top is the first iframe (marked by 1) and inside top we have the iframe left (marked by 2). Hence first we have to use await page.frameLocator(‘[name=”frame-top”]’) to go inside iframe top and then again use topframe.frameLocator(‘[name=”frame-left”]’).locator(‘body’) to go inside iframe left. And then finally we are validating the text ‘LEFT’ using await expect(leftframebody).toHaveText(‘LEFT’).
const middleframebody = await topframe.frameLocator(‘[name=”frame-middle”]’).locator(‘body’) || await expect(middleframebody).toHaveText(‘MIDDLE’) – Let’s again go back to our HTML page.
Similarly, the iframe Middle (marked by 3) is also inside iframe top. Hence we are using await topframe.frameLocator(‘[name=”frame-middle”]’).locator(‘body’) to go inside iframe middle. And then we are validating the text ‘MIDDLE’ using await expect(middleframebody).toHaveText(‘MIDDLE’).
const rightframebody = await topframe.frameLocator(‘[name=”frame-right”]’).locator(‘body’) || await expect(rightframebody).toHaveText(‘RIGHT’) – Similarly here also the iframe right (marked by 4) is inside iframe top.
Hence we are using await topframe.frameLocator(‘[name=”frame-right”]’).locator(‘body’) to go inside iframe right. And then we are validating the text ‘RIGHT’ using await expect(rightframebody).toHaveText(‘RIGHT’).
const bottomframebody = await page.frameLocator(‘[name=”frame-bottom”]’).locator(‘body’) || await expect(bottomframebody).toHaveText(‘BOTTOM’) – As we can see the iframe bottom (Marked by 5) is on the same level as iframe top, hence we can directly access the iframe text using await page.frameLocator(‘[name=”frame-bottom”]’).locator(‘body’) and then assert the text ‘BOTTOM’ using await expect(bottomframebody).toHaveText(‘BOTTOM’).
Upon execution, we should see that all tests are getting passed.
Do check out 🙂