Skip to content

Screenshots

craftdriver exposes a single options-bag screenshot() method on both Browser and ElementHandle. PNG bytes are always returned as a Buffer; pass path to also write the file in one step.

Page screenshots

browser.screenshot(opts?)

OptionTypeDefaultNotes
pathstringWrite the PNG to this file path.
selectorstring | Byfull viewportIf set, capture only the matching element.
fullPagebooleanfalseCapture the entire scrollable document. Requires BiDi.
timeoutnumber (ms)defaultWait timeout when locating selector.

fullPage and selector are mutually exclusive.

typescript
// Viewport only (default), buffer
const buffer = await browser.screenshot();

// Viewport, written to disk
await browser.screenshot({ path: 'screenshots/homepage.png' });

// Whole scrollable document (BiDi `browsingContext.captureScreenshot`
// with `origin: "document"`).
await browser.screenshot({ fullPage: true, path: 'screenshots/full.png' });

// One element by CSS selector
const chart = await browser.screenshot({ selector: '#sales-chart' });

// One element, written to disk
await browser.screenshot({
  selector: '#sales-chart',
  path: 'screenshots/chart.png',
});

Full-page vs viewport

Viewport capture (fullPage: false, the default) uses the W3C Classic Take Screenshot endpoint and is bounded by the visible viewport. Full-page capture uses BiDi browsingContext.captureScreenshot with origin: "document" and produces a PNG sized to the full scrollable content — useful for visual diffs of long pages and for archiving the complete rendered output. Full-page capture requires enableBiDi: true (the default); on Classic-only sessions it throws.

Element screenshots

element.screenshot(opts?)

OptionTypeDefaultNotes
pathstringWrite the PNG to this file path.
timeoutnumberdefaultElement resolution timeout.
typescript
const buffer = await browser.find('#product-image').screenshot();
await browser.find('#logo').screenshot({ path: 'logo.png' });

Use cases

Test failure documentation

typescript
afterEach(async (context) => {
  if (context.task.result?.state === 'fail') {
    const name = context.task.name.replace(/\s+/g, '-');
    await browser.screenshot({ path: `screenshots/${name}.png` });
  }
  await browser.quit();
});

Visual comparison baseline

typescript
await browser.navigateTo('https://example.com');
await browser.screenshot({ path: 'baseline/homepage.png' });

// Later, capture the candidate and diff with an image library:
await browser.navigateTo('https://example.com');
await browser.screenshot({ path: 'current/homepage.png' });

Component screenshots

typescript
await browser.screenshot({ selector: 'header',   path: 'components/header.png' });
await browser.screenshot({ selector: '.sidebar', path: 'components/sidebar.png' });
await browser.screenshot({ selector: 'footer',   path: 'components/footer.png' });

Before / after an action

typescript
await browser.screenshot({ selector: '#order-form', path: 'before-submit.png' });
await browser.find('#submit-order').click();
await browser.expect('#confirmation').toBeVisible();
await browser.screenshot({ selector: '#confirmation', path: 'after-submit.png' });

Tips

Create the screenshot directory

screenshot({ path }) writes through fs.writeFile; the parent directory must already exist:

typescript
import { mkdir } from 'fs/promises';
await mkdir('screenshots', { recursive: true });
await browser.screenshot({ path: 'screenshots/test.png' });

Timestamped filenames

typescript
const ts = new Date().toISOString().replace(/[:.]/g, '-');
await browser.screenshot({ path: `screenshots/page-${ts}.png` });

Wait for stability

typescript
await browser.navigateTo('https://example.com');
await browser.expect('#main-content').toBeVisible();
await browser.screenshot({ path: 'stable-page.png' });

Buffer usage

When you only need bytes (uploading, image diffing), omit path:

typescript
const buffer = await browser.screenshot();

import { writeFile } from 'fs/promises';
await writeFile('screenshot.png', buffer);

await uploadToS3(buffer, 'screenshots/latest.png');

Released under the MIT License.