microsoft / microsoft/playwright

[Bug]: expect(locator).toHaveScreenshot({ mask: [locators] }) is affected by page backdrop styles

Open
#41,504 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

P3-collecting-feedback
Dominant language
TypeScript
Stars
96.3k
Forks
6.5k
Avg merge
1d 6h
Merged PRs (30d)
180

Description

### Version

1.60.0

### Steps to reproduce

1. Run following code with on version `1.58.2`
2. Update to `1.59.0` (up to `1.61.1`) and run the tests again

```typescript
import { expect, test } from "@playwright/test";

test("masked screenshot with global backdrop styling", async ({ page }) => {
await page.setContent(`





Playwright Mask Backdrop Repro

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);
}




Mask + Backdrop Repro


Blue bordered input should stay visually unchanged when applying mask.







`);

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

1. The tests do pass
2. In visual comparison - the area around masked element is not grayed out

### Actual behavior

1. The tests fail
2. The whole viewport has the gray overlay

Sample from test report:

Image

### 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:

```ts
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

```shell
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
```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the supplied TypeScript reproduction with Playwright versions 1.58.2 through 1.61.1, focusing on expect(container).toHaveScreenshot() with mask: [masked]. Compare the masked and unmasked screenshots and inspect the x-pw-glass backdrop behavior; done means the masked area is handled without graying the rest of the viewport and the tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.