skip to Main Content

During Playwright api test i’am not able to read API_URL value for specified env in test.

my global-setup:

import * as dotenv from 'dotenv';
import fs from 'fs/promises';
import path from 'path';

interface User {
  username: string;
  password: string;
  cis: string;
  debitCard: string;
}

interface BankAccount {
  accountNumber: string;
  title: string;
}

interface TransferTitles {
  [key: string]: string;
}

export let CONFIG: {
  BASE_URL: string;
  API_URL: string;
  ENV: string;
  USERS: User[];
  BANK_ACCOUNTS: BankAccount[];
  COMMON_TRANSFER_TITLES: TransferTitles;
} = {
  BASE_URL: '',
  API_URL: '',
  ENV: '',

};

async function globalSetup(): Promise<void> {
  const environment = process.env.ENV || 'uat';
  console.log(`Loading environment: ${environment}`);
  const envPath = path.resolve(__dirname, `../../.env.${environment}`);
  console.log(`Loading .env file from: ${envPath}`);
  dotenv.config({ path: envPath, override: true });
  console.log(`Loaded BASE_URL from .env: ${process.env.BASE_URL}`);
  console.log(`Loaded API_URL from .env: ${process.env.API_URL}`);

  CONFIG = {
    BASE_URL: process.env.BASE_URL ?? '[NOT SET]',,
    API_URL: process.env.API_URL ?? '[NOT SET]',
    ENV: environment,
    COMMON_TRANSFER_TITLES: {},
    USERS: [],
    BANK_ACCOUNTS: [],
  };

  try {
    const commonDataPath = path.resolve(__dirname, './COMMON/commonData.json');
    const commonData = await fs.readFile(commonDataPath, 'utf8');
    const parsedCommonData = JSON.parse(commonData);
    CONFIG.COMMON_TRANSFER_TITLES = parsedCommonData.transferTitles;
    console.log('Common data loaded successfully.');
  } catch (error) {
    console.error('Error loading common data:', error);
    throw new Error('Failed to load common data');
  }

  try {
    const testDataPath = path.resolve(__dirname, `./${environment}/testData-${environment}.json`);
    const testData = await fs.readFile(testDataPath, 'utf8');
    const parsedTestData = JSON.parse(testData);
    CONFIG.USERS = parsedTestData.users;
    CONFIG.BANK_ACCOUNTS = parsedTestData.bankAccounts;
    console.log(`${environment} data loaded successfully.`);
  } catch (error) {
    console.error(`Error loading ${environment} data:`, error);
    throw new Error(`Failed to load ${environment} data`);
  }

  console.log('Global setup completed. Configuration and test data loaded.');
  console.log(`Final BASE_URL in CONFIG: ${CONFIG.BASE_URL}`);
  console.log(`Final API_URL in CONFIG: ${CONFIG.API_URL}`);

  global.CONFIG = CONFIG;
}

export default globalSetup;

my api_requests file in utils

import { CONFIG } from './global-setup';
import { APIRequestContext } from '@playwright/test';

const headersUnblock = {
  'sim-state': 'UNKNOWN',
  'device-flag-vpn': 'true',
  'os-type': 'iOS',
};

console.log('CONFIG.API_URL at top level:', CONFIG.API_URL);

export const putUnblockRequest = async (request: APIRequestContext): Promise<any> => {
  console.log('CONFIG.API_URL inside function:', CONFIG.API_URL);
  const baseApiUrl = CONFIG.API_URL;
  const path = '/my/path';
  const url = `${baseApiUrl}${path}`;
  console.log('Full URL:', url);
  const response = await request.fetch(url, {
    method: 'PUT',
    headers: headersUnblock,
  });
  console.log('Response:', response);
  return response;
};

My api.spec.ts file:


import { putUnblockRequest } from '../../src/utils/api_requests';
import { expect, request as pwRequest, test } from '@playwright/test';
import { CONFIG } from '../../src/utils/global-setup';
console.log('CONFIG after import:', CONFIG);

test.describe('API Tests', () => {
  let request: any;

  test.beforeAll(async ({ playwright }) => {
    request = await pwRequest.newContext({
      extraHTTPHeaders: {},
    });
  });

  test.afterAll(async () => {
    await request.dispose();
  });

  

  test.only('PUT request to unblock all channels', async () => {
    console.log('CONFIG.API_URL BEFORE calling putUnblockRequest:', CONFIG.API_URL);
    const response = await putUnblockRequest(request);
    expect(response.status()).toBe(204);
  });
});

Why i’am not able to perform API test? – my url from api_requests
I tried everything atm I lost my CONFIG.API_URL when i’am entering into function it is avaliable when try to console.log(‘CONFIG.API_URL at top level:’, CONFIG.API_URL);

 const baseApiUrl = CONFIG.API_URL;
  const path = '/my/path';
  const url = `${baseApiUrl}${path}`;

is always just /my/path

2

Answers


  1. Chosen as BEST ANSWER

    Ok, i managed to do it by myself, solution was so easy. Need to add await for globalSetup() in test

      test.beforeAll(async ({ playwright }) => {
    await globalSetup();
    request = await pwRequest.newContext({
      extraHTTPHeaders: {},
    });
    

    });


  2. Looks like the problem is that you are reassigning the exported value CONFIG in your globalSetup function:

    CONFIG = {
      BASE_URL: process.env.BASE_URL ?? '[NOT SET]',,
      API_URL: process.env.API_URL ?? '[NOT SET]',
      ENV: environment,
      COMMON_TRANSFER_TITLES: {},
      USERS: [],
      BANK_ACCOUNTS: [],
    };
    

    While this statement changes the value of CONFIG inside globalSetup, it does not overwrite the cached exported CONFIG that you’re importing into your spec files.

    Maybe just put the config into its own module and don’t try to initialize it via the globalSetup hook. For example:

    // config.ts
    
    // Call dotenv.load, read values from data files, etc. ...
    
    export default {
      API_URL: process.env.API_URL,
      BASE_URL: process.env.BASE_URL,
      ENV: process.env.ENV,
      USERS: ...,
      BANK_ACCOUNTS: ...,
      COMMON_TRANSFER_TITLES: ...,
    };
    

    Alternatively, Playwright allows you to specify custom options or parameters in your playwright.config.ts that are injected into every test case. IMO, that’s the most elegant way to configure tests.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search