Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

The short answer: Mocha does not read playwright.config.ts as Playwright Test does. A Mocha test that imports the standalone playwright package must load environment variables itself and pass browser or context options to chromium.launch() and browser.newContext(). If you depend on Playwright fixtures, projects, use, retries, or webServer, run the suite with npx playwright test instead.

Why Mocha ignores playwright.config.ts

There are two different execution models that happen to use Playwright browsers:

  • Playwright Test: the @playwright/test runner discovers playwright.config.ts. It applies runner settings such as testDir, projects, reporter, retries, workers and webServer at the top level. Browser and context defaults, including baseURL and storageState, belong under use.
  • Standalone Playwright: a Mocha test normally imports playwright, calls chromium.launch(), creates a context and opens a page. This library API does not search for or merge Playwright Test configuration files.

Having a file named playwright.config.ts in the repository therefore does not make its values global. A Mocha command such as npx mocha starts Mocha, not the Playwright Test runner.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose the correct fix

Use Playwright Test when you need Playwright configuration

Move or keep the suite as Playwright Test tests if it uses fixtures, projects, use.baseURL, storageState, retries, or a configured web server. A minimal configuration is:

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    baseURL: process.env.BASE_URL,
  },
});

Run it with:

npx playwright test

Tests then receive the configured context through the runner. For example:

import { test, expect } from '@playwright/test';

test('opens the configured URL', async ({ page }) => {
  await page.goto('/login');
  await expect(page).toHaveTitle(/Sign in/);
});

Do not launch the same file with mocha and expect the use block to be applied.

Keep Mocha when the suite must remain Mocha

In Mocha, load configuration in the Mocha process, then pass the resulting values explicitly to Playwright. This is the reliable replacement for expecting playwright.config.ts to be consumed automatically.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Working Mocha setup with dotenv

Install the required packages if they are not already present:

npm install --save-dev mocha playwright dotenv

Put environment loading in a setup module. The important order is dotenv first, process.env second, browser construction third.

// test/setup.js
const path = require('node:path');
require('dotenv').config({
  path: path.resolve(__dirname, '../../.env'),
});

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

exports.baseURL = process.env.BASE_URL;

exports.createBrowser = () => chromium.launch({
  headless: process.env.HEADLESS !== 'false',
});

The absolute path matters when the command is run from a subdirectory or the dotenv file is outside the current working directory. Adjust the number of .. segments to match your project.

A complete Mocha test can consume those exported values:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
// test/example.spec.js
const assert = require('node:assert/strict');
const { createBrowser, baseURL } = require('./setup');

let browser;

before(async () => {
  if (!baseURL) throw new Error('BASE_URL is not set');
  browser = await createBrowser();
});

after(async () => {
  await browser.close();
});

test('opens the configured URL', async () => {
  const page = await browser.newPage();
  await page.goto(baseURL);
  assert.equal(await page.title(), 'Expected title');
});

For context-level settings, create a context with the options that would otherwise have been placed under use:

const context = await browser.newContext({
  baseURL,
  storageState: process.env.STORAGE_STATE,
  locale: process.env.LOCALE || 'en-US',
});
const page = await context.newPage();
await page.goto('/dashboard');

Remember the distinction: launch options belong to chromium.launch(); context options belong to browser.newContext(). A baseURL passed to neither call cannot affect navigation.

Use environment variables safely and predictably

Verify the exact name

Environment keys are case-sensitive. BASE_URL, Base_URL and baseUrl are different variables. Check the value immediately before handing it to Playwright, but avoid printing credentials:

const resolved = process.env.BASE_URL;
console.log({
  hasBaseURL: Boolean(resolved),
  baseURL: resolved ? new URL(resolved).origin : undefined,
});

Do not log complete URLs if they contain tokens, query credentials or signed parameters.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Load dotenv before importing modules that read the variable

If another module evaluates process.env.BASE_URL during import, calling dotenv.config() afterward is too late for that module. Put require('dotenv').config(...) at the top of the Mocha entry point or use a dedicated setup file that Mocha loads first. In ESM, the equivalent is:

// test/setup.mjs
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import dotenv from 'dotenv';

const here = path.dirname(fileURLToPath(import.meta.url));
dotenv.config({ path: path.resolve(here, '../../.env') });

Then import modules that read the variables.

Set variables in the shell or CI

For a one-off Bash run:

BASE_URL=https://test.example npm test

In PowerShell:

$env:BASE_URL='https://test.example'
npm test

CI systems must export the variable into the process that invokes Mocha. A value configured in a different job, container, or step is not automatically available.

Mocha configuration is separate

Mocha has its own configuration discovery. It can read a local configuration file, search parent directories when no local file is found, or be told exactly which file to use. Pin the intended file when discovery is uncertain:

npx mocha --config .mocharc.cjs

You can deliberately disable discovery with:

npx mocha --no-config

A Mocha configuration can load setup code, but it still does not transform that setup into Playwright Test configuration:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
// .mocharc.cjs
module.exports = {
  require: ['test/setup.js'],
  extension: ['js'],
  timeout: 30000,
};

Check package.json scripts to see which runner actually executes. npx playwright test and npx mocha are not interchangeable commands.

Translate common Playwright Test settings for Mocha

Playwright Test setting Standalone Mocha equivalent
use.baseURL Pass baseURL to browser.newContext(), then navigate with relative paths.
use.storageState Pass storageState when creating the context.
use.headless Pass headless to chromium.launch().
use.viewport, locale, timezone Pass the corresponding options to browser.newContext().
projects Create separate Mocha runs or explicitly launch each browser/context configuration.
webServer Start the application separately in an npm script or CI step and wait for it before Mocha.
fixtures Implement Mocha hooks and helper functions, or migrate the tests to Playwright Test.
retries and workers Use Mocha’s own retry/parallel options; they do not come from playwright.config.ts.

Diagnostic checklist

  1. Identify the runner. Read the script in package.json. If it says mocha, Playwright Test configuration is not being applied.
  2. Check the import. playwright is the library API. @playwright/test is the test runner and fixture API. A Mocha file using the former must create its own browser and context.
  3. Confirm dotenv timing. Load dotenv before importing configuration modules and before reading process.env.
  4. Confirm the path. Anchor nonstandard dotenv locations with path.resolve(__dirname, ...) rather than relying on the current directory.
  5. Confirm the key and value. Check spelling, capitalization and whether CI exported the variable.
  6. Confirm option placement. Launch options go to chromium.launch(); URL, state and browser-context defaults go to browser.newContext().
  7. Pin Mocha’s config. Use --config if the intended .mocharc file is not being selected.
  8. Turn on diagnostics. Use DEBUG=pw:api mocha for Playwright API activity or DEBUG=pw:browser mocha for browser-launch failures. Keep secrets out of debug output.

Common symptoms and fixes

baseURL is undefined

Usually dotenv was not loaded, the path is wrong, or the variable name differs. Log only a boolean and safe origin, then pass the value in newContext({ baseURL }).

Relative navigation fails

page.goto('/login') requires a context baseURL. Without it, use an absolute URL or create the context with the resolved base URL.

The browser starts with the wrong headless mode

Mocha does not inherit use.headless. Convert the environment value explicitly. For example, process.env.HEADLESS !== 'false' makes headless the default and allows HEADLESS=false for local debugging.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Configuration works locally but not in CI

Compare the working directory, dotenv path and exported variables. A local .env file may exist while CI intentionally has none. Set the variable in the CI job and verify its presence without printing secrets.

Mocha reports an unexpected timeout

Mocha’s timeout is independent of Playwright Test’s timeout settings. Set it in .mocharc.cjs or with --timeout, and configure Playwright action or navigation timeouts on the context or page as needed.

Browser launch fails before a test runs

Run with DEBUG=pw:browser mocha. Inspect the launch output, verify that the required browser is installed, and check executable or sandbox settings in the CI environment.

Performance, reliability and maintenance

  • Create one browser per Mocha process and close it in an after hook; create isolated contexts per test or suite.
  • Validate required configuration at startup so a missing URL fails before expensive browser work.
  • Keep secrets in CI variables or a protected dotenv file, never in source control or debug logs.
  • Use an explicit setup module and a single configuration boundary. Scattered reads of process.env make timing and overrides difficult to reason about.
  • If you need projects, fixtures, automatic retries, trace settings or web-server orchestration, migration to Playwright Test generally removes more custom code than reproducing those features in Mocha.
  • If Mocha is mandatory because of an existing test ecosystem, treat Playwright as a library and document every option passed to launch and context creation.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is simply to obtain a reliable screenshot of a URL rather than maintain a browser test, ScreenshotNeo provides a single HTTP request. 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. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use the API documentation at https://screenshotneo.com/docs/ for all options:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python:

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)

Node.js:

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 also offers an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. It supports PNG, JPEG, WebP and PDF output, full-page and element capture, device presets, retina scale, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting and an OpenAPI specification. Existing parameter names used by other screenshot APIs also work.

The Free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.

Final decision

Use npx playwright test when you want playwright.config.ts to control the suite. Use Mocha only as a separate runner: load dotenv before reading variables, pass launch and context options explicitly, and select Mocha’s own config with --config when necessary. That runner boundary is the reason the values appeared to be missing.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can Mocha execute a Playwright Test file directly?

Not with Playwright Test fixtures and configuration semantics. Run that file with the Playwright Test runner or rewrite it to use standalone Playwright APIs and Mocha hooks.

Should baseURL be passed to launch or newContext?

Pass baseURL to browser.newContext(). chromium.launch() is for browser-process options such as headless mode.

Does –config in Mocha select playwright.config.ts?

No. Mocha’s –config selects a Mocha configuration file. It does not make Mocha consume Playwright Test configuration.

Why does changing .env not affect an already imported module?

That module may have read process.env during import. Load dotenv before importing modules that evaluate configuration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.