---
title: "Dialogs"
description: "Handling browser dialog windows in automated sessions."
image: "https://help.agent.mq/og.svg"
---

> Documentation Index
> Fetch the complete documentation index at: https://help.agent.mq/llms.txt
> Use this file to discover all available pages before exploring further.

# Dialogs

## What are Chrome dialogs?

A Chrome dialog is any pop-up or modal window that Google Chrome itself creates (not part of a web page) to communicate something to the user or request input. These include:

* **`alert()`** dialogs that display a message with an "OK" button
* **`confirm()`** dialogs that ask for confirmation with "OK" and "Cancel" buttons
* **`prompt()`** dialogs that request text input from the user
* **`window.print()`** dialogs that open the browser's print interface

These native browser dialogs are different from custom web page modals and require special handling in automation.

## Why you can't interact with them directly

Chrome dialogs block JavaScript execution on the page until they're dismissed. This means:

* Automation tools can't interact with the page while a dialog is open
* Automation scripts will hang until the dialog is manually dismissed

## Preventing Chrome dialogs

The best approach is to prevent these dialogs from appearing by overriding the native dialog functions before any page code runs. Use `addInitScript()`, which executes code before any page scripts.

### Implementation

### Node.js

```javascript Playwright
import { chromium } from "playwright-core";
import { Browsers } from "@agentmq/browsers";

const browsers = new Browsers({ apiKey: process.env.AGENTMQ_TOKEN });
const session = await browsers.sessions.create();

const browser = await chromium.connectOverCDP(session.connectUrl);
const defaultContext = browser.contexts()[0];
const page = defaultContext.pages()[0];

// Override dialog functions before page loads
await page.context().addInitScript(() => {
  window.alert = () => {};
  window.confirm = () => true;
  window.prompt = () => '';
});

// Now navigate to your target page
await page.goto("https://example.com");

// Dialogs should now be prevented

await page.close();
await browser.close();
```

### Python

```python Playwright
from agentmq.browsers import Browsers
from playwright.sync_api import sync_playwright
import os

browsers = Browsers(api_key=os.environ["AGENTMQ_TOKEN"])
session = browsers.sessions.create()

with sync_playwright() as playwright:
    browser = playwright.chromium.connect_over_cdp(session.connect_url)
    context = browser.contexts[0]
    page = context.pages[0]

    # Override dialog functions before page loads
    context.add_init_script("""
        window.alert = () => {};
        window.confirm = () => true;
        window.prompt = () => '';
    """)

    # Now navigate to your target page
    page.goto("https://example.com")

    # Dialogs should now be prevented

    page.close()
    browser.close()
```

### Customizing dialog behavior

You can customize the return values based on your automation needs:

```javascript
// Always reject confirmations
window.confirm = () => false;

// Return a specific value for prompts
window.prompt = () => 'my custom input';

// Log when dialogs would have appeared
window.alert = (message) => console.log('Alert prevented:', message);
```

## Handling PDF dialogs

PDF dialogs present unique challenges because PDFs can be generated and displayed in different ways. You'll encounter two common scenarios:

### Scenario 1: PDF opens in the current tab

When a PDF replaces the current page content, you need to capture it differently:

### Node.js

```javascript Playwright
import { chromium } from "playwright-core";
import { Browsers } from "@agentmq/browsers";
import fs from 'fs/promises';

const browsers = new Browsers({ apiKey: process.env.AGENTMQ_TOKEN });
const session = await browsers.sessions.create();

const browser = await chromium.connectOverCDP(session.connectUrl);
const context = browser.contexts()[0];
const page = context.pages()[0];

let savedPdfPath: string | null = null;

// Route PDF requests to capture them
await context.route('**/*.pdf', async (route) => {
  const resp = await route.fetch();
  const contentType = (resp.headers()['content-type'] ?? '').toLowerCase();

  if (contentType.includes('application/pdf')) {
    const url = route.request().url();
    const name = new URL(url).pathname.split('/').pop() || 'document.pdf';
    const outputPath = `captured-${Date.now()}-${name}`;
    const buffer = await resp.body();

    await fs.writeFile(outputPath, buffer);
    console.log('Saved PDF (network):', outputPath, 'from', url);
    savedPdfPath = outputPath;
  }

  await route.fulfill({ response: resp });
});

// Override print dialog
await context.addInitScript(() => {
  window.print = () => {};

  // Also capture client-side blobs as fallback
  const origCreate = URL.createObjectURL;
  (window as any).__pdfBlobs = [];
  URL.createObjectURL = function (blob: Blob) {
    try {
      if ((blob as any)?.type?.toLowerCase?.().includes('application/pdf')) {
        (window as any).__pdfBlobs.push(blob);
      }
    } catch {}
    return origCreate.apply(this, arguments);
  };
});

await page.goto("https://dialogue-interaction.vercel.app/");

// Trigger PDF generation
await page.click("#open-pdf");

// If network capture didn't work, try blob capture
if (!savedPdfPath) {
  const arrays = await page.evaluate(async () => {
    const blobs: Blob[] = (window as any).__pdfBlobs || [];
    const bufs = await Promise.all(blobs.map(b => b.arrayBuffer()));
    return bufs.map(ab => Array.from(new Uint8Array(ab)));
  });

  if (arrays.length) {
    const buf = Buffer.from(Uint8Array.from(arrays[0]));
    const outputPath = `captured-blob-${Date.now()}.pdf`;
    await fs.writeFile(outputPath, buf);
    console.log('Saved PDF (blob):', outputPath);
    savedPdfPath = outputPath;
  }
}

await page.close();
await browser.close();
```

### Python

```python Playwright
from playwright.sync_api import sync_playwright
from agentmq.browsers import Browsers
import time
import os

browsers = Browsers(api_key=os.environ["AGENTMQ_TOKEN"])
session = browsers.sessions.create()

saved_pdf_path = None

with sync_playwright() as playwright:
    browser = playwright.chromium.connect_over_cdp(session.connect_url)
    context = browser.contexts[0]
    page = context.pages[0]

    # Route PDF requests to capture them
    def handle_route(route):
        nonlocal saved_pdf_path
        response = route.fetch()
        content_type = (response.headers.get('content-type', '')).lower()

        if 'application/pdf' in content_type:
            url = route.request.url
            name = url.split('/')[-1] or 'document.pdf'
            output_path = f"captured-{int(time.time() * 1000)}-{name}"
            buffer = response.body()

            with open(output_path, 'wb') as f:
                f.write(buffer)
            print(f"Saved PDF (network): {output_path} from {url}")
            saved_pdf_path = output_path

        route.fulfill(response=response)

    context.route('**/*.pdf', handle_route)

    # Override print dialog and capture blobs
    context.add_init_script("""
        window.print = () => {};

        const origCreate = URL.createObjectURL;
        window.__pdfBlobs = [];
        URL.createObjectURL = function(blob) {
            try {
                if (blob?.type?.toLowerCase?.().includes('application/pdf')) {
                    window.__pdfBlobs.push(blob);
                }
            } catch {}
            return origCreate.apply(this, arguments);
        };
    """)

    page.goto("https://dialogue-interaction.vercel.app/")

    # Trigger PDF generation
    page.click("#open-pdf")

    # If network capture didn't work, try blob capture
    if not saved_pdf_path:
        arrays = page.evaluate("""
            async () => {
                const blobs = window.__pdfBlobs || [];
                const bufs = await Promise.all(blobs.map(b => b.arrayBuffer()));
                return bufs.map(ab => Array.from(new Uint8Array(ab)));
            }
        """)

        if arrays:
            pdf_data = bytes(arrays[0])
            output_path = f"captured-blob-{int(time.time() * 1000)}.pdf"
            with open(output_path, 'wb') as f:
                f.write(pdf_data)
            print(f"Saved PDF (blob): {output_path}")
            saved_pdf_path = output_path

    browser.close()
```

### Scenario 2: PDF opens in a new tab

When a PDF is generated client-side and opens in a new tab, you can capture the PDF blob before it's displayed:

### Node.js

```javascript Playwright
import { chromium } from "playwright-core";
import { Browsers } from "@agentmq/browsers";
import fs from 'fs/promises';

const browsers = new Browsers({ apiKey: process.env.AGENTMQ_TOKEN });
const session = await browsers.sessions.create();

const browser = await chromium.connectOverCDP(session.connectUrl);
const context = browser.contexts()[0];
const page = context.pages()[0];

// Prevent print dialog and capture PDF blobs
await context.addInitScript(() => {
  // Don't let native print dialog block
  window.print = () => {};

  // Capture client-side generated PDF blobs
  const origCreate = URL.createObjectURL;
  (window as any).__pdfBlobs = [];
  URL.createObjectURL = function (blob: Blob) {
    try {
      if ((blob as any)?.type?.toLowerCase?.().includes('application/pdf')) {
        (window as any).__pdfBlobs.push(blob);
      }
    } catch {}
    return origCreate.apply(this, arguments);
  };
});

await page.goto("http://pdfmake.org/playground.html");

// Trigger PDF generation by clicking the print button
await page.click("#printThis li:nth-child(2)");

// Wait for PDF to be generated
await page.waitForTimeout(1000);

// Extract and save the PDF
const arrays = await page.evaluate(async () => {
  const blobs: Blob[] = (window as any).__pdfBlobs || [];
  const bufs = await Promise.all(blobs.map(b => b.arrayBuffer()));
  return bufs.map(ab => Array.from(new Uint8Array(ab)));
});

if (arrays.length) {
  const buf = Buffer.from(Uint8Array.from(arrays[0]));
  const outputPath = `captured-blob-${Date.now()}.pdf`;
  await fs.writeFile(outputPath, buf);
  console.log('Saved PDF (blob):', outputPath);
}

await page.close();
await browser.close();
```

### Python

```python Playwright
from playwright.sync_api import sync_playwright
from agentmq.browsers import Browsers
import time
import os

browsers = Browsers(api_key=os.environ["AGENTMQ_TOKEN"])
session = browsers.sessions.create()

with sync_playwright() as playwright:
    browser = playwright.chromium.connect_over_cdp(session.connect_url)
    context = browser.contexts[0]
    page = context.pages[0]

    # Prevent print dialog and capture PDF blobs
    context.add_init_script("""
        window.print = () => {};

        const origCreate = URL.createObjectURL;
        window.__pdfBlobs = [];
        URL.createObjectURL = function(blob) {
            try {
                if (blob?.type?.toLowerCase?.().includes('application/pdf')) {
                    window.__pdfBlobs.push(blob);
                }
            } catch {}
            return origCreate.apply(this, arguments);
        };
    """)

    page.goto("http://pdfmake.org/playground.html")

    # Trigger PDF generation by clicking the print button
    page.click("#printThis li:nth-child(2)")
    page.wait_for_timeout(1000)

    # Extract and save the PDF
    arrays = page.evaluate("""
        async () => {
            const blobs = window.__pdfBlobs || [];
            const bufs = await Promise.all(blobs.map(b => b.arrayBuffer()));
            return bufs.map(ab => Array.from(new Uint8Array(ab)));
        }
    """)

    if arrays:
        pdf_data = bytes(arrays[0])
        output_path = f"captured-blob-{int(time.time() * 1000)}.pdf"
        with open(output_path, 'wb') as f:
            f.write(pdf_data)
        print(f"Saved PDF (blob): {output_path}")

    browser.close()
```

### How PDF capture works

Both scenarios use a combination of techniques:

1. **Override `window.print()`** - Prevents the native print dialog from blocking automation
2. **Intercept `URL.createObjectURL()`** - Captures client-side generated PDF blobs before they're displayed
3. **Route network requests** (Scenario 1) - Intercepts PDF files loaded from the network

The key difference:

* **Scenario 1**: PDF might be fetched from the network or generated, and the print dialog appears in the current tab
* **Scenario 2**: PDF is generated client-side and stored in a blob, opened in a new tab where the print dialog appears

Source: https://help.agent.mq/browsers/techniques/dialogues/index.mdx
