For the complete documentation index, see llms.txt. This page is also available as Markdown.

Playwright

Playwright Integration

Q: How do I integrate Stoobly with Playwright tests?

A: Prefer initializing Stoobly in a custom Playwright fixture so interception starts before any other fixtures that might trigger network calls. In that fixture, set withContext() or withPage(), call enable() (pass { mode: InterceptMode.record } when recording), and set withTestTitle() using testInfo.

Instead of managing a scenarioKey, derive a scenario name from the hierarchical test title path — this is more intuitive and one less thing to configure. Compute it from testInfo.titlePath and pass it in the interceptor options:

const scenarioName = testInfo.titlePath.join(' > '); // pass as { scenarioName }

Example:

import { test as base, expect } from '@playwright/test';
import Stoobly from 'stoobly';

// Create a test fixture that initializes Stoobly early
const test = base.extend({
  stooblyInterceptor: [
    async ({ context, page }, use, testInfo) => {
      const stoobly = new Stoobly();
      const scenarioName = testInfo.titlePath.join(' > ');
      const interceptor = stoobly.playwrightInterceptor({
        urls: [new RegExp('https://api.example.com/.*')],
        scenarioName,
      });

      // Choose one based on scope:
      await interceptor.withContext(context).enable(); // recommended for multi-page tests
      // await interceptor.withPage(page).enable();    // for single-page tests
      interceptor.withTestTitle(testInfo.title);

      await use(undefined);
    },
    { auto: true }, // ensure it runs automatically before the test starts
  ],
});

test.describe('My Tests', () => {
  test('can fetch data', async ({ page }) => {
    await page.goto('https://example.com');
    // Your test code here
  });
});

Q: Why do I need to call withPage() and withTestTitle() in Playwright?

A: Playwright doesn't provide a global API to auto-detect the current page or test title, so you must explicitly set them in a setup point. Use a custom fixture (recommended) so interception is active before other fixtures run, or set them in beforeEach if you cannot use a fixture.

Example:

Q: When should I use withContext() instead of withPage()?

A: Use withContext() when you need to intercept requests from all pages in a browser context, including new pages created during tests. Use withPage() when you only want to intercept requests from a specific page.

Key differences:

  • withPage() - Intercepts requests only from the specified page. New pages created in the same context will NOT be intercepted.

  • withContext() - Intercepts requests from all pages in the browser context, including pages created with context.newPage(), browser extensions, and service workers.

  • Both together - You can use both withContext() and withPage() to ensure all pages are intercepted.

Example:

Use withContext() when:

  1. Your tests create multiple pages (popups, new tabs)

  2. You're testing browser extensions that make background requests

  3. You're testing service workers

  4. You want consistent interception across all pages without calling withPage() for each

Use withPage() when:

  1. You only work with the test fixture page

  2. You want fine-grained control over which pages are intercepted

  3. You're following the typical Playwright test pattern with a single page

Q: How do I intercept context.request (API tests) in Playwright?

A: withPage() and withContext() use Playwright's page.route() / context.route() internally, which only intercepts requests made by browser pages — not requests made via context.request (Playwright's APIRequestContext). For API tests that use context.request, you must also call context.setExtraHTTPHeaders() with the interceptor's headers after enable().

This works because context.request calls still travel through any proxy configured in playwright.config.ts. Adding the Stoobly headers via setExtraHTTPHeaders ensures those calls carry the correct X-Stoobly-Proxy-Mode, X-Stoobly-Scenario-Key, and session headers to the proxy.

Example:

Key points:

  • withContext(context) sets up context.route() for browser page requests only

  • context.setExtraHTTPHeaders((interceptor as any).headers) must be called after enable() so the headers reflect the current session ID, scenario key, and proxy mode

  • headers is a protected field on the interceptor class; (interceptor as any).headers accesses it at runtime


Q: How do I record requests in Playwright tests?

A: Set intercept mode to record—either in the interceptor constructor (mode: InterceptMode.record) or when calling enable({ mode: InterceptMode.record }).

Example:

Last updated