In Playwright's page.screenshot, what does the mask option do to the captured image?
answer
- A list of locators, not selectors
- Bounding boxes, filled solid
- Pink by default, overridable
- Nothing is hidden, nothing reflows
- Applied while the image is made
basics
~20 sIt takes locators and paints a solid box over each matching element's bounding box while the image is being taken, pink by default and any CSS color via maskColor. Those pixels never reach the file.
solid answer
~40 s`mask` accepts an array of locators. Every element matched by any of them is covered with a solid rectangle over its bounding box at the moment of capture, so the underlying pixels are never written into the PNG. The default overlay is pink, `#FF00FF`, and `maskColor` takes any CSS color string if that clashes with the page. The same option exists on `locator.screenshot()`. Two properties matter: the page is not modified -- nothing is hidden, so layout does not reflow and the boxes sit exactly where the content was -- and masking happens during capture, not as an edit afterwards, so there is no window in which a file holds the raw pixels. A locator matching several elements masks all of them; a locator matching nothing masks nothing and does not fail.
code
typescript · 11 linesimport { test } from '@playwright/test';
test('order tracker capture', async ({ page }, testInfo) => {
await page.goto('/orders/8842');
await page.screenshot({
path: testInfo.outputPath('tracker.png'),
fullPage: true,
mask: [page.getByTestId('customer-address'), page.getByTestId('driver-phone')],
maskColor: '#1f2933',
});
});go deeper
Recall that mask takes an array of locators and paints a solid box, pink by default, over each matched element's bounding box in the captured image.
Explain that the page is untouched, so nothing reflows, and that masking happens during capture rather than as a later edit, so the covered pixels never reach the file.
Weigh what a mask costs you in diagnostic value, keep the locator list maintained, and remember that other captures of the same page carry no mask of their own.
Own the standard for which regions of an application are masked by default and how that convention survives page redesigns without depending on each author remembering it.
## What the option takes `mask` is a list of **locators**, not selectors or coordinates: ```ts await page.screenshot({ path: test.info().outputPath('tracker.png'), fullPage: true, mask: [ page.getByTestId('customer-address'), page.getByTestId('driver-phone'), ], maskColor: '#1f2933', }); ``` Because they are locators, they are resolved at capture time against the live page, which means a mask keeps working when the element moves, and covers however many elements the locator matches. ## What actually appears in the image - Each matched element's **bounding box** is filled with a solid rectangle. - The default fill is pink, `#FF00FF`, chosen to be unmistakable in a report. - `maskColor` accepts any CSS color string, useful when a page is already magenta-heavy or when a reviewer needs the box to read as deliberate rather than as a rendering bug. - The box is the bounding box, so an irregular shape is covered by the rectangle that encloses it, and a masked inline element may cover a little more than its glyphs. ## The page is not modified This is the property people most often get wrong. Masking does not hide, remove or restyle anything: - the element still exists and still occupies its space, so nothing reflows; - the box lands exactly where the content was, keeping the screenshot's layout honest; - subsequent actions in the test are unaffected, because nothing was changed to take the picture. Contrast that with the usual home-grown approach of setting `visibility: hidden` before a capture, which changes what you are photographing and leaves the page in a state the next assertion has to undo. ## Masking happens at capture, not afterwards The overlay is composed while the image is produced, so the covered pixels are never encoded into the file. There is no intermediate artefact holding the raw content and no post-processing step that can be skipped, fail, or run too late. For any capture that might frame customer detail on an order tracker -- delivery address, phone number, the map pin outside the customer's door -- that ordering is the whole value of the option. | Approach | Raw pixels ever on disk | Layout disturbed | Fails open | |---|---|---|---| | `mask` at capture | no | no | no: an unmatched locator simply masks nothing | | CSS hiding before capture | no | yes, content reflows | yes, if the style is not applied | | Editing the PNG afterwards | yes, until edited | no | yes, if the step is skipped | ## Limits worth stating 1. A locator that matches nothing masks nothing, silently. A mask list is only as good as its locators, so treat them like any other selector you must maintain. 2. Only what the frame contains can be masked; content that scrolls into view later in a video, or a value visible in a page's own text elsewhere, is untouched. 3. The overlay is opaque, so anything the box covers is unavailable for diagnosis too -- masking the entire status panel to hide one field costs you the evidence. 4. Deciding *what* must never be captured, and how long captures may be retained, is a policy question; `mask` is only the mechanism that enforces one decision at capture time. ## Where it fits Use it on the captures you take deliberately: an element or page screenshot in a test, where you already know which region carries content that should not be in an artefact reviewers pass around. Keep the mask list next to the capture so a reader can see, in one place, what the image is missing and why.
- A mask locator matches three elements on the order tracker. What gets covered?All three. Each match is covered by a box over its own bounding box, so a locator such as one matching every phone-number cell masks the whole set. Nothing warns you if it matches none, which is the failure mode to guard against with a quick assertion on the locator's count.
- Does mask stop the same value reaching other artefacts of the run?No. It applies to the capture that carries the option, so a video of the same page, another screenshot without the mask, or the page's own text recorded elsewhere still show the value. It is a per-capture mechanism, not a run-wide filter.
It is the marker held over a document as it goes through the scanner, not a redaction pen taken to the printed copy afterwards.
saying these in an interview costs you the question
- Thinks mask hides the element so the layout reflows
- Believes the overlay is blurred rather than solid
- Assumes the pink box colour cannot be changed
- Expects an unmatched mask locator to fail the capture
- Thinks one mask covers videos and other captures too