[Bug]: Issues with iframes
Version
1.49.0
Steps to reproduce
After upgrade to the newest chromium headless version my tests started to fail when i'm trying to access/make actions on some iframe elements, which isn't the case on the lower versions. I switched one of the click methods to dispatchEvent('click') and i see that this way it's working. I can't provide any specific example reproduction steps besides of mui date picker: https://mui.com/x/react-date-pickers/date-picker/, which is constantly failing in my case.
It's happening for very different locators, so i cannot provide any specific locator methods or actions, which will trigger this behaviour. I would be grateful for help, because that's the thing which is working for us on previous playwright and browser versions, it started to happen when we tried to switch to the newest one.
Channel: 'chromium'
Expected behavior
I expect iframes to work like in previous versions
Actual behavior
Error: Timed out 20000ms waiting for expect(locator).toBeVisible()
Locator: locator('.gldbm-panel__dbmIframe').contentFrame().getByTestId('extras')
Expected: visible
Received: <element(s) not found>
Call log:
- expect.toBeVisible with timeout 20000ms
- waiting for locator('.gldbm-panel__dbmIframe').contentFrame().getByTestId('extras')
Additional context
No response
Environment
System:
OS: macOS 15.1
CPU: (8) arm64 Apple M2
Memory: 99.83 MB / 16.00 GB
Binaries:
Node: 20.12.1 - ~/.nvm/versions/node/v20.12.1/bin/node
npm: 10.5.0 - ~/.nvm/versions/node/v20.12.1/bin/npm
Languages:
Bash: 3.2.57 - /bin/bash
npmPackages:
@playwright/test: ^1.49.0 => 1.49.0
@karolwajs Thank you for the issue! It seems like there is a difference in how new and old headless handle these iframes. However, it's unlikely we can fix the issue without a repro. Anything that shows the problem, even if not consistently, would be a great help.
If you click 'book now', the iframe will be opened (page.frameLocator('.gldbm-panel__dbmIframe')) with the booking engine, every interaction with a calendar (when it's displayed), clicking on dates for example won't be executed properly on v1.49.0 version
@karolwajs Unfortunately, clicking "Booking now" does not open any iframe for me. But even then, guessing the actions that do not work is not something that I'd like to do. Could you please record a short script on that page that does work without channel: 'chromium' and does not work with the channel specified?
'Book now', not 'Booking now'. Every action taken on the opened calendar is not working with channel 'chromium'
Example script:
import date from 'date-and-time';
import { type FrameLocator, type Locator, type Page } from '@playwright/test';
test(
'iFrame Test',
async ({ page }) => {
const startDate = new Date();
const formattedStartDate = date.format(startDate, 'dddd, MMMM D, YYYY');
await page.goto('https://gxpservicesstagestorage.z6.web.core.windows.net');
await page.getByText('Book Now').click();
await page.frameLocator('.gldbm-panel__dbmIframe').locator('#gldbm_startdate').click();
await page.frameLocator('.gldbm-panel__dbmIframe').getByLabel(`Choose ${formattedStartDate} as your check-in date. It’s available.`).click();
});
The last click won't be executed. (code will be executed, but the click won't happen). It will work with .dispatchEvent('click')
When I try to run your script, the site is hanging after I click on "Book Now" - looks like the site doesn't work for me?
It should work now
What do you mean with "click won't happen"? I tried to create a smaller script which shows on the screenshot that the click happens. The screenshot it seems that the "Check in" is updated to the selected date:
import { chromium } from 'playwright';
(async () => {
const browser = await chromium.launch({
channel: 'chromium',
// headless: false,
});
const context = await browser.newContext({
viewport: {
width: 1920,
height: 1080
}
});
const page = await context.newPage();
await page.goto('https://gxpservicesstagestorage.z6.web.core.windows.net');
await page.getByText('Book Now').click();
await page.frameLocator('.gldbm-panel__dbmIframe').locator('#gldbm_startdate').click();
await page.frameLocator('.gldbm-panel__dbmIframe').getByLabel(`Choose Friday, November 29, 2024 as your check-in date. It’s available.`).click();
await page.waitForTimeout(5000)
await page.screenshot({ path: 'screenshot.png' });
console.log('written screenshot');
await browser.close();
})();
When i switched viewport settings to: viewport: { width: 1920, height: 1080 } it seems to work fine, weird that it worked for different viewport settings previously. I have to check rest of the suite, because i believe that i had similar issues with some other components on this page
Investigation, it seems to work when its not embedded as an iframe:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
channel: 'chromium',
});
const context = await browser.newContext({
});
await context.tracing.start({ screenshots: true, snapshots: true, sources: true });
const page = await context.newPage();
await page.goto('https://booking.stage.guestline.app/OBMNG?lng=en-US&panelMode=fullscreen&enableCustomFrameAncestor=true');
await page.locator('#gldbm_startdate').click();
await page.getByLabel(`Choose Friday, November 29, 2024 as your check-in date. It’s available.`).click();
await page.screenshot({ path: 'screenshot.png' });
await context.tracing.stop({ path: 'trace.zip' });
console.log('written screenshot');
await browser.close();
})();
Next is try to find whats breaking it on the main document site
I can confirm that the whole website not embedded is working correctly with new chromium, because we've got tests for it and they're passing and i can assure you that it's not the change on our side, because we are still running daily tests on version 1.48. From my perspective there's an issue with only few components
New version a bit more minimal but still relies on the iframe - please make sure to keep this site running if possible so my colleague can start looking into it.
import { chromium } from 'playwright';
(async () => {
const browser = await chromium.launch({
channel: 'chromium',
// Works in headed + headless_shell
// headless: false,
});
const context = await browser.newContext({});
const page = await context.newPage();
await page.route('https://gxpservicesstagestorage.z6.web.core.windows.net/', route => {
console.log('serving custom index.html')
route.fulfill({
contentType: 'text/html',
body: `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#gldbm-panel__dbmIframe {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
right: 0;
}
</style>
</head>
<body>
<iframe id="gldbm-panel__dbmIframe" src="https://booking.stage.guestline.app/OBMNG?measurementId=G-N3QWQ3RQYX&clientId=1014091106.1732705991&sessionId=1732705990&ts=1732705991494&lng=en-GB&panelMode=fullscreen&enableCustomFrameAncestor=true"></iframe>
</body>
</html>`
})
})
await page.goto('https://gxpservicesstagestorage.z6.web.core.windows.net');
await page.frameLocator('#gldbm-panel__dbmIframe').locator('#gldbm_startdate').click();
// This makes it work
// await page.mouse.wheel(0, 100)
await page.frameLocator('#gldbm-panel__dbmIframe').getByLabel(`Choose Friday, November 29, 2024 as your check-in date. It’s available.`).click();
await page.waitForTimeout(3000)
await page.screenshot({ path: 'screenshot.png'})
// Expected: CHECK-IN29Nov 2024FridayCHECK-OUT
// Actual: CHECK-INCHECK-OUT
console.log(await page.frameLocator('#gldbm-panel__dbmIframe').locator(".MuiGrid-root.MuiGrid-container.MuiGrid-item.MuiGrid-grid-sm-12.css-5zgqq").evaluate((e) => e.textContent))
await browser.close();
})();
Investigation notes:
- scrolling works fine;
- when dispatching the mouse event, it never arrives to the OOPIF;
- passing
args: ['--disable-site-isolation-trials']fixes the issue; - most likely, this upstream line misbehaves.