ScreenshotNeo

BlogHow-to

How to Override Browser Permissions in Puppeteer

Grant a browser permission to the right Puppeteer origin and context with the current setPermission() API, then clean up overrides safely.

By the ScreenshotNeo team4 October 20266 min read

Use BrowserContext.setPermission() to set a permission for an origin in current Puppeteer code. The older overridePermissions() method is deprecated. For example, grant geolocation to https://example.com through the same browser context that owns the page:

const context = browser.defaultBrowserContext();
await context.setPermission('https://example.com', {
  permission: 'geolocation',
  state: 'granted',
});
const page = await context.newPage();

The call sets the permission decision; it does not provide location coordinates. For geolocation testing, also call page.setGeolocation(). See the official BrowserContext reference and Page reference.

1. Grant a permission in a complete Puppeteer script

Install Puppeteer in a Node.js project with npm install puppeteer. This runnable example launches Chromium, grants geolocation for one origin, sets coordinates, visits the page, and closes the browser even if navigation or evaluation fails.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const context = browser.defaultBrowserContext();
    const origin = 'https://example.com';

    await context.setPermission(origin, {
      permission: 'geolocation',
      state: 'granted',
    });

    const page = await context.newPage();
    await page.setGeolocation({ latitude: 37.7749, longitude: -122.4194 });
    await page.goto(origin, { waitUntil: 'domcontentloaded' });

    console.log('Page loaded:', page.url());
    // Run assertions or interact with the page here.
  } finally {
    await browser.close();
  }
})().catch(error => {
  console.error(error);
  process.exitCode = 1;
});

The origin is the permission scope. Use the scheme and host that the page actually uses; include a port when testing a non-default port. Configure the permission before navigation or before the page makes the permission request.

2. Choose the context and origin carefully

Permission overrides belong to a BrowserContext, while the origin identifies which site receives the decision. A page created in another context will not inherit this context’s setup. Puppeteer exposes the page’s owning context with page.browserContext().

Situation What to do
Default context Call browser.defaultBrowserContext(), then set the permission there before opening or navigating the page.
Dedicated isolated context Create the context, set permission on it, then create the page from that same context.
Existing page Call await page.browserContext().setPermission(origin, descriptor) for the page’s context.
Several test accounts or origins Prefer separate contexts when isolation is useful; set each origin’s permission in its owning context.

For an isolated context, the sequence is:

const context = await browser.createBrowserContext();
try {
  await context.setPermission('https://example.com', {
    permission: 'geolocation',
    state: 'granted',
  });
  const page = await context.newPage();
  await page.goto('https://example.com');
} finally {
  await context.close();
}

A dedicated context can be closed to discard its pages and context-scoped state. The default context cannot be closed; clear overrides when finished if other work does not depend on them.

3. Permission descriptors and states

setPermission(origin, permissions) takes an origin (or '*') and one or more permission descriptor/state objects. A descriptor has a permission name and a state such as 'granted', 'denied', or 'prompt', subject to support in the installed Puppeteer and browser versions. The exact descriptor names are browser-dependent, so check the versions you run if a name is rejected.

await context.setPermission('https://example.com', [
  { permission: 'geolocation', state: 'granted' },
]);

For broad use across origins, the API accepts '*' as the target. Use that only when a test deliberately needs the same permission behavior for every origin in that context. Narrow origin scopes make tests easier to reason about.

Do not assume that setting one descriptor reproduces the old method’s behavior. The deprecated method grants the listed permissions and automatically denies permissions omitted from the list. The current method sets permissions using descriptor/state objects; treat each desired decision explicitly.

4. Test geolocation correctly

Granting the permission and setting coordinates are separate steps. If the page must read location, set both before triggering its location lookup:

await context.setPermission('https://example.com', {
  permission: 'geolocation',
  state: 'granted',
});
await page.setGeolocation({
  latitude: 37.7749,
  longitude: -122.4194,
});

If your test intentionally exercises the denied or prompt path, set that state and assert the page’s behavior. Do not confuse a permission denial with missing or invalid coordinates.

5. Migrate from overridePermissions()

Legacy code commonly looks like this:

await context.overridePermissions('https://example.com', ['geolocation']);

The current Puppeteer reference marks overridePermissions() deprecated in favor of setPermission(). Migrate by translating each permission name into a descriptor and choosing its state:

await context.setPermission('https://example.com', {
  permission: 'geolocation',
  state: 'granted',
});

Review tests that depended on the old method’s automatic denial of omitted permissions. If those denials matter, express them deliberately using supported descriptors and states rather than relying on the legacy list semantics. The permission names available depend on the browser version.

6. Clear permission overrides

Use clearPermissionOverrides() to clear all permission overrides for a context:

await context.clearPermissionOverrides();

This is context-wide cleanup, not a per-origin reset. If pages or tests share a context, clearing overrides can affect all of them. A common safe pattern is to create and close a dedicated context for each isolated test, or to clear only after all users of a shared context are done.

7. Troubleshooting

Symptom Likely cause Fix
overridePermissions() is flagged as deprecated The code uses the legacy API. Use context.setPermission(origin, { permission, state }) and verify the descriptor is supported by your browser version.
The page still shows a permission prompt or denial The permission was set on a different context, for a different origin, or after the page attempted access. Set the decision on page.browserContext()‘s context for the page’s exact origin before the permission request.
Geolocation returns an error or no useful position Permission was granted but coordinates were not set, or the page is not using the origin you configured. Call page.setGeolocation() with valid coordinates and check page.url() and its origin.
The descriptor or state is rejected The installed Puppeteer/browser combination may not support that permission name or state. Check the installed versions and the supported permission descriptors for that browser. Use a supported descriptor and state.
A later test unexpectedly loses permission clearPermissionOverrides() cleared every override in the shared context. Run tests in separate contexts or move cleanup until all pages using the context are finished.
Permission behavior differs between environments Different Puppeteer or browser versions can expose different supported descriptors. Pin or record the versions used by the test environment and validate the permission name against that environment.

8. Reliability, performance, and cost considerations

  • Reliability: Scope decisions to the exact origin and owning context. Explicitly clean up or close a dedicated context so state does not leak between tests.
  • Timing: Apply permission settings before the page triggers the browser API. For geolocation, set coordinates before asking the page for its position.
  • Performance: These calls configure browser state; they do not replace page navigation, loading, or application work. Keep test setup focused and avoid reusing a mutable context across unrelated tests.
  • Cost: Puppeteer itself is an open-source browser automation library; operational costs depend on where and how you run Chromium, which this API reference does not quantify.

9. Or skip the browser setup

If your goal is to get a website screenshot rather than exercise permission-dependent behavior, ScreenshotNeo can capture a URL with one request. It does not override browser permissions or replace a Puppeteer permission test. See the ScreenshotNeo API docs for request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and responses identify the page verdict and billing status in headers. Its MCP server provides screenshot tools for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card required.

10. FAQ

Can I grant more than one permission?

Yes. Pass an array of supported descriptor/state objects to the context method and verify each permission is supported by your browser version.

Can a permission be set for every origin?

The method accepts '*' as a target origin. Use it only when broad behavior is intentional for that context.

Does setting geolocation permission choose the test location?

No. Set the permission and coordinates separately with page.setGeolocation().

Can I clear one origin’s overrides?

clearPermissionOverrides() clears all permission overrides for the context. Use a dedicated context when you need isolated cleanup.

Official references

Learn more about ScreenshotNeo.