[BUG]: `page.goto: Page closed` with mobile webkit
Context:
- GOOD Playwright Version: 1.37.1
- BAD Playwright Version: 1.39.0
- Operating System: Linux (Mint 20.3 locally, Ubuntu on GH Actions)
- Extra: Node v18.15.0
Code Snippet
This is my config file:
import { defineConfig, devices } from "@playwright/test";
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
timeout: 7500,
testDir: "./src/test/e2e",
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 10 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: "http://localhost:8888",
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
},
/* Configure projects for major browsers */
projects: [
{
name: "chromium",
testIgnore: /.*\.mobile.spec.ts/,
use: { ...devices["Desktop Chrome"] },
},
{
name: "firefox",
testIgnore: /.*\.mobile.spec.ts/,
use: { ...devices["Desktop Firefox"] },
},
{
name: "webkit",
testIgnore: /.*\.mobile.spec.ts/,
use: { ...devices["Desktop Safari"] },
},
/* Test against mobile viewports. */
{
name: "Mobile Chrome",
testMatch: /.*\.mobile.spec.ts/,
use: { ...devices["Pixel 5"] },
},
{
name: "Mobile Safari",
testMatch: /.*\.mobile.spec.ts/,
use: { ...devices["iPhone 12"] },
},
/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],
/* Run your local dev server before starting the tests */
webServer: {
command: "npm run start",
url: "http://localhost:8888",
reuseExistingServer: !process.env.CI,
},
});
This is the now failing, stand alone test:
import { test, expect } from "@playwright/test";
test.describe("Intro", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/"); // <--- errors here
});
test("is not visible", async ({ page }) => {
await expect(page.getByTestId("deskIntro")).toBeHidden();
});
});
Describe the bug
The test above used to run and pass fine on 1.37.1. Now with 1.39.0, it fails:
page.goto: Page closed
=========================== logs ===========================
navigating to "http://localhost:8888/", waiting until "load"
============================================================
This happens both locally and on GH Actions.
Locally, if I curl or load localhost:8888 I'm getting a response and the website without any issues. It's only Playwright that seemingly can't get to it.
I've also tried to remove the beforeEach and put the goto directly in the test case, with the same result.
If I look in the "Network" tab of the Playwright UI, I can see the requests and HTTP 200 responses but the screenshots are white and empty. If I try to goto http://google.com, I can see the page loading.
If I use mobile Chrome, the same test passes without issues. Only mobile Webkit fails.
If I rerun the test enough times, it will pass. It roughly passes once every 6--10 runs using npx playwright test --project 'Mobile Safari' --reporter dot
Did you run npx playwright install --with-deps after you updated Playwright? Can you try to run it with DEBUG=pw:browser npx playwright test env var? This should yield more output in case of a browser crash.
Would it be possible to share the website which you are navigating to? This plays most likely an important part in finding out why WebKit is crashing/closing.
--with-deps doesn't change anything.
This is the debug output:
$ DEBUG=pw:browser npx playwright test --project 'Mobile Safari' --reporter dot
Running 1 test using 1 worker
pw:browser <launching> /home/pierre/.cache/ms-playwright/webkit-1921/pw_run.sh --inspector-pipe --headless --no-startup-window +0ms
pw:browser <launched> pid=322863 +6ms
pw:browser [pid=322863][err] +358ms
pw:browser [pid=322863][err] (MiniBrowser:322869): GStreamer-WARNING **: 11:42:35.559: External plugin loader failed. This most likely means that the plugin loader helper binary was not found or could not be run. You might need to set the GST_PLUGIN_SCANNER environment variable if your setup is unusual. This should normally not be required though. +0ms
pw:browser [pid=322863][err] +1ms
pw:browser [pid=322863][err] (MiniBrowser:322869): GStreamer-WARNING **: 11:42:35.561: Failed to load plugin '/home/pierre/.cache/ms-playwright/webkit-1921/minibrowser-wpe/sys/lib/gst/libgstwpe.so': libWPEWebKit-1.0.so.3: cannot open shared object file: No such file or directory +0ms
pw:browser [pid=322863][err] +2ms
pw:browser [pid=322863][err] (MiniBrowser:322869): GStreamer-WARNING **: 11:42:35.563: Failed to load plugin '/home/pierre/.cache/ms-playwright/webkit-1921/minibrowser-wpe/sys/lib/gst/libgstfdkaac.so': libfdk-aac.so.1: cannot open shared object file: No such file or directory +0ms
pw:browser [pid=322863][err] +8s
pw:browser [pid=322863][err] (MiniBrowser:322869): GLib-GIO-CRITICAL **: 11:42:43.588: g_application_quit: assertion 'G_IS_APPLICATION (application)' failed +0ms
pw:browser [pid=322863] <gracefully close start> +7ms
pw:browser [pid=322863] <process did exit: exitCode=0, signal=null> +17ms
pw:browser [pid=322863] starting temporary directories cleanup +0ms
pw:browser [pid=322863] finished temporary directories cleanup +1ms
pw:browser [pid=322863] <gracefully close end> +0ms
This is the website that's being tested: https://deploy-preview-54--rav-tools.netlify.app/
I can reproduce it in our docker image, the following test passes in --headed mode and times out in headless:
import { test, expect } from "@playwright/test";
test("is not visible", async ({ page }) => {
await page.goto('https://deploy-preview-54--rav-tools.netlify.app', {waitUntil: 'domcontentloaded' });
});
@coaxial did something change on the page? I cannot reproduce the bug any more, the page is not hanging. A few days ago I saw it was loading some .mp4 files and now it does not, I suspect that the issue has something to do with those mp4's.
It shouldn't have, it's a preview deploy of a branch that was merged a while back. Last deploy was on 2023-10-20.
I have no code that loads mp4 files though. Netlify adds some code to the deploy to show their little banner at the bottom, but when running in CI/CD it doesn't have that and hung anyway.
I'll try and take the code as it was then, generate the site, and put it up on a separate Netlify (not a preview deploy) so that it doesn't have all the Netlify stuff added. This should be pretty close to what playwright is testing when running locally.
@yury-s It's deployed here: https://65427d7503b5b91f4055e520--remarkable-cranachan-7e0265.netlify.app/
@yury-s It's deployed here: https://65427d7503b5b91f4055e520--remarkable-cranachan-7e0265.netlify.app/
Cannot reproduce it with this deployment, it loads just fine in 1.39 playwright. Are you still able to reproduce it?
If it is still reproducible with the same output, can you try installing libfdk-aac1 and see if it helps?
I tried with this test:
import { test, expect } from "@playwright/test";
test.describe("Safari Mobile crash", async () => {
test.beforeEach(async ({ page }) => {
await page.goto("https://remarkable-cranachan-7e0265.netlify.app");
});
test("is not visible", async ({ page }) => {
await expect(page.locator("#EndDateCalculator > div:nth-child(1) > div:nth-child(4)")).toBeHidden();
});
});
Using that browser:
{
name: "Mobile Safari",
testMatch: /.*\.mobile.spec.ts/,
use: { ...devices["iPhone 12"] },
},
And I could reproduce. If I used your snippet (no beforeEach, waitUntil, etc) then it didn't crash. If I used the test above but installed libfdk-aac1, then it would also work. I'm not sure why that lib makes a difference since there are no multimedia resources loaded on this page.
This is what loads in the Playwright UI:
Even weirder, this test should pass, but instead I get the same page closed error on Safari Mobile and with libfdk-aac1 installed:
import { test, expect } from "@playwright/test";
test.describe("Safari Mobile crash", async () => {
test.beforeEach(async ({ page }) => {
await page.goto("https://remarkable-cranachan-7e0265.netlify.app");
});
test("is not visible", async ({ page }) => {
await expect(page.locator("#EndDateCalculator > .errorContainer")).toBeHidden();
});
});
Yeah, can reproduce it too, here is a reduced test:
import { test, expect } from '@playwright/test';
test.use({
viewport: { width: 390, height: 664 },
isMobile: true,
browserName: 'webkit'
});
test('example', async ({ page }) => {
console.log('start loading');
await page.goto('https://remarkable-cranachan-7e0265.netlify.app', { waitUntil: 'domcontentloaded' });
console.log('done loading');
});
No load or domcontentloaded events are fired when a small mobile viewport is set. Works fine in headed mode.
@coaxial any chance you can share the source of the page? I've been debugging what's going but to no avail so far. My hunch it has something to do with how /_astro/footer.e57d8ce4.js script load is triggered and being able to see the source would help. Or perhaps you can reduce the test case and share the source code? I'll keep debugging with the page you have running for now.
Thanks for looking into it.
The code for footer.js is very short (it's the same as the file that is served):
document.getElementById("footer__year").innerText = new Date().getFullYear();
It is imported at the bottom of the HTML, like so:
<div class="mt-20 border-t">
<!-- The HTML for the footer -->
</div>
<script>
import "../scripts/footer.js";
</script>
Astro then does its thing and bundles it all up when built for prod.
I'm sorry I can't share the whole repo as it's private, but maybe this helps? Available for anything you might need to troubleshoot this.
it happens for MACs : replace localhost with 127.0.0.1
if it helps - add to /etc/hosts
127.0.0.1 yourMaclocalHostname
::1 yourMaclocalHostname
it happens for MACs : replace
localhostwith127.0.0.1if it helps - add to /etc/hosts127.0.0.1 yourMaclocalHostname ::1 yourMaclocalHostname
Are you sure this comment is supposed to be on this issue?
This is still an issue, to me it boiled down to PW 1.39 using Webkit 17.4 on Ubuntu 22.04 (also 20.04) and Node 20.9. supposedly caused by the resizing functions non managing to resize the Webkit browser in headless mode (ref: https://bugs.webkit.org/show_bug.cgi?id=238513)
Here is the reduced repro: https://github.com/yury-s/bug-27701. The test hangs with viewport width: 448 and passes with width: 449.
can we please reopen this? this is still an issue
Related issue https://github.com/microsoft/playwright/issues/8340
When executing it with npx playwright test --repeat-each 100 only 16/100 pass for me with 1.37.1 (1.25 as well). Looks like its not a regression and its just more racy with recent versions.
I have a similar problem and it is still reproducing. https://github.com/microsoft/playwright/issues/28801
I am also encountering this bug. The load event never triggers and the browser just hangs with a white page. All other browsers run fine. Interestingly, this doesn't seem to be universal and is test specific. I believe it only occurs when images are loaded on my page. Tests that hit pages without images don't have any problems loading the page.