microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
64.18k stars 3.49k forks source link

[QUESTION] How can I correctly resolve environment variables in Playwright tests for a React project built with Vite? #31576

Closed omelnik closed 5 days ago

omelnik commented 2 weeks ago

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 'ENV_VAR')

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

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

mxschmitt commented 1 week ago

Vite recommends import.meta.env - so I recommend changing it to that, since it seems the newer standard which supersedes process.env.

If you still want to use process.env, it looks like you could use e.g. this 3rd-party plugin. In this case it passes the API_KEY env var over:

import { defineConfig, devices } from '@playwright/experimental-ct-svelte';
import { resolve } from 'path';
import EnvironmentPlugin from 'vite-plugin-environment'

export default defineConfig({
  testDir: 'tests',
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  reporter: process.env.CI ? 'html' : 'line',
  use: {
    ctViteConfig: async () => ({
      plugins: [
        import('@vitejs/plugin-react').then(plugin => plugin.svelte()),
        EnvironmentPlugin(['API_KEY']),
      ],
    })
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
  ],
});
omelnik commented 1 week ago

Thanks, @mxschmitt, for the response. Any suggestions on how to change Playwright to use import.meta.env instead of process.env.?

mxschmitt commented 1 week ago

Playwright gets executed by Node.js which doesn't use this notion under the hood. So you'd keep using process.env for your tests while using import.meta.env for your component tests. Would that work for you?

omelnik commented 1 week ago

No, as I described in my question above, that's exactly what I have right now, and it's failing for me.

mxschmitt commented 1 week ago

When looking at your app, you have a constants.ts file, which is imported only by the playwright.config.ts. This file is executed with Node.js - so there is only process.env.MODE working.

If you want to access environment variables in your Vite build, then you need to prefix them with VITE_, see here: https://vitejs.dev/guide/env-and-mode#env-variables

I hope that helps.

dgozman commented 5 days ago

Closing since there is no action item for Playwright here. If you still encounter problems, please file a new issue by filling in the "Bug Report" template and link to this one.