microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
67.33k stars 3.71k forks source link

[BUG] page.frame({url:iframesrc}) returns null with firefox #29148

Closed mittster closed 10 months ago

mittster commented 10 months ago

System info

Source code

import puppeteer from "playwright";

export async function WaitForTimeout(ms){
    return new Promise(resolve => setTimeout(resolve, ms));
}

let url = "https://laptop.bg/"; // or any other page with cf protection on
var browser = await puppeteer.firefox.launch({
    headless:false,
    ignoreHTTPSErrors: true
});

const page = await browser.newPage();
let response = await page.goto(url, {waitUntil: "domcontentloaded", timeout: 40000});
await WaitForTimeout(6000);

//parsing iframe src
let pageContent = await page.content();
let iframeString = pageContent.substring(pageContent.indexOf("<iframe"), pageContent.indexOf(">",pageContent.indexOf("<iframe"))+1);
let iframeSrc = iframeString.substring(iframeString.indexOf('src="')+5, iframeString.indexOf('"',iframeString.indexOf('src="')+5));
console.log("parsed src: "+iframeSrc+"")

// print all iframe urls on the page, that is main and one child of main
// notice that no url is found for the actual iframe
console.log("all iframe srcs found via frame.url(), only main has src")
let allFrames = page.frames();
for (const singleFrame of allFrames) {
    console.log("url "+singleFrame.url());
}

let iframe = page.frame({url:iframeSrc}); // returns null when firefox is used, but it works with WebKit and Chromium
console.log(iframe);

Steps

Expected

page.frame({url:iframesrc}) is expected to return a Frame object.

Frame objects returned by page.frames() should return an url when by Frame.url() method is call

Actual

page.frame({url:iframesrc}) returns null, even though iframe src is correct. Frame.url() does not return a iframe src url.

This only happens with firefox. I think the iframe used by CF is special, because I was not able to reproduce the issue on this website: https://ui.vision/demo/webtest/frames/

The error may have something to do with the iframe attributes. allow="cross-origin-isolated; fullscreen" is mentioned in other issues, not sure if this is the same problem.

mxschmitt commented 10 months ago

Looks like related to https://github.com/microsoft/playwright/issues/28966 and https://github.com/microsoft/playwright/issues/28082

yury-s commented 10 months ago

The test itself is flaky in a few places, most of the times it prints 'parsed src: <!DO'. Sometimes it finds the frame but sometimes fails apparently due to frame not completely loaded. There is also cloudflare page in between which is shown when the script tries to find the frame. Inserting a delay before page.frame call makes it work in many cases:

await new Promise(resolve => setTimeout(resolve, 2000));
let iframe = page.frame({url:iframeSrc}); // returns null when firefox is used, but it works with WebKit and Chromium

So far it looks like just a flaky test. If you think this is bug in playwright, please provide a reduced repro.

yury-s commented 10 months ago

Closing per the response above, feel free to open a new issue if it doesn't work.