Search code examples
reactjsreact-testing-libraryplaywrightplaywright-test

Process.env not accessible while writing playwright-ct component testing?


I am using playwright for component testing, I have a following dir. structure in my next.js project.

./playwright
 - component
     ./ MyComponent.spec.tsx
     ./ MyComponent.tsx
     ./ index.html
 - fixtures
 - index.ts

Unfortunately process.env is not accessible in MyComponent.tsx?

I can access them in MyComponent.spec.tsx.

How I am loading them at the moment is e.g -

import dotenv from 'dotenv';

dotenv.config({ path: './env/.env.test', override: true });

in. playwright-ct-config.ts

My concern is to load them in MyComponent.tsx.


Solution

  • I found the solution to this problem, seems like it very important concept when it comes to playwright-component testing.

    The test runs in the Node.js process while the component is created inside a real browser in a separate process. process is not a part of Web API, this is why you can't access it from your component. You can use page.evaluate() to run javascript code in the browser context:

    test.beforeEach(async ({ page }) => {
      await page.evaluate(() => (window as any).TEST_ENV_VAR = 'test_value');
    });
    
    test('should work', async ({ mount }) => {
      const component = await mount(<App />);
      await expect(component).toContainText('Test');
    });
    

    and then in your component:

    export const MyComponent = () => {
      const { shareEvent } = useAnalytics();
    
      console.log('TEST_ENV_VAR = ' + (window as any).TEST_ENV_VAR);
    
      return (
        <>
          <button onClick={() => shareEvent("PDP")}>shareEvent</button>
        </>
      );
    };
    

    I have extended this research further nevertheless you can also pass .env variables as an OBJ and then assign it to window.env inside page.evaluate().

    Something like this:

    test.beforeAll(async ({ page, mount }) => {
      const next_app_analytics_enviroment = {
        analytics_url: process.env.NEXT_PUBLIC_ANALYTICS_ENVIRONMENT,
      };
    
      await page.evaluate((next_app_analytics_enviroment) => {
        (window as any).ANALYTICS_URL = analytics_url;
      }, next_app_analytics_enviroment);
    
    });