2

I'm encountering an issue with environment variable access in my tests for a project using Vite as a build tool alongside a React app. In the React app, environment variables are accessed via import.meta.env, but in our tests, we rely on process.env and .env files using the dotenv package.

I'm seeing the following error:

TypeError: Cannot read properties of undefined (reading 'MODE')

Could anyone suggest how to resolve this issue and properly access MODE within both the React app and the test environment?

# src/constants.ts

let BASE_URL: string;

const testMode = import.meta.env.MODE;

if (testMode === "testing") {
  BASE_URL = "http://testing.com";
} else if (testMode === "dev") {
  BASE_URL = "http://dev.com";
} else {
  BASE_URL = "http://production.com";
}

export { BASE_URL };
# playwright.config.ts


import { defineConfig, devices } from "@playwright/test";
import { BASE_URL as baseURL } from "./src/constants";
import dotenv from 'dotenv';

dotenv.config({ path:  '.env' });

export default defineConfig({
  testDir: "./e2e",
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: "html",
  use: {
    baseURL // using the baseURL that is used by APP as well,
    trace: "on-first-retry",
  },

});

Link to the repo with repro example: https://github.com/omelnik/playwright-vite-repro

5
  • Can you share the code in the question? Links go down over time and we want this to be a resource for future visitors with the same problem 5 years from now. Thanks.
    – ggorlen
    Commented Jul 6 at 5:59
  • Why don't you use dotenv in both React and Playwright sides?
    – I.sh.
    Commented Jul 10 at 6:45
  • @I.sh. i do use dotenv on both sides
    – username
    Commented Jul 10 at 16:24
  • does your .env file exist in root of your project where vite.config exist? have you tried importing your env data using BUN?
    – jexroid
    Commented yesterday
  • cause Bun uses a different approach for importing .env
    – jexroid
    Commented yesterday

2 Answers 2

0

Why not simply add a fallback in the constant like:

const testMode = import?.meta?.env?.MODE || process?.env?.MODE;

if (testMode === "testing") {
  BASE_URL = "http://testing.com";
}
...
2
  • I would consider it a last resort. I would rather avoid altering the app's code to accommodate that.
    – username
    Commented Jul 10 at 4:42
  • Imo, since you use import.meta.env in config file playwright.config.ts, it's better to switch to just use process.env altogether since import.meta.env isn't even available in vite.config.js file. In other words, import.meta.env is not meant to be used in config files
    – Damzaky
    Commented Jul 10 at 7:08
-2

According to Vite Docs about env variables:

To prevent accidentally leaking env variables to the client, only variables prefixed with VITE_ are exposed to your Vite-processed code. e.g. for the following env variables:

VITE_SOME_KEY=123
DB_PASSWORD=foobar

Only VITE_SOME_KEY will be exposed as import.meta.env.VITE_SOME_KEY to your client source code, but DB_PASSWORD will not.

console.log(import.meta.env.VITE_SOME_KEY) // "123"
console.log(import.meta.env.DB_PASSWORD) // undefined
1
  • How can I utilize Vite's mechanism to resolve environment variables within Playwright's import.meta.env?
    – username
    Commented Jul 10 at 4:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.