Screenshot a Logged-In Page Protected by HTTP Basic Authentication with Playwright
Use Playwright HTTP credentials to capture a protected page. Learn context setup, readiness checks, full-page output, troubleshooting, and a no-browser-setup option.
To screenshot a page protected by HTTP Basic Authentication, configure Playwright’s httpCredentials on a browser context before navigating to the page. Wait for the content you need, then call page.screenshot(). Use environment variables for the credentials and restrict them to the target origin when practical.
import { chromium } from 'playwright';
const username = process.env.BASIC_AUTH_USERNAME;
const password = process.env.BASIC_AUTH_PASSWORD;
if (!username || !password) {
throw new Error('Set BASIC_AUTH_USERNAME and BASIC_AUTH_PASSWORD');
}
const browser = await chromium.launch();
try {
const context = await browser.newContext({
httpCredentials: {
username,
password,
origin: 'https://example.com',
},
});
const page = await context.newPage();
await page.goto('https://example.com/protected-page', {
waitUntil: 'domcontentloaded',
});
await page.locator('main').waitFor({ state: 'visible' });
await page.screenshot({ path: 'screenshot.png', fullPage: true });
} finally {
await browser.close();
}
This is an illustrative recipe, not a report of executed testing. Replace the example origin, route, and readiness selector with values for your application. See the Playwright BrowserContext API, Page API, and authentication guide.
1. Install Playwright and prepare credentials
In a Node.js project, install Playwright and its browser binaries using the commands appropriate to your package manager:
npm install playwright
npx playwright install chromium
Set BASIC_AUTH_USERNAME and BASIC_AUTH_PASSWORD in your shell, CI secret store, or secrets manager. For a local shell, you can export them before starting the script. Never commit real credentials in the script, a checked-in .env file, or a configuration file.
2. Configure HTTP Basic Authentication
Playwright accepts an httpCredentials object in browser.newContext(). Set the username and password there before creating the page and navigating. Its optional origin field limits where those credentials apply by scheme, host, and port. An array can be used when you need distinct credentials for multiple origins. Consult the BrowserContext API for the installed version’s precise types and behavior.
For one target site, prefer an origin such as https://example.com over leaving credentials broadly applicable. The origin must match the URL that issues the Basic Auth challenge; a different port or scheme is a different origin. Redirects to another protected origin may need their own credentials.
The BrowserType API also documents HTTP credential configuration. Context configuration is convenient when credentials should apply to a particular browsing session. Choose the configuration point that fits your browser setup and check the documentation for your Playwright version.
3. Navigate, wait for the page, and capture
A successful navigation does not guarantee that application content is ready. Choose a page-specific signal such as a visible main region, a known heading, or a result row. A title check alone may only prove that navigation occurred, not that the required content has loaded.
The example uses domcontentloaded for navigation and then waits for main. Replace that selector with an element that reliably indicates the authenticated page is ready. If the page renders asynchronously, this explicit condition is more useful than taking the screenshot immediately after navigation.
page.screenshot() produces PNG by default. Set fullPage: true to capture the full scrollable page; omit it for a viewport-only capture. The Page API documents screenshot options and supported formats.
4. Runnable Python and cURL alternatives
Playwright’s official examples in this guide are for Node.js and browser automation. If you need to automate the browser with Python, use Playwright’s Python package and the same context credential setup:
import asyncio
import os
from playwright.async_api import async_playwright
async def main():
username = os.environ.get("BASIC_AUTH_USERNAME")
password = os.environ.get("BASIC_AUTH_PASSWORD")
if not username or not password:
raise RuntimeError("Set BASIC_AUTH_USERNAME and BASIC_AUTH_PASSWORD")
async with async_playwright() as p:
browser = await p.chromium.launch()
try:
context = await browser.new_context(
http_credentials={
"username": username,
"password": password,
"origin": "https://example.com",
}
)
page = await context.new_page()
await page.goto("https://example.com/protected-page", wait_until="domcontentloaded")
await page.locator("main").wait_for(state="visible")
await page.screenshot(path="screenshot.png", full_page=True)
finally:
await browser.close()
asyncio.run(main())
Install the Python package and browser binaries with pip install playwright and playwright install chromium. The Python API uses snake_case option names; refer to the official Playwright Python documentation for the version you install.
cURL can fetch an HTTP resource using Basic Authentication, but it does not render a webpage or produce a browser screenshot. It is useful for checking whether the server accepts the credentials and returns a response:
curl --fail --user "$BASIC_AUTH_USERNAME:$BASIC_AUTH_PASSWORD" \
--output response.html \
https://example.com/protected-page
Keep the password out of command history and process listings where possible. For a visual screenshot of a rendered, authenticated page, use a browser automation tool such as Playwright.
5. Choose capture options for the job
| Need | Playwright choice |
|---|---|
| Visible browser viewport only | Call page.screenshot({ path: 'screenshot.png' }). |
| Entire scrollable document | Set fullPage: true. |
| Wait for authenticated content | Wait for an application-specific locator or other reliable readiness condition before capture. |
| Constrain credentials | Set httpCredentials.origin to the challenged origin. |
| Reusable signed-in browser session | Use Playwright storage state when the site’s authentication uses browser state; Basic Auth may still require HTTP credentials. |
Full-page capture can produce a much taller image and take more memory than a viewport screenshot. If only one section matters, consider capturing that region through a locator screenshot where supported by your Playwright version, or capture the viewport after scrolling the target into view.
6. Credentials and reusable authentication state
HTTP Basic Authentication and Playwright’s saved browser storage state are separate mechanisms. Storage state can preserve cookies and local storage for applications that use them, but do not assume it answers an HTTP Basic Auth challenge. Configure httpCredentials for the protected origin when the server requires that challenge.
For reusable browser state, the Playwright authentication guide recommends storing files under playwright/.auth and adding that path to .gitignore. Authentication state can contain sensitive cookies and headers that could impersonate a user. Protect it like a password and keep it out of source control and build artifacts.
If parallel tests share an account, consider whether they change shared server-side state. Playwright’s guide notes that shared accounts are unsuitable when parallel tests modify shared state; separate accounts avoid that interference.
7. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The page still shows a login prompt or returns an authorization error | Username or password is wrong, credentials were configured after navigation, or the configured origin does not match the challenged origin. | Check the secret values, configure credentials on the context before goto(), and match scheme, hostname, and port. |
| The first URL works, but a redirect destination fails | The redirect lands on a different origin that also requires authentication. | Identify the final challenged origin and configure credentials for it as well, using the documented origin configuration. |
| The screenshot is blank or missing page content | The capture happened before client-side content became visible, or the readiness selector does not match the page. | Wait for a specific visible element that proves the needed content has loaded. Confirm the selector in the actual page. |
| The screenshot contains only the top of the page | The default screenshot is viewport-sized. | Set fullPage: true for the full scrollable page. |
| Secrets are missing in CI | Environment variables were not configured in the job or are unavailable to the branch or environment. | Set both variables in the CI secret manager and fail early when either is absent, as the examples do. |
| A saved authentication file appears in Git status | The state directory is not ignored. | Add playwright/.auth to .gitignore, and remove any accidentally committed sensitive file using your repository’s secret-handling process. |
| Parallel captures affect one another | Tests use the same account while changing shared server-side state. | Use distinct test accounts when parallel workers modify shared state, or serialize the affected work. |
8. Performance, reliability, and cost
For repeatable captures, wait for the smallest reliable page-specific condition rather than an unnecessarily long fixed delay. A fixed delay can waste time on fast pages and still be too short on slow ones. Full-page images are larger than viewport captures, so use the smallest capture area that meets the requirement.
Always close the browser in a finally block so it is closed even if navigation or capture fails. In a larger job, catch failures per URL, record the target and error without logging credentials, and retry only failures that are plausibly transient. A login rejection usually needs credential or origin correction rather than repeated retries.
Playwright is open-source browser automation software; operating cost depends on where the browser runs and the compute and storage used for capture. The supplied Playwright references do not provide a per-screenshot price or performance benchmark, so none is asserted here.
9. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. For pages it can access, request a screenshot with one GET call instead of installing and running a browser locally. Its screenshot API does not document an HTTP Basic Authentication credential parameter in the facts available here, so do not assume it can access a Basic Auth protected page; use the Playwright method above when the target requires that challenge.
For an accessible page, this cURL request saves a WebP screenshot. See the ScreenshotNeo API documentation for options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Cookie banners are accepted and removed, along with known newsletter popups and chat widgets, before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.
10. FAQ
Does Playwright’s HTTP credential setup create a logged-in cookie?
No. It supplies credentials for HTTP Basic Authentication challenges. Cookie-based application login is a separate flow.
Can I use a full-page screenshot with Basic Authentication?
Yes. Authenticate the context, wait for the protected content, then set fullPage: true on the screenshot call.
Can ScreenshotNeo take this screenshot without credentials?
The product facts provided do not specify Basic Authentication support, so use Playwright for a protected endpoint that requires HTTP Basic Authentication.


