> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uplink.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Screenshots

> Capture screenshots of mobile browser pages

Take screenshots of the mobile browser viewport to capture visual state, debug issues, or document test results.

## Method

### `page.screenshot()`

Takes a screenshot of the page viewport.

```typescript theme={null}
page.screenshot(width?: number, height?: number, quality?: number): Promise<string | undefined>
```

**Parameters:**

* `width` (optional): Viewport width in pixels, 0 for auto (default: 0)
* `height` (optional): Viewport height in pixels, 0 for auto (default: 0)
* `quality` (optional): JPEG quality from 0 to 1 (default: 0.8)

**Returns:** `Promise<string | undefined>` - Base64-encoded image data (JPEG format)

**Examples:**

```typescript theme={null}
// Default screenshot (auto size, 0.8 quality)
const screenshot = await page.screenshot()

// Custom size
const screenshot = await page.screenshot(1920, 1080)

// High quality
const screenshot = await page.screenshot(0, 0, 1.0)

// Specific size and quality
const screenshot = await page.screenshot(800, 600, 0.9)
```

## Complete examples

### Basic screenshot

```typescript theme={null}
await page.goto('https://example.com')
await page.waitForSelector('#main-content')

const screenshot = await page.screenshot()

if (screenshot) {
  console.log('Screenshot captured')
  // Screenshot is base64-encoded JPEG data
} else {
  console.log('Screenshot failed')
}
```

### Save screenshot to file

```typescript theme={null}
import fs from 'fs/promises'

async function captureAndSave(page, filename) {
  const screenshot = await page.screenshot()

  if (screenshot) {
    // Remove base64 prefix if present
    const base64Data = screenshot.replace(/^data:image\/jpeg;base64,/, '')

    // Convert to buffer and save
    const buffer = Buffer.from(base64Data, 'base64')
    await fs.writeFile(filename, buffer)

    console.log('Screenshot saved to', filename)
  }
}

await page.goto('https://example.com')
await captureAndSave(page, 'page.jpg')
```

### Screenshot with custom dimensions

```typescript theme={null}
async function captureCustomSize(page) {
  // Capture at different sizes
  const mobile = await page.screenshot(375, 812, 0.9)   // iPhone size
  const tablet = await page.screenshot(768, 1024, 0.9)  // iPad size
  const desktop = await page.screenshot(1920, 1080, 0.9) // Desktop size

  return { mobile, tablet, desktop }
}

await page.goto('https://example.com')
const screenshots = await captureCustomSize(page)
```

### Screenshot after interaction

```typescript theme={null}
await page.goto('https://example.com')

// Capture before clicking
const before = await page.screenshot()

// Interact with page
await page.click('#toggle-button')
await page.waitForSelector('.expanded-content')

// Capture after clicking
const after = await page.screenshot()

// Save both for comparison
await saveScreenshot(before, 'before.jpg')
await saveScreenshot(after, 'after.jpg')
```

### Screenshot for test evidence

```typescript theme={null}
async function runTest(page, testName) {
  try {
    await page.goto('https://example.com/feature')
    await page.click('#action-button')
    await page.waitForSelector('.success')

    // Capture success state
    const screenshot = await page.screenshot()
    await saveScreenshot(screenshot, `${testName}-success.jpg`)

    console.log(`✓ Test "${testName}" passed`)
    return true

  } catch (error) {
    // Capture failure state
    const screenshot = await page.screenshot()
    await saveScreenshot(screenshot, `${testName}-failure.jpg`)

    console.error(`✗ Test "${testName}" failed:`, error.message)
    return false
  }
}

const passed = await runTest(page, 'checkout-flow')
```

### Screenshot sequence

```typescript theme={null}
async function captureSequence(page, actions) {
  const screenshots = []

  for (let i = 0; i < actions.length; i++) {
    const action = actions[i]

    // Perform action
    await action(page)

    // Wait a bit for UI to settle
    await new Promise(resolve => setTimeout(resolve, 500))

    // Capture screenshot
    const screenshot = await page.screenshot()

    screenshots.push({
      step: i + 1,
      name: action.name,
      image: screenshot
    })

    console.log(`Captured step ${i + 1}: ${action.name}`)
  }

  return screenshots
}

const sequence = await captureSequence(page, [
  { name: 'Homepage', action: (p) => p.goto('https://example.com') },
  { name: 'Click login', action: (p) => p.click('#login') },
  { name: 'Enter email', action: (p) => p.input('#email', 'user@example.com') },
  { name: 'Enter password', action: (p) => p.input('#password', 'pass') },
  { name: 'Submit form', action: (p) => p.click('#submit') }
])

// Save sequence
sequence.forEach((step, i) => {
  saveScreenshot(step.image, `step-${i + 1}-${step.name}.jpg`)
})
```

### Compare screenshots

```typescript theme={null}
import { createHash } from 'crypto'

function getImageHash(base64Image) {
  return createHash('md5').update(base64Image).digest('hex')
}

async function hasPageChanged(page, previousScreenshot) {
  const currentScreenshot = await page.screenshot()

  if (!currentScreenshot) return false

  const previousHash = getImageHash(previousScreenshot)
  const currentHash = getImageHash(currentScreenshot)

  return previousHash !== currentHash
}

// Capture initial state
const initial = await page.screenshot()

// Do something
await page.click('#refresh-button')
await new Promise(resolve => setTimeout(resolve, 2000))

// Check if page changed
const changed = await hasPageChanged(page, initial)
console.log('Page changed:', changed)
```

### Screenshot with different qualities

```typescript theme={null}
async function compareQualities(page) {
  const qualities = [0.3, 0.5, 0.7, 0.9, 1.0]

  for (const quality of qualities) {
    const screenshot = await page.screenshot(0, 0, quality)

    if (screenshot) {
      const size = Buffer.from(screenshot, 'base64').length
      console.log(`Quality ${quality}: ${(size / 1024).toFixed(2)} KB`)

      await saveScreenshot(screenshot, `quality-${quality}.jpg`)
    }
  }
}

await page.goto('https://example.com')
await compareQualities(page)
```

### Screenshot on error

```typescript theme={null}
async function automationWithErrorCapture(page) {
  try {
    await page.goto('https://example.com')
    await page.click('#button')
    await page.waitForSelector('.result', { timeout: 5000 })

  } catch (error) {
    console.error('Error occurred:', error.message)

    // Capture screenshot for debugging
    const screenshot = await page.screenshot()

    if (screenshot) {
      const timestamp = Date.now()
      await saveScreenshot(screenshot, `error-${timestamp}.jpg`)
      console.log('Error screenshot saved')
    }

    throw error
  }
}
```

### Visual regression testing

```typescript theme={null}
async function captureBaseline(page, name) {
  await page.goto('https://example.com')
  const screenshot = await page.screenshot()
  await saveScreenshot(screenshot, `baseline-${name}.jpg`)
  return screenshot
}

async function compareWithBaseline(page, name, baseline) {
  const current = await page.screenshot()

  if (!current) {
    throw new Error('Failed to capture screenshot')
  }

  const baselineHash = getImageHash(baseline)
  const currentHash = getImageHash(current)

  if (baselineHash !== currentHash) {
    await saveScreenshot(current, `diff-${name}.jpg`)
    throw new Error('Visual regression detected!')
  }

  console.log('Visual test passed')
}

// Capture baseline
const baseline = await captureBaseline(page, 'homepage')

// Later, compare
await page.goto('https://example.com')
await compareWithBaseline(page, 'homepage', baseline)
```

## Best practices

<AccordionGroup>
  <Accordion title="Wait for content to load" icon="hourglass">
    Always wait for important content before taking screenshots:

    ```typescript theme={null}
    await page.goto('https://example.com')
    await page.waitForSelector('.main-content')
    await new Promise(resolve => setTimeout(resolve, 500)) // Let animations finish
    const screenshot = await page.screenshot()
    ```
  </Accordion>

  <Accordion title="Use appropriate quality settings" icon="sliders">
    Balance quality and file size:

    ```typescript theme={null}
    // High quality for reports (larger files)
    const report = await page.screenshot(0, 0, 1.0)

    // Medium quality for testing (smaller files)
    const test = await page.screenshot(0, 0, 0.7)
    ```
  </Accordion>

  <Accordion title="Handle undefined returns" icon="question">
    Check if screenshot succeeded:

    ```typescript theme={null}
    const screenshot = await page.screenshot()

    if (!screenshot) {
      console.error('Screenshot failed')
      // Handle failure
    }
    ```
  </Accordion>

  <Accordion title="Organize screenshot files" icon="folder">
    Use descriptive filenames and organize by test/feature:

    ```typescript theme={null}
    const timestamp = new Date().toISOString().replace(/:/g, '-')
    const filename = `${testName}-${timestamp}.jpg`
    await saveScreenshot(screenshot, `screenshots/${testName}/${filename}`)
    ```
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Waiting" icon="hourglass" href="/api-reference/page/waiting">
    Wait before capturing screenshots
  </Card>

  <Card title="UI Control" icon="eye" href="/api-reference/page/overview">
    Show/hide pages
  </Card>

  <Card title="Navigation" icon="compass" href="/api-reference/page/navigation">
    Navigate to pages
  </Card>

  <Card title="Page overview" icon="window-maximize" href="/api-reference/page/overview">
    Back to Page API overview
  </Card>
</CardGroup>
