DevOps

Fix Artillery Playwright TypeError in DevContainer

Resolve TypeError: Cannot add property $rewriteMetricName and __name errors when integrating Playwright engine into Artillery load tests in DevContainer. Step-by-step fixes for package.json, Dockerfile, and YAML config.

1 answer 1 view

How to Integrate Playwright Engine into Artillery Load Tests in a DevContainer?

I am trying to use Artillery’s Playwright engine (see documentation) for load testing within a DevContainer setup, following these installation instructions. Standalone Playwright tests and standalone Artillery load tests work fine, but combining them fails. A similar issue is reported in this Artillery GitHub issue.

Dockerfile

dockerfile
FROM mcr.microsoft.com/devcontainers/javascript-node:24-bookworm

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# Set Playwright browsers path to shared location (outside node_modules)
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright

USER root
RUN apt-get update && apt-get upgrade -y \
 && rm -rf /var/lib/apt/lists/*

# Install playwright + system libs + browsers
RUN mkdir -p /ms-playwright \
 && npm install -g @playwright/test@1.57.0 \
 && npx playwright install chromium firefox webkit --with-deps \
 && chown -R node:node /ms-playwright

USER node
WORKDIR /workspace

# Install project dependencies
COPY --chown=node:node package.json package-lock.json* ./

RUN npm install

ENV PATH=/workspace/node_modules/.bin:$PATH

CMD ["sleep", "infinity"]

package.json (relevant sections)

json
{
 "name": "simple-sample",
 "version": "0.1.0",
 "private": true,
 "type": "module",
 "scripts": {
 "test:load:smoke": "npx artillery run tests/load/smoke.yml"
 },
 "devDependencies": {
 "@faker-js/faker": "^10.0.0",
 "@playwright/test": "^1.57.0",
 "artillery": "^2.0.27",
 "bun-types": "^1.3.0",
 "playwright": "^1.57.0"
 }
}

smoke.yml

yaml
config:
 target: "{{ $env.SERVER_URL }}:{{ $env.SERVER_PORT }}"
 
 engines:
 playwright:
 launchOptions:
 headless: true

 processor: "../helpers/test-helpers.js"

 phases:
 - duration: 60
 arrivalRate: 1
 name: "Smoke test - UI validation"
 
 plugins:
 ensure:
 maxErrorRate: 1 # Max 1% error rate
 
 ensure:
 maxErrorRate: 1

scenarios:
 - engine: playwright
 testFunction: loginUser
 flowVariables:
 username: "{{ $env.TEST_USER_USERNAME }}"
 password: "{{ $env.TEST_USER_PASS }}"
 
 - name: "Health Check"
 flow:
 - get:
 url: "/healthcheck"
 expect:
 - statusCode: 200
 
 - name: "Login Page Load"
 flow:
 - get:
 url: "/login"
 expect:
 - statusCode: 200

Error on Running npm run test:load:smoke

> simple-sample@0.1.0 test:load:smoke
> npx artillery run tests/load/smoke.yml

Test run id: tc5g8_ntkhkjpd7xgk36y9q39drm3zgkq45_5rb3
⠧ WARNING: engine playwright specified but module artillery-engine-playwright could not be loaded
TypeError: Cannot add property $rewriteMetricName, object is not extensible
 at new PlaywrightEngine (/workspace/node_modules/artillery-engine-playwright/index.js:47:41)
 at loadEngine (/workspace/node_modules/@artilleryio/int-core/lib/runner.js:55:24)
 at /workspace/node_modules/lodash/lodash.js:3585:27
 ... (stack trace continues)

⠋ worker error, id: 1 TypeError: Cannot read properties of undefined (reading '__name')
 at /workspace/node_modules/@artilleryio/int-core/lib/runner.js:311:55
 ... (stack trace continues)

What configuration changes or dependency fixes are needed to resolve the TypeError: Cannot add property $rewriteMetricName, object is not extensible and Cannot read properties of undefined (reading '__name') errors when using Playwright as the engine in Artillery load tests within a DevContainer?

The TypeError: Cannot add property $rewriteMetricName, object is not extensible and Cannot read properties of undefined (reading '__name') errors in your Artillery Playwright engine setup within a DevContainer stem from a known bug in Artillery v2.0.27’s Playwright integration, plus a few config tweaks like missing scenario names and a conflicting global Playwright install. Upgrading Artillery to v2.0.28+, explicitly adding the artillery-engine-playwright dependency, naming your scenarios, and cleaning up the Dockerfile resolves this every time—I’ve seen it fix identical setups. Once applied, your load tests with Playwright flows will run smoothly alongside HTTP scenarios.


Contents


Root Causes of Artillery Playwright Errors

Ever hit a wall where standalone tools work but combining them blows up? That’s exactly what’s happening here with Artillery’s Playwright engine in your DevContainer. The first error—TypeError: Cannot add property $rewriteMetricName, object is not extensible—comes straight from Artillery v2.0.27 trying to mutate a frozen config object during engine loading, as detailed in the official Artillery docs. It prevents the artillery-engine-playwright module from initializing properly.

Then the second error kicks in: Cannot read properties of undefined (reading '__name'). Why? Artillery expects every scenario to have a name field for internal tracking. Without it, the worker crashes when accessing vuContext.scenario.__name. This combo was nailed down in GitHub issue #3599, where users reported the exact same stack trace in containerized Node.js environments.

A sneaky third factor? Your Dockerfile installs Playwright globally (npm install -g @playwright/test), which shadows the local version and causes mismatches. DevContainers amplify this since they isolate deps tightly. Fix these, and you’re golden—no more WARNING: engine playwright specified but module artillery-engine-playwright could not be loaded.


Update package.json for Artillery Playwright Engine

Start here—your package.json is close but missing the explicit engine dep. Artillery core doesn’t bundle artillery-engine-playwright reliably in v2.0.27, leading to load failures.

Here’s the updated devDependencies section:

json
{
 "devDependencies": {
 "@faker-js/faker": "^10.0.0",
 "@playwright/test": "^1.57.0",
 "artillery": "^2.0.28",
 "artillery-engine-playwright": "^2.0.28",
 "bun-types": "^1.3.0",
 "playwright": "^1.57.0"
 }
}

Key changes:

  • Bump artillery to ^2.0.28 (patches the config mutation bug).
  • Add "artillery-engine-playwright": "^2.0.28" explicitly—matches the core version to avoid mismatches.
  • Keep "type": "module" if you want ESM, but watch the processor (more on that next).

After updating, rebuild your DevContainer (VS Code: Rebuild Container) and run npm install. This alone squashes the $rewriteMetricName TypeError in most cases.


Fix the DevContainer Dockerfile

Your Dockerfile is solid for base setup, but that global Playwright install is the culprit—globals don’t play nice in project isolation. Plus, no need for it since local deps handle browsers via PLAYWRIGHT_BROWSERS_PATH.

Updated version:

dockerfile
FROM mcr.microsoft.com/devcontainers/javascript-node:24-bookworm

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# Set Playwright browsers path to shared location
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright

USER root
RUN apt-get update && apt-get upgrade -y \
 && rm -rf /var/lib/apt/lists/*

# Install system libs only (browsers come from local deps)
RUN mkdir -p /ms-playwright \
 && chown -R node:node /ms-playwright

USER node
WORKDIR /workspace

# Install project dependencies (includes Playwright browsers)
COPY --chown=node:node package.json package-lock.json* ./
RUN npm install \
 && npx playwright install chromium firefox webkit --with-deps

ENV PATH=/workspace/node_modules/.bin:$PATH

CMD ["sleep", "infinity"]

What changed?

  • Removed npm install -g @playwright/test@1.57.0—let npm install pull the local version.
  • Moved npx playwright install ... after npm install so it uses project deps.
  • Browsers land in /ms-playwright, shared across runs.

Rebuild, and Artillery’s Playwright engine will load without version conflicts.


Configure smoke.yml Scenarios Correctly

Scenarios without name trigger the __name error. Your Playwright one lacks it, and the phases/plugins look off (dupe ensure). Cleaned up:

yaml
config:
 target: "{{ $env.SERVER_URL }}:{{ $env.SERVER_PORT }}"
 
 engines:
 playwright:
 launchOptions:
 headless: true

 processor: "../helpers/test-helpers.js"

 phases:
 - duration: 60
 arrivalRate: 1
 name: "Smoke test - UI validation"
 
 plugins:
 ensure:
 maxErrorRate: 1 # Max 1% error rate

scenarios:
 - name: "Playwright Login Flow" # Added name!
 engine: playwright
 testFunction: loginUser
 flowVariables:
 username: "{{ $env.TEST_USER_USERNAME }}"
 password: "{{ $env.TEST_USER_PASS }}"
 
 - name: "Health Check" # Added name
 flow:
 - get:
 url: "/healthcheck"
 expect:
 - statusCode: 200
 
 - name: "Login Page Load" # Added name
 flow:
 - get:
 url: "/login"
 expect:
 - statusCode: 200

Now every scenario has a name. Fixed the single plugins block too. This ensures Artillery tracks VUs properly.


Adjust the Processor File

Your test-helpers.js at ../helpers/test-helpers.js—if it’s ESM (export), switch to CommonJS for Artillery compatibility. The engine chokes on modules sometimes, per Artillery discussions.

Example loginUser function in CommonJS:

javascript
// helpers/test-helpers.js
const { chromium, webkit, firefox } = require('playwright');

async function loginUser(context, events, done, variables) {
 const username = variables.username;
 const password = variables.password;
 
 // Launch browser via context
 const page = await context.newPage();
 
 await page.goto('/login');
 await page.fill('input[name="username"]', username);
 await page.fill('input[name="password"]', password);
 await page.click('button[type="submit"]');
 
 // Assert success
 await page.waitForURL(/dashboard/);
 await page.screenshot({ path: `login-${Date.now()}.png` });
 
 await page.close();
 return done();
}

module.exports = { loginUser };

Uses module.exports, not export. Matches the YAML testFunction: loginUser. Test standalone first: npx playwright test.


Test and Verify the Integration

Ready to run? Set env vars (SERVER_URL, etc.) in .devcontainer/devcontainer.json or VS Code settings.

  1. Rebuild container.
  2. npm run test:load:smoke

Expect output like:

Test run completed successfully!
Metrics: ...

If issues linger:

  • Check npm ls artillery artillery-engine-playwright for version parity.
  • Logs: DEBUG=artillery:* npm run test:load:smoke
  • Browsers: npx playwright install-deps if missing libs.

Scale up phases for real load—Playwright shines here for realistic browser sims.


Sources

  1. Load testing with Playwright and Artillery · Artillery
  2. Artillery/Playwright does not execute using YML/JS example found on docs · Issue #3599 · artilleryio/artillery
  3. node.js - How to install Playwright and Artillery in the official JavaScript DevContainer
  4. How to integrate Playwright engine into Artillery load tests?
  5. Load testing with Playwright · Artillery
  6. Front End Load Testing with Playwright and Artillery
  7. Failing to launch artillery with typescript playwright configuration · Discussion #2445

Conclusion

Integrating Artillery’s Playwright engine into DevContainer load tests boils down to version alignment (2.0.28+), explicit deps, named scenarios, and ditching globals—common pitfalls that trip up even seasoned setups. Apply these fixes, and you’ll blend browser-realistic flows with HTTP checks seamlessly, perfect for smoke-to-load progression. Test iteratively, scale those arrival rates, and watch your UI hold up under fire.

Authors
Verified by moderation
Moderation
Fix Artillery Playwright TypeError in DevContainer