Version
1.60.0
Steps to reproduce
- Run following code with on version
1.58.2
- Update to
1.59.0 (up to 1.61.1) and run the tests again
import { expect, test } from "@playwright/test";
test("masked screenshot with global backdrop styling", async ({ page }) => {
await page.setContent(`
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Playwright Mask Backdrop Repro</title>
<style>
html,
body {
margin: 0;
padding: 0;
}
body {
background: #ffffff;
font-family: sans-serif;
}
main[role="main"] {
width: 420px;
height: 280px;
background: rgb(243, 243, 243);
border: 1px solid rgb(180, 180, 180);
position: relative;
box-sizing: border-box;
overflow: hidden;
}
h1 {
margin: 12px;
font-size: 18px;
}
p {
margin: 12px;
}
#probe {
position: absolute;
top: 70px;
left: 12px;
width: 180px;
height: 42px;
box-sizing: border-box;
border: 3px solid rgb(0, 102, 204);
background: rgb(255, 255, 255);
color: rgb(0, 0, 0);
font-size: 16px;
padding: 6px 8px;
}
#secret {
position: absolute;
top: 140px;
left: 155px;
width: 80px;
height: 80px;
background: rgb(30, 30, 30);
}
/* Intentionally broad backdrop style to trigger interaction with popover-backed overlays. */
::backdrop,
::-webkit-backdrop {
background: rgba(0, 0, 0, 0.35);
}
</style>
</head>
<body>
<main role="main">
<h1>Mask + Backdrop Repro</h1>
<p>Blue bordered input should stay visually unchanged when applying mask.</p>
<input id="probe" value="UNMASKED AREA" readonly />
<div id="secret" aria-label="masked-target"></div>
</main>
</body>
</html>
`);
const container = page.getByRole("main");
const masked = page.locator("#secret");
await expect(masked).toBeVisible();
await expect(container).toHaveScreenshot("repro-no-mask.png");
await expect(container).toHaveScreenshot("repro-with-mask.png", {
mask: [masked],
});
});
Expected behavior
- The tests do pass
- In visual comparison - the area around masked element is not grayed out
Actual behavior
- The tests fail
- The whole viewport has the gray overlay
Sample from test report:
Additional context
Initially, an update to 1.60.0 from 1.58.2 was made, but then the actual breaking change was observed when updating from 1.58.2 to 1.59.0.
As a workaround, the following code fixed the issue:
await page.evaluate(() => {
const cspMeta = document
.querySelector("meta[http-equiv='Content-Security-Policy']")
?.getAttribute("content");
const cspNonce = cspMeta?.match(/'nonce-([^']+)'/)?.[1];
const styleNonce =
cspNonce ??
document.querySelector("script[nonce], style[nonce]")?.getAttribute("nonce");
const style = document.createElement("style");
if (styleNonce) style.setAttribute("nonce", styleNonce);
style.textContent = `
x-pw-glass::backdrop,
x-pw-glass::-webkit-backdrop {
background: transparent !important;
opacity: 0 !important;
}
`;
document.head.appendChild(style);
});
Environment
System:
OS: Windows 11 10.0.26100
CPU: (22) x64 Intel(R) Core(TM) Ultra 7 165H
Memory: 32.44 GB / 63.45 GB
Binaries:
Node: 24.13.0 - C:\Program Files\nodejs\node.EXE
npm: 11.9.0 - C:\Program Files\nodejs\npm.CMD
IDEs:
VSCode: 1.126.0 - C:\Users\REDACTED\AppData\Local\Programs\Microsoft VS Code\bin\code.CMD
Languages:
Bash: 5.2.21 - C:\WINDOWS\system32\bash.EXE
npmPackages:
@playwright/test: ^1.59.1 => 1.59.1
Version
1.60.0
Steps to reproduce
1.58.21.59.0(up to1.61.1) and run the tests againExpected behavior
Actual behavior
Sample from test report:
Additional context
Initially, an update to
1.60.0from1.58.2was made, but then the actual breaking change was observed when updating from1.58.2to1.59.0.As a workaround, the following code fixed the issue:
Environment
System: OS: Windows 11 10.0.26100 CPU: (22) x64 Intel(R) Core(TM) Ultra 7 165H Memory: 32.44 GB / 63.45 GB Binaries: Node: 24.13.0 - C:\Program Files\nodejs\node.EXE npm: 11.9.0 - C:\Program Files\nodejs\npm.CMD IDEs: VSCode: 1.126.0 - C:\Users\REDACTED\AppData\Local\Programs\Microsoft VS Code\bin\code.CMD Languages: Bash: 5.2.21 - C:\WINDOWS\system32\bash.EXE npmPackages: @playwright/test: ^1.59.1 => 1.59.1