# Handling CAPTCHA Events

### Event-Based Method&#x20;

To monitor the CAPTCHA solving process, we recommend using the Event-Based method. It allows your script to listen for custom messages sent directly from the extension.

#### How it works

The extension sends a message to the browser's `window` object. You can capture these by adding a "message" event listener.

|                               |                                                |
| ----------------------------- | ---------------------------------------------- |
| `oxylabs-captcha-solve-start` | The CAPTCHA is detected and solving has begun. |
| `oxylabs-captcha-solve-end`   | The CAPTCHA was successfully solved.           |
| `oxylabs-captcha-solve-error` | The auto-solver failed to bypass the CAPTCHA.  |

You can subscribe to these events to pause your automation and resume only after the CAPTCHA has been successfully handled. Normally, CAPTCHA solving takes up to 30 seconds, depending on the type and complexity of the CAPTCHA, but in some cases could take longer, so allow time for CAPTCHA solving to end.

#### Code samples

{% tabs %}
{% tab title="Python (Playwright)" %}

```python
import sys
from playwright.sync_api import sync_playwright

# Configuration
EXTENSION_NAME = 'oxylabs-runtime'
CAPTCHA_SOLVE_END = 'oxylabs-captcha-solve-end'
CAPTCHA_SOLVE_ERROR = 'oxylabs-captcha-solve-error'
UB_BROWSER_URL = 'wss://<username>:<password>@ubc.oxylabs.io'
CAPTCHA_CHECK_TIMEOUT_SEC = 60
TARGET_URL = 'https://www.indeed.com/cmp/Bank-of-the-West/reviews?lang=any&fcountry=ALL&sort=date'

def run():
    with sync_playwright() as p:
        print('Opening browser page...')
        # Connect to the remote browser using CDP
        browser = p.chromium.connect_over_cdp(UB_BROWSER_URL)
        
        # Get the default context and create a new page
        ctx = browser.contexts[0]
        page = ctx.new_page()

        # This must be done BEFORE navigation.
        ctx.add_init_script(f"""
            window.addEventListener("message", (event) => {{
                if (event.data && event.data.source === "{EXTENSION_NAME}") {{
                    window.__extensionStatus = event.data.type;
                }}
            }});
        """)

        print('Opening target website...')
        page.goto(TARGET_URL, wait_until='domcontentloaded')

        try:
            # Wait for the extension status to change
            page.wait_for_function(
                """
                ([solveEnd, solveError]) => {
                    const status = window.__extensionStatus;
                    if (status === solveError) {
                        throw new Error("CAPTCHA solving failed");
                    }
                    return status === solveEnd;
                }
                """,
                arg=[CAPTCHA_SOLVE_END, CAPTCHA_SOLVE_ERROR],
                timeout=CAPTCHA_CHECK_TIMEOUT_SEC * 1000
            )
            print('CAPTCHA solved successfully, continue scraping...')
            
        except Exception as err:
            print(f'Error during CAPTCHA solve: {err}')
            browser.close()
            sys.exit(1)

        page.wait_for_selector('h1[data-testid="PageHeader-title-reviews"]')
        page.screenshot(path='page_screenshot.jpg')

        page.close()
        browser.close()
        print('Done.')

if __name__ == "__main__":
    run()
```

{% endtab %}

{% tab title="JavaScript (Playwright)" %}

```javascript
const { chromium } = require('playwright');

const 
    EXTENSION_NAME = 'oxylabs-runtime',
    CAPTCHA_SOLVE_END = 'oxylabs-captcha-solve-end',
    CAPTCHA_SOLVE_ERROR = 'oxylabs-captcha-solve-error',
    UB_BROWSER_URL = 'wss://<username>:<password>@ubc.oxylabs.io',
    CAPTCHA_CHECK_TIMEOUT_SEC = 60,
    TARGET_URL = 'https://www.indeed.com/cmp/Bank-of-the-West/reviews?lang=any&fcountry=ALL&sort=date';

(async () => {
    console.log('Opening browser page...');
    const browser = await chromium.connectOverCDP(UB_BROWSER_URL);
    const ctx = browser.contexts()[0];
    const page = await ctx.newPage();

    // This must be done BEFORE navigation.
    await ctx.addInitScript((extensionName) => {
        window.addEventListener("message", (e) => {
            if (e.data?.source !== extensionName) return;
            window.__extensionStatus = e.data.type;
        });
    }, EXTENSION_NAME);

    console.log('Opening target website...');
    await page.goto(TARGET_URL, { waitUntil: 'domcontentloaded' });

    try {
        await page.waitForFunction(
            ([solveEnd, solveError]) => {
                const status = window.__extensionStatus;
                if (status === solveError) {
                    throw new Error("CAPTCHA solving failed");
                }
                return status === solveEnd;
            },
            [CAPTCHA_SOLVE_END, CAPTCHA_SOLVE_ERROR],
            { timeout: CAPTCHA_CHECK_TIMEOUT_SEC * 1000 }
        );
        console.log('CAPTCHA solved successfully, continue scraping...');
    } catch (err) {
        console.error('Error during CAPTCHA solve:', err.message);
        await browser.close();
        process.exit(1);
    }

    await page.waitForSelector('h1[data-testid="PageHeader-title-reviews"]');
    await page.screenshot({ path: 'page_screenshot.jpg' });

    await page.close();
    await browser.close();
    console.log('Done.');
})();

```

{% endtab %}

{% tab title="JavaScript (Puppeteer)" %}

```javascript
const puppeteer = require('puppeteer');

const 
    EXTENSION_NAME = 'oxylabs-runtime', 
    CAPTCHA_SOLVE_END = 'oxylabs-captcha-solve-end',
    CAPTCHA_SOLVE_ERROR = 'oxylabs-captcha-solve-error',
    UB_BROWSER_URL = 'wss://<username>:<password>@ubc.oxylabs.io',
    CAPTCHA_CHECK_TIMEOUT_SEC = 60,
    TARGET_URL = 'https://www.indeed.com/cmp/Bank-of-the-West/reviews?lang=any&fcountry=ALL&sort=date';

(async () => {
    console.log('Opening browser page...');
    
    const browser = await puppeteer.connect({
        browserWSEndpoint: UB_BROWSER_URL,
    });
    const page = await browser.newPage();

    // This must be done BEFORE navigation.
    await page.evaluateOnNewDocument((extensionName) => {
        window.addEventListener("message", (e) => {
            if (e.data?.source !== extensionName) return;
            window.__extensionStatus = e.data.type;
        });
    }, EXTENSION_NAME);

    console.log('Opening target website...');
    await page.goto(TARGET_URL, { waitUntil: 'domcontentloaded' });

    try {
        await page.waitForFunction(
            (solveEnd, solveError) => {
                const status = window.__extensionStatus;
                if (status === solveError) {
                    throw new Error("CAPTCHA solving failed");
                }
                return status === solveEnd;
            },
            { timeout: CAPTCHA_CHECK_TIMEOUT_SEC * 1000 },
            CAPTCHA_SOLVE_END, 
            CAPTCHA_SOLVE_ERROR
        );
        console.log('CAPTCHA solved successfully, continue scraping...');
    } catch (err) {
        console.error('Error during CAPTCHA solve:', err.message);
        await browser.close();
        process.exit(1);
    }

    await page.waitForSelector('h1[data-testid="PageHeader-title-reviews"]');
    await page.screenshot({ path: 'page_screenshot.jpg' });

    await page.close();
    await browser.disconnect();
    console.log('Done.');
})();

```

{% endtab %}
{% endtabs %}
