How to Capture a Website Screenshot with OneTrust Consent Already Accepted
Accept OneTrust consent in the same browser context and site origin you use to capture. Then save a viewport, element, or full-page screenshot with Playwright.
To capture a website screenshot after OneTrust consent has been accepted, make the intended choice on the target site, wait for the banner to disappear, and take the screenshot in the same browser context and on the same site origin. With Playwright, persist that browser context if you need to reuse the consent state later. A first-party consent cookie from another domain or a different OneTrust deployment may not apply.
This guide uses Playwright with Node.js. It covers a visible user choice, saved browser state, viewport, element, and full-page screenshots, plus the OneTrust details that explain why a banner can return.
1. Accept the intended choice on the target site
First load the exact site origin in the browser context that will do the capture. OneTrust’s production banner scripts are domain-specific, and its OptanonConsent cookie is first-party and associated with the domain configured for the deployed banner script. Accepting consent on a different host or origin is not a reliable way to establish state for the page you intend to capture.
Make the choice that matches the test or task. Accepting all categories is different from dismissing the banner. OneTrust documents OneTrust.Close() as dismissing the banner and setting the default consent model; OneTrust.AllowAll() enables consent for all categories or purposes, hosts, and vendors. Do not treat Close as equivalent to accepting everything, and do not select all categories unless that is the intended choice.
For reproducible QA, use the target site’s intended test environment and make the required choice there. There is no universal cookie value or script that safely represents acceptance across sites: deployments can have different domains, categories, geolocation behavior, and backend synchronization. OneTrust also distinguishes testing and production script placement; use production scripts only on the domains for which they were generated.
2. Install Playwright
The following example uses Node.js and Playwright’s Chromium browser. Create a project and install the package and browser:
mkdir onetrust-screenshot
cd onetrust-screenshot
npm init -y
npm install playwright
npx playwright install chromium
Save the next script as capture.mjs. It opens a visible browser so a person can make the real consent choice. It saves the browser context state after the choice and captures a full-page PNG.
3. Make the choice, save state, and capture
import { chromium } from 'playwright';
import { mkdir } from 'node:fs/promises';
const targetUrl = process.env.TARGET_URL ?? 'https://example.com/';
const statePath = 'state/onetrust.json';
const outputPath = 'artifacts/page-after-consent.png';
await mkdir('state', { recursive: true });
await mkdir('artifacts', { recursive: true });
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
// Match the site's language or viewport if those affect the consent UI.
viewport: { width: 1440, height: 1000 },
});
const page = await context.newPage();
try {
await page.goto(targetUrl, { waitUntil: 'domcontentloaded', timeout: 60000 });
console.log('Make the intended consent choice in the browser, then return here.');
console.log('Press Enter in this terminal after the banner closes and the page updates.');
await new Promise((resolve) => process.stdin.once('data', resolve));
// Keep cookies and other browser storage for reuse on this same origin.
await context.storageState({ path: statePath });
await page.screenshot({ path: outputPath, fullPage: true });
console.log(`Saved ${outputPath} and ${statePath}`);
} finally {
await browser.close();
}
Run it with the target URL:
TARGET_URL='https://www.example.com/page' node capture.mjs
After the screenshot is saved, inspect it to confirm that the banner is gone and the page reflects the intended consent choice. State files can contain cookies and other site storage; treat them as credentials, keep them out of source control, and use them only in an appropriate test workflow.
4. Reuse the saved consent state
To capture again without making the choice each time, create a new context from the saved storage state. Keep the same origin, since the consent cookie is first-party:
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
storageState: 'state/onetrust.json',
viewport: { width: 1440, height: 1000 },
});
const page = await context.newPage();
try {
await page.goto('https://www.example.com/page', {
waitUntil: 'domcontentloaded',
timeout: 60000,
});
await page.screenshot({ path: 'artifacts/reused-state.png', fullPage: true });
} finally {
await browser.close();
}
Replace the example URL with the same scheme, host, and relevant path used when accepting consent. A state file does not make consent portable to unrelated origins. If the site has server-side consent synchronization, the server’s stored state may also affect what the browser sees.
5. Choose the screenshot extent
Playwright supports screenshots of the visible viewport, a specific element, and the full scrollable page. Pick the mode that matches what the screenshot needs to show.
| Capture mode | Playwright call | Use it when |
|---|---|---|
| Viewport | page.screenshot({ path: 'viewport.png' }) |
You need the currently visible screen at a chosen viewport size. |
| Element | page.locator('main').screenshot({ path: 'main.png' }) |
You need one element and its rendered contents. |
| Full page | page.screenshot({ path: 'full.png', fullPage: true }) |
You need the page’s full scrollable extent. |
For an element screenshot, wait for the element to exist and be visible. Change main to a selector that identifies the content on the site:
const content = page.locator('main');
await content.waitFor({ state: 'visible', timeout: 15000 });
await content.screenshot({ path: 'artifacts/main.png' });
A full-page screenshot is useful for long pages, but it can differ from a viewport capture: content below the fold is included, and very long pages can take longer to render and save. Use a fixed viewport when you need comparable captures across runs.
6. Why OneTrust consent can disappear or the banner can return
- Origin mismatch: consent was accepted on a different host or scheme. Open the exact origin used for capture and make the choice there.
- Script domain mismatch: the deployed OneTrust production script is configured for a different domain. Confirm the site’s script and configured domain match; a mismatch can prevent consent from being captured correctly.
- Dismissal mistaken for acceptance: the banner was closed, but the default consent model is not all-category acceptance. Use the site’s preference center or intended accept action for the required state.
- State was not retained: a new browser context was created without loading the saved state, or state was saved before the choice finished applying. Save after the page updates and initialize the capture context with that state.
- Server-side consent synchronization: a server-side CMP integration may retain and update
otConsentString. Configured profile synchronization can give precedence to a newer server consent timestamp, so local browser state may not be the final state.
OneTrust’s implementation guidance recommends calling its Banner API on each app launch to determine whether a banner needs to be shown. For a screenshot workflow, that means a persisted browser state alone may not explain a reappearing banner if the application or server has its own consent lifecycle.
7. Performance, reliability, and cost
For local Playwright capture, the main practical costs are browser startup, page load, and screenshot rendering; the research sources provide no benchmark figures. Reuse one browser process for a batch of pages and create separate contexts when you need isolated storage. Give navigation and selector waits sensible timeouts, and save state only after the consent choice has taken effect.
For reliable comparisons, keep the browser version, viewport, origin, and consent workflow consistent. A site can still change its banner or page content between runs, and server-side profile synchronization can change the effective consent state. If the capture is for QA, record which choice was made and use the site’s intended test setup.
Playwright itself is a browser automation library; this DIY workflow does not have a per-screenshot API charge. It does require managing a browser runtime and the state files yourself. If that setup is inconvenient, the hosted option below takes a URL directly.
8. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. One GET request returns a PNG, JPEG, WebP, or PDF. It removes cookie/consent banners, newsletter popups, and chat widgets before capture; each step can be turned off. Responses identify page verdict and billing status, and bot checks, blank pages, timeouts, failed loads, and cache hits are not billed.
Use the API key from your account. See the ScreenshotNeo API documentation for request options and configuration.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com/page \
-o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com/page"},
timeout=90,
)
r.raise_for_status()
with open("shot.webp", "wb") as f:
f.write(r.content)
Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://example.com/page',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
The MCP server includes take_screenshot, get_page_info, and capture_pdf tools for AI agents such as Claude, Cursor, and other MCP clients. ScreenshotNeo offers 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 screenshots, and every feature is available on every plan. Sign up for 1,000 free screenshots a month, with no card required.
9. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The banner appears again in the screenshot. | The capture used another origin, context, or a state file saved before the choice finished. | Accept the intended choice at the exact origin, wait for the UI to update, save storage state, and load that state into the capture context. |
| The banner disappears, but consent is not what the test expects. | The banner was dismissed with default-model behavior rather than accepting the intended categories. | Use the preference center or the site’s intended accept action; verify the resulting page state. |
| The saved state works on one host but not another. | OneTrust’s consent cookie is first-party and tied to the configured banner domain. | Establish the choice separately in the browser context and origin required by the test. Check that the production script matches the deployed domain. |
| The banner returns despite a saved cookie. | The site may use server-side state or profile synchronization, or the script/domain setup may not match. | Check the application’s OneTrust integration and retained otConsentString; verify domain configuration and synchronization behavior with the site owner. |
| The full-page capture is missing content. | Lazy-loaded content may not have rendered before capture, or the page’s content loads after navigation. | Wait for the relevant content or selector before screenshotting. For important sections, capture the element after it becomes visible. |
| Navigation times out. | The page did not reach the selected load condition within the timeout, often because of slow or persistent network activity. | Use domcontentloaded for initial navigation, then wait for the specific content needed; retain a finite timeout and investigate the target page’s load behavior. |
FAQ
Does taking a screenshot mean consent was accepted?
No. A screenshot only records what the page rendered. The choice must be made in the site’s consent interface or preference center and verified in the resulting page state.
Can I copy an accepted OneTrust cookie from another website?
Do not assume it will work. The cookie is first-party and associated with the domain configured for that site’s banner script.
Can I use the same saved Playwright state for every site?
No. Browser storage is scoped to origins and the sites’ consent implementations. Save and load state for the specific site and test workflow.
Should I use a visible or headless browser?
Use a visible browser when a person needs to make or verify the choice. Once the appropriate state is saved, a headless browser can load that state for repeat captures, subject to the site’s server-side consent behavior.


