Why isn't Playwright's addInitScript method working as expected?

I’m working with Playwright on a Windows 10 machine while testing a web application in Chrome 91. I’m trying to use the addInitScript method to inject a custom script into the page before any of the page’s own scripts execute. However, even though there are no errors being thrown, the injected script does not seem to take effect — the page behavior suggests that my code was never applied.

I’ve already verified the syntax and parameters, and I am calling the method in my test setup, but it still doesn’t behave as expected. I’m unsure whether this is a timing issue, navigation order problem, or something related to how Playwright handles script injection internally.

What could be causing addInitScript to not execute properly, and what is the correct way to ensure it runs before the page scripts?

A common mistake when using addInitScript is misunderstanding when it actually runs. The method injects a script after the page context is created but before any page scripts execute. However, it must be added before navigation to take effect properly.

If your script seems like it’s not executing, make sure:

You call addInitScript() before page.goto().

Your injected logic is not being overwritten by page scripts.

You are not adding it after the page has already loaded.

Example:

const { chromium } = require('playwright');

(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();

await page.addInitScript(() => {
window.someGlobalVariable = 'test';
});

await page.goto('https://example.com
');

await browser.close();
})();

In this example, the global variable is defined before the page’s own scripts run. If it still doesn’t work, inspect whether the site resets or overrides global values during execution.

If you’re working with a Single Page Application (SPA) like React, Angular, or Vue, timing can feel inconsistent. addInitScript runs on every new document load, but client-side route changes do not always trigger a full reload.

In such cases, using a browser context–level injection can be more reliable.

Example:

const { chromium } = require('playwright');

(async () => {
const browser = await chromium.launch();
const context = await browser.newContext();

await context.addInitScript({
content: "window.myInjectedScript = () => true;"
});

const page = await context.newPage();
await page.goto('https://example.com
');

const result = await page.evaluate(() => window.myInjectedScript());
console.log(result); // true

await browser.close();
})();

Key tips:

Prefer context.addInitScript() if you want it applied across multiple pages.

Ensure navigation happens after injection.

Remember that SPA route changes won’t re-trigger init scripts unless a full reload happens.