PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchRead the JSON in your test process, create the browser context, and register context.addInitScript() before opening or navigating the page. The init script copies each JSON entry into window.sessionStorage before the application’s scripts run. Playwright’s normal storageState mechanism does not persist session storage; this is the documented workaround in the authentication guide.
The working pattern
Assume playwright/.auth/session.json contains an object such as:
{
"onboardingComplete": "true",
"draftId": "abc-123",
"preferences": "{"theme":"dark"}"
}
Load and parse that file, then pass the object to an init script. This complete TypeScript example limits writes to the intended hostname:
import fs from 'node:fs';
import { chromium } from 'playwright';
const sessionStorage = JSON.parse(
fs.readFileSync('playwright/.auth/session.json', 'utf-8'),
);
const browser = await chromium.launch();
const context = await browser.newContext();
await context.addInitScript((storage) => {
if (window.location.hostname !== 'example.com') return;
for (const [key, value] of Object.entries(storage)) {
window.sessionStorage.setItem(key, String(value));
}
}, sessionStorage);
const page = await context.newPage();
await page.goto('https://example.com/');
await browser.close();
The same sequence works in JavaScript after removing the TypeScript-only annotations. Register the script before newPage() and before any navigation that needs the values. addInitScript runs after a document is created but before that document’s own scripts execute, and it applies to pages created in the context and to subsequent navigations. The BrowserContext API reference also documents that init scripts can run in child frames.
Recommended Free Tools
#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
Prepare the JSON correctly
Use an object of key/value pairs
The code expects the top-level JSON value to be an object. An array, a nested export such as {"sessionStorage": {...}}, or malformed JSON will not produce the entries the loop expects. If your export is nested, select the correct property before calling addInitScript:
const file = JSON.parse(fs.readFileSync(fileName, 'utf8'));
const sessionStorage = file.sessionStorage ?? file;
Remember that Web Storage stores strings
sessionStorage.setItem() stores strings. Calling String(value) turns a number into text and turns a boolean into "true" or "false". For objects and arrays, that conversion becomes "[object Object]", which is usually not what an application expects. Serialize structured values deliberately:
await context.addInitScript((storage) => {
if (window.location.hostname !== 'example.com') return;
for (const [key, value] of Object.entries(storage)) {
const text = value !== null && typeof value === 'object'
? JSON.stringify(value)
: String(value);
window.sessionStorage.setItem(key, text);
}
}, sessionStorage);
If the application expects JSON, it will normally call JSON.parse(sessionStorage.getItem('preferences')); store the corresponding JSON string, not a JavaScript object.
Scope the script to the right origin
Session storage is isolated by origin (scheme, host, and port) and by the page’s storage context. A value seeded for https://example.com is not automatically available at another scheme, port, or unrelated host. The official example uses a hostname check:
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsif (window.location.hostname !== 'example.com') return;
Use a stricter guard when your test visits several environments:
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
const allowedOrigins = new Set([
'https://staging.example.com',
'https://app.example.com',
]);
await context.addInitScript((storage, origins) => {
if (!origins.includes(window.location.origin)) return;
for (const [key, value] of Object.entries(storage)) {
window.sessionStorage.setItem(key, String(value));
}
}, sessionStorage, [...allowedOrigins]);
Do not seed every page in a context indiscriminately. A broad script can leak test data into a third-party frame or a different application visited later. If a site uses several subdomains, decide explicitly whether each exact origin should receive the values. Child frames are also candidates for init-script execution, so the guard matters there as well.
Use it with Playwright Test
In the test runner, install the script on the supplied context fixture before navigating:
import { test as base, expect } from '@playwright/test';
import fs from 'node:fs';
type SessionStorage = Record<string, unknown>;
const sessionStorage: SessionStorage = JSON.parse(
fs.readFileSync('playwright/.auth/session.json', 'utf8'),
);
export const test = base.extend({
page: async ({ context, page }, use) => {
await context.addInitScript((storage) => {
if (window.location.hostname !== 'example.com') return;
for (const [key, value] of Object.entries(storage)) {
window.sessionStorage.setItem(key, String(value));
}
}, sessionStorage);
await use(page);
},
});
export { expect };
// example.spec.ts
import { test, expect } from './fixtures';
test('opens with the saved session data', async ({ page }) => {
await page.goto('https://example.com/dashboard');
await expect(page).toHaveURL(/dashboard/);
});
Alternatively, call context.addInitScript in a beforeEach hook before page.goto. The runner’s storageState option remains useful for cookies and supported origin storage, but it is not a session-storage snapshot. See the TestOptions API for the runner option.
Capture a session-storage file for later reuse
The official authentication guide demonstrates the reverse operation: evaluate sessionStorage in the page, serialize it, and save the result. A minimal capture looks like this:
import fs from 'node:fs';
import { chromium } from 'playwright';
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com/');
const json = await page.evaluate(() => JSON.stringify(sessionStorage));
fs.mkdirSync('playwright/.auth', { recursive: true });
fs.writeFileSync('playwright/.auth/session.json', json);
await browser.close();
This is an advanced workflow. The documentation notes that session storage is rarely used for signed-in state; authentication is often represented by cookies, local storage, or another mechanism. Inspect the application before deciding that this file is the state you need.
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
How this differs from storageState
| State or API | What it is suitable for | Session-storage JSON loaded automatically? |
|---|---|---|
storageState |
Reusable cookies and the storage types documented by Playwright’s authentication flow | No |
context.addInitScript |
Writing selected values into window.sessionStorage before application code |
Yes, when you read and pass the JSON yourself |
page.evaluate |
Reading or changing storage after a document exists | It is too late for code that already read storage during startup |
Playwright’s authentication documentation explicitly says it has no API to persist session storage and supplies the init-script approach. Newer adjacent APIs do not remove that limitation: the current references list BrowserContext.setStorageState in v1.59, IndexedDB capture in v1.51, WebStorage APIs in v1.61, WebAuthn credential capture in v1.61, and OPFS capture in v1.63. Those version numbers describe the referenced APIs; they do not turn storageState into a session-storage importer.
Security and maintenance precautions
- Treat the JSON as a credential. Tokens, identifiers, or setup state can impersonate a user. Playwright warns against committing saved authentication state to public or private repositories; apply the same rule to session-storage files.
- Put the file in an ignored directory such as
playwright/.auth, restrict its permissions in CI, and provide it through a secret or setup step. - Use a separate test account and short-lived data where possible. Delete or rotate exports when a run is complete.
- Validate the shape before injecting it. Reject unexpected keys rather than silently loading an entire untrusted JSON document.
- Keep one context per independent state. Session storage is context/page state, so reusing a context between unrelated tests can create order-dependent failures.
Troubleshooting
The application still behaves as logged out
Check whether login is actually held in cookies, local storage, IndexedDB, or a server-side session. Session storage alone may not be sufficient. If the app redirects before your expected origin, the guard may never match; log page.url() and inspect the final origin.
The values appear only after a reload
The script was probably registered after the first navigation, or the values were written with page.evaluate after startup. Register addInitScript before newPage() or before the navigation, then create a fresh page or reload.
Nothing is written
Print the parsed keys in the Node process and verify the file path and encoding. In the browser, check window.location.origin and compare it with your guard. A hostname-only guard will not distinguish ports; use an exact origin set when necessary.
Objects come back as [object Object]
That is JavaScript’s ordinary string conversion. Store nested values with JSON.stringify and parse them in the application, or export the exact string representation the application expects.
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
A frame receives the wrong values
Init scripts can run in child frames. Narrow the origin check and, if necessary, avoid navigating third-party frames in the same context. Do not assume a top-level-page check protects every frame.
Parallel tests interfere
Do not mutate shared JSON or share a context between tests that require different session data. Create isolated contexts, and make each fixture deterministic. A cache of the parsed file in the Node process is safe; a shared browser context is often not.
The JSON file is rejected or empty
Run JSON.parse on the file in the test process and report the parse error before launching the browser. Confirm that the capture step completed after the page had initialized its storage and that the file was not truncated by a failed setup job.
Performance and reliability notes
The init script performs one synchronous-looking loop in the page for each stored key. Keep the export limited to values the test actually needs; large blobs increase document-start work and make failures harder to diagnose. Registering one script per context is preferable to repeatedly adding scripts for every navigation. If a test needs different state, create another context or use a separate fixture rather than conditionally overwriting keys after the app has started.
For reproducibility, record the target origin, the export timestamp, and the application version alongside the secret file outside version control. Expired tokens and server-side sessions can make a technically correct injection fail, so refresh the state through the application’s supported login/setup flow when it expires.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Or skip the browser setup
If your separate goal is to obtain a clean image or PDF of a page after your test has prepared it, ScreenshotNeo is a website screenshot API—not a replacement for Playwright session-state injection. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with the result identified by X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
One GET request is enough:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for parameters and response details. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is included on every plan. Sign up for the free plan.
Practical checklist
- Parse a top-level JSON object in the Node test process.
- Register
context.addInitScriptbefore creating or navigating the page. - Guard the exact origin(s) that should receive the data.
- Convert values to the strings the application expects.
- Use
storageStateseparately for cookies and other supported state. - Keep session files secret and isolate browser contexts between independent tests.
Frequently Asked Questions
Can I pass the JSON filename directly to Playwright?
No. Read and parse the file in your test process, then pass the resulting object to an init script.
Will this work for every tab in a context?
The script is installed for pages created in that context and for their navigations, subject to your origin guard.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Should I use session storage for login state?
Only if the application actually stores the required state there. Playwright’s guide notes that signed-in state is often represented by cookies or other storage instead.
Can I use a hostname guard for multiple ports?
Use an exact window.location.origin allowlist when ports, schemes, or subdomains differ.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

