diff --git a/docs/src/api/class-elementhandle.md b/docs/src/api/class-elementhandle.md index 1671be2606..91aff6a232 100644 --- a/docs/src/api/class-elementhandle.md +++ b/docs/src/api/class-elementhandle.md @@ -741,6 +741,9 @@ Returns the buffer with the captured screenshot. ### option: ElementHandle.screenshot.timeout = %%-input-timeout-js-%% * since: v1.8 +### option: ElementHandle.screenshot.maskColor = %%-screenshot-option-mask-color-%% +* since: v1.34 + ## async method: ElementHandle.scrollIntoViewIfNeeded * since: v1.8 diff --git a/docs/src/api/class-locator.md b/docs/src/api/class-locator.md index 5e0879b68b..ab0bf8ebe4 100644 --- a/docs/src/api/class-locator.md +++ b/docs/src/api/class-locator.md @@ -1768,6 +1768,9 @@ Returns the buffer with the captured screenshot. ### option: Locator.screenshot.timeout = %%-input-timeout-js-%% * since: v1.14 +### option: Locator.screenshot.maskColor = %%-screenshot-option-mask-color-%% +* since: v1.34 + ## async method: Locator.scrollIntoViewIfNeeded * since: v1.14 diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index b35458eac0..833a9c04af 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -3381,6 +3381,9 @@ Returns the buffer with the captured screenshot. ### option: Page.screenshot.clip = %%-screenshot-option-clip-%% * since: v1.8 +### option: Page.screenshot.maskColor = %%-screenshot-option-mask-color-%% +* since: v1.34 + ## async method: Page.selectOption * since: v1.8 * discouraged: Use locator-based [`method: Locator.selectOption`] instead. Read more about [locators](../locators.md). diff --git a/docs/src/api/params.md b/docs/src/api/params.md index e49ba90615..7ed78b4bbe 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -1092,6 +1092,12 @@ Specify screenshot type, defaults to `png`. Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink box `#FF00FF` that completely covers its bounding box. +## screenshot-option-mask-color +* since: v1.34 +- `maskColor` <[string]> + +Specify the color of the overlay box for masked elements, in [CSS color format](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). Default color is pink `#FF00FF`. + ## screenshot-option-full-page - `fullPage` <[boolean]> diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 578ccd4a67..82a11dc829 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -1046,6 +1046,7 @@ scheme.PageExpectScreenshotParams = tObject({ frame: tChannel(['Frame']), selector: tString, }))), + maskColor: tOptional(tString), })), }); scheme.PageExpectScreenshotResult = tObject({ @@ -1069,6 +1070,7 @@ scheme.PageScreenshotParams = tObject({ frame: tChannel(['Frame']), selector: tString, }))), + maskColor: tOptional(tString), }); scheme.PageScreenshotResult = tObject({ binary: tBinary, @@ -1876,6 +1878,7 @@ scheme.ElementHandleScreenshotParams = tObject({ frame: tChannel(['Frame']), selector: tString, }))), + maskColor: tOptional(tString), }); scheme.ElementHandleScreenshotResult = tObject({ binary: tBinary, diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index b6338da4fa..a4b7a3c517 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -857,12 +857,12 @@ export class Frame extends SdkObject { return result; } - async maskSelectors(selectors: ParsedSelector[]): Promise { + async maskSelectors(selectors: ParsedSelector[], color?: string): Promise { const context = await this._utilityContext(); const injectedScript = await context.injectedScript(); - await injectedScript.evaluate((injected, { parsed }) => { - injected.maskSelectors(parsed); - }, { parsed: selectors }); + await injectedScript.evaluate((injected, { parsed, color }) => { + injected.maskSelectors(parsed, color); + }, { parsed: selectors, color: color }); } async querySelectorAll(selector: string): Promise[]> { diff --git a/packages/playwright-core/src/server/injected/highlight.ts b/packages/playwright-core/src/server/injected/highlight.ts index 86ae25f442..767b077d4b 100644 --- a/packages/playwright-core/src/server/injected/highlight.ts +++ b/packages/playwright-core/src/server/injected/highlight.ts @@ -154,8 +154,8 @@ export class Highlight { this._innerUpdateHighlight(elements, { color, tooltipText: selector ? asLocator(this._language, selector) : '' }); } - maskElements(elements: Element[]) { - this._innerUpdateHighlight(elements, { color: '#F0F' }); + maskElements(elements: Element[], color?: string) { + this._innerUpdateHighlight(elements, { color: color ? color : '#F0F' }); } private _innerUpdateHighlight(elements: Element[], options: { color: string, tooltipText?: string }) { diff --git a/packages/playwright-core/src/server/injected/injectedScript.ts b/packages/playwright-core/src/server/injected/injectedScript.ts index 49d7ffaad7..3b2703e51a 100644 --- a/packages/playwright-core/src/server/injected/injectedScript.ts +++ b/packages/playwright-core/src/server/injected/injectedScript.ts @@ -1093,7 +1093,7 @@ export class InjectedScript { return error; } - maskSelectors(selectors: ParsedSelector[]) { + maskSelectors(selectors: ParsedSelector[], color?: string) { if (this._highlight) this.hideHighlight(); this._highlight = new Highlight(this); @@ -1101,7 +1101,7 @@ export class InjectedScript { const elements = []; for (const selector of selectors) elements.push(this.querySelectorAll(selector, this.document.documentElement)); - this._highlight.maskElements(elements.flat()); + this._highlight.maskElements(elements.flat(), color); } highlight(selector: ParsedSelector) { diff --git a/packages/playwright-core/src/server/screenshotter.ts b/packages/playwright-core/src/server/screenshotter.ts index 12791e0a49..3fd4f9eb60 100644 --- a/packages/playwright-core/src/server/screenshotter.ts +++ b/packages/playwright-core/src/server/screenshotter.ts @@ -38,6 +38,7 @@ export type ScreenshotOptions = { omitBackground?: boolean, animations?: 'disabled' | 'allow', mask?: { frame: Frame, selector: string}[], + maskColor?: string, fullPage?: boolean, clip?: Rect, scale?: 'css' | 'device', @@ -268,7 +269,7 @@ export class Screenshotter { progress.throwIfAborted(); // Avoid extra work. await Promise.all([...framesToParsedSelectors.keys()].map(async frame => { - await frame.maskSelectors(framesToParsedSelectors.get(frame)); + await frame.maskSelectors(framesToParsedSelectors.get(frame), options.maskColor); })); progress.cleanupWhenAborted(cleanup); return cleanup; diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index ac962e4f91..a5de4499de 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -9828,6 +9828,12 @@ export interface ElementHandle extends JSHandle { */ mask?: Array; + /** + * Specify the color of the overlay box for masked elements, in + * [CSS color format](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). Default color is pink `#FF00FF`. + */ + maskColor?: string; + /** * Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images. * Defaults to `false`. @@ -19639,6 +19645,12 @@ export interface LocatorScreenshotOptions { */ mask?: Array; + /** + * Specify the color of the overlay box for masked elements, in + * [CSS color format](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). Default color is pink `#FF00FF`. + */ + maskColor?: string; + /** * Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images. * Defaults to `false`. @@ -19826,6 +19838,12 @@ export interface PageScreenshotOptions { */ mask?: Array; + /** + * Specify the color of the overlay box for masked elements, in + * [CSS color format](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). Default color is pink `#FF00FF`. + */ + maskColor?: string; + /** * Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images. * Defaults to `false`. diff --git a/packages/protocol/src/channels.ts b/packages/protocol/src/channels.ts index bfd97e15b0..eccb93b51d 100644 --- a/packages/protocol/src/channels.ts +++ b/packages/protocol/src/channels.ts @@ -1910,6 +1910,7 @@ export type PageExpectScreenshotParams = { frame: FrameChannel, selector: string, }[], + maskColor?: string, }, }; export type PageExpectScreenshotOptions = { @@ -1936,6 +1937,7 @@ export type PageExpectScreenshotOptions = { frame: FrameChannel, selector: string, }[], + maskColor?: string, }, }; export type PageExpectScreenshotResult = { @@ -1959,6 +1961,7 @@ export type PageScreenshotParams = { frame: FrameChannel, selector: string, }[], + maskColor?: string, }; export type PageScreenshotOptions = { timeout?: number, @@ -1974,6 +1977,7 @@ export type PageScreenshotOptions = { frame: FrameChannel, selector: string, }[], + maskColor?: string, }; export type PageScreenshotResult = { binary: Binary, @@ -3327,6 +3331,7 @@ export type ElementHandleScreenshotParams = { frame: FrameChannel, selector: string, }[], + maskColor?: string, }; export type ElementHandleScreenshotOptions = { timeout?: number, @@ -3340,6 +3345,7 @@ export type ElementHandleScreenshotOptions = { frame: FrameChannel, selector: string, }[], + maskColor?: string, }; export type ElementHandleScreenshotResult = { binary: Binary, diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index 0a7fb5c6c1..26b0276b4f 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -376,6 +376,7 @@ CommonScreenshotOptions: properties: frame: Frame selector: string + maskColor: string? LaunchOptions: type: mixin diff --git a/tests/page/page-screenshot.spec.ts b/tests/page/page-screenshot.spec.ts index dcaa2cdb6b..7ee3900896 100644 --- a/tests/page/page-screenshot.spec.ts +++ b/tests/page/page-screenshot.spec.ts @@ -534,6 +534,15 @@ it.describe('page screenshot', () => { }); await page.screenshot({ mask: [page.locator('non-existent')] }); }); + + it('should work when mask color is not pink #F0F', async ({ page, server }) => { + await page.setViewportSize({ width: 500, height: 500 }); + await page.goto(server.PREFIX + '/grid.html'); + expect(await page.screenshot({ + mask: [page.locator('div').nth(5)], + maskColor: '#00FF00', + })).toMatchSnapshot('mask-color-should-work.png'); + }); }); }); diff --git a/tests/page/page-screenshot.spec.ts-snapshots/mask-color-should-work-chromium.png b/tests/page/page-screenshot.spec.ts-snapshots/mask-color-should-work-chromium.png new file mode 100644 index 0000000000..fef9e17ffe Binary files /dev/null and b/tests/page/page-screenshot.spec.ts-snapshots/mask-color-should-work-chromium.png differ diff --git a/tests/page/page-screenshot.spec.ts-snapshots/mask-color-should-work-firefox.png b/tests/page/page-screenshot.spec.ts-snapshots/mask-color-should-work-firefox.png new file mode 100644 index 0000000000..13e2365709 Binary files /dev/null and b/tests/page/page-screenshot.spec.ts-snapshots/mask-color-should-work-firefox.png differ diff --git a/tests/page/page-screenshot.spec.ts-snapshots/mask-color-should-work-webkit.png b/tests/page/page-screenshot.spec.ts-snapshots/mask-color-should-work-webkit.png new file mode 100644 index 0000000000..26b701d790 Binary files /dev/null and b/tests/page/page-screenshot.spec.ts-snapshots/mask-color-should-work-webkit.png differ