diff --git a/docs/guide/browser/context.md b/docs/guide/browser/context.md
index 744bb37ec597..cbe43ed0652e 100644
--- a/docs/guide/browser/context.md
+++ b/docs/guide/browser/context.md
@@ -105,6 +105,11 @@ export const page: {
The `getBy*` API is explained at [Locators API](/guide/browser/locators).
:::
+::: warning WARNING 3.1.2
+Note that `screenshot` will always return a base64 string if `save` is set to `false`.
+The `path` is also ignored in that case.
+:::
+
## `cdp`
The `cdp` export returns the current Chrome DevTools Protocol session. It is mostly useful to library authors to build tools on top of it.
diff --git a/docs/guide/browser/locators.md b/docs/guide/browser/locators.md
index 24d3413e3c22..5da93827e561 100644
--- a/docs/guide/browser/locators.md
+++ b/docs/guide/browser/locators.md
@@ -769,6 +769,7 @@ await languages.selectOptions([
### screenshot
```ts
+function screenshot(options: LocatorScreenshotOptions & { save: false }): Promise
function screenshot(options: LocatorScreenshotOptions & { base64: true }): Promise<{
path: string
base64: string
@@ -797,6 +798,11 @@ const { path, base64 } = await button.screenshot({
// bas64 - base64 encoded string of the screenshot
```
+::: warning WARNING 3.1.2
+Note that `screenshot` will always return a base64 string if `save` is set to `false`.
+The `path` is also ignored in that case.
+:::
+
### query
```ts
diff --git a/packages/browser/context.d.ts b/packages/browser/context.d.ts
index 2202de22df64..4464287341a3 100644
--- a/packages/browser/context.d.ts
+++ b/packages/browser/context.d.ts
@@ -29,12 +29,19 @@ export interface ScreenshotOptions {
element?: Element | Locator
/**
* Path relative to the current test file.
+ * @default `__screenshots__/${testFileName}/${testName}.png`
*/
path?: string
/**
* Will also return the base64 encoded screenshot alongside the path.
*/
base64?: boolean
+ /**
+ * Keep the screenshot on the file system. If file is not saved,
+ * `page.screenshot` always returns `base64` screenshot.
+ * @default true
+ */
+ save?: boolean
}
export interface BrowserCommands {
@@ -552,11 +559,16 @@ export interface BrowserPage extends LocatorSelectors {
* Make a screenshot of the test iframe or a specific element.
* @returns Path to the screenshot file or path and base64.
*/
+ screenshot(options: Omit & { save: false }): Promise
screenshot(options: Omit & { base64: true }): Promise<{
path: string
base64: string
}>
- screenshot(options?: ScreenshotOptions): Promise
+ screenshot(options?: Omit): Promise
+ screenshot(options?: ScreenshotOptions): Promise
/**
* Extend default `page` object with custom methods.
*/
diff --git a/packages/browser/src/node/commands/screenshot.ts b/packages/browser/src/node/commands/screenshot.ts
index 324da3dc6ba8..68b9aac7aab9 100644
--- a/packages/browser/src/node/commands/screenshot.ts
+++ b/packages/browser/src/node/commands/screenshot.ts
@@ -1,6 +1,6 @@
import type { BrowserCommand, ResolvedConfig } from 'vitest/node'
import type { ScreenshotOptions } from '../../../context'
-import { mkdir } from 'node:fs/promises'
+import { mkdir, rm } from 'node:fs/promises'
import { normalize } from 'node:path'
import { basename, dirname, relative, resolve } from 'pathe'
import { PlaywrightBrowserProvider } from '../providers/playwright'
@@ -15,6 +15,12 @@ export const screenshot: BrowserCommand<[string, ScreenshotOptions]> = async (
throw new Error(`Cannot take a screenshot without a test path`)
}
+ options.save ??= true
+
+ if (!options.save) {
+ options.base64 = true
+ }
+
const path = options.path
? resolve(dirname(context.testPath), options.path)
: resolveScreenshotPath(
@@ -31,28 +37,28 @@ export const screenshot: BrowserCommand<[string, ScreenshotOptions]> = async (
const element = context.iframe.locator(`${selector}`)
const buffer = await element.screenshot({
...config,
- path: savePath,
+ path: options.save ? savePath : undefined,
})
return returnResult(options, path, buffer)
}
const buffer = await context.iframe.locator('body').screenshot({
...options,
- path: savePath,
+ path: options.save ? savePath : undefined,
})
return returnResult(options, path, buffer)
}
if (context.provider instanceof WebdriverBrowserProvider) {
const page = context.provider.browser!
- if (!options.element) {
- const body = await page.$('body')
- const buffer = await body.saveScreenshot(savePath)
- return returnResult(options, path, buffer)
- }
+ const element = !options.element
+ ? await page.$('body')
+ : await page.$(`${options.element}`)
- const element = await page.$(`${options.element}`)
const buffer = await element.saveScreenshot(savePath)
+ if (!options.save) {
+ await rm(savePath, { force: true })
+ }
return returnResult(options, path, buffer)
}
@@ -84,6 +90,9 @@ function returnResult(
path: string,
buffer: Buffer,
) {
+ if (!options.save) {
+ return buffer.toString('base64')
+ }
if (options.base64) {
return { path, base64: buffer.toString('base64') }
}
diff --git a/test/browser/test/dom.test.ts b/test/browser/test/dom.test.ts
index 23f33e72bc70..83d4f8f3a151 100644
--- a/test/browser/test/dom.test.ts
+++ b/test/browser/test/dom.test.ts
@@ -65,6 +65,20 @@ describe('dom related activity', () => {
expect(base64).toBeTypeOf('string')
})
+ test('doesn\'t save base64', async () => {
+ const wrapper = createWrapper()
+ const div = createNode()
+ wrapper.appendChild(div)
+
+ const base64 = await page.screenshot({
+ element: wrapper,
+ save: false,
+ })
+ expect(base64).toBeTypeOf('string')
+ expect(base64).not.toContain('__screenshots__')
+ expect(base64).not.toContain('dom.test.ts')
+ })
+
test('shadow dom screenshot', async () => {
const wrapper = createWrapper()
const div = createNode()