Search code examples
automated-teststokenplaywright

Playwright: How can I use a token generated by an API to be used across all tests?


I have an authentication API endpoint that generates an accessToken. I would this token to be temporarily saved and then used / executed across all my other API tests every run with the setup / test snippet below:

const url = 'https://serverless.net/api/authority/token';

    await request.post(url, {
        headers: {
        'Accept': 'application/json',
        // Add authorization token to all requests.
        'Authorization': `Basic ${Buffer.from(`${process.env.USERNAME}:${process.env.PASSWORD}`).toString('base64')}`, }
    });
/// this generates an `accessToken` in the body

The API response body would have something like:

{
    "result": 0,
    "message": "Success",
    "data": {
        "accessToken": "eyasdadasdasdasdasdasdasdasdsa",
        "tokenType": "Bearer",
        "expiresIn": "1440",
        "userId": 1
    }
}

where I would need the accessToken.

Can I write / save this to a temporary storage (maybe a json file?) then use it as a Bearer token for my API tests?


Solution

  • I got this working by using Playwright's global-setup (https://playwright.dev/docs/test-global-setup-teardown).

    First, on the root directory, I created global-setup.ts with the following code. The gist is to save the accessToken from the response body into an environment variable process.env.TOKEN:

    import { FullConfig, request } from '@playwright/test';
    
    async function globalSetup(config: FullConfig) {
        const baseURL = config.projects[0].use.baseURL;
        const url = '/api/authority/token';
    
        const requestContext = await request.newContext();
        const response = await requestContext.post(`${baseURL}${url}`, {
                headers: {
                    'Accept': 'application/json',
                    'Authorization': `Basic ${Buffer.from(`${process.env.USERNAME}:${process.env.USER_ADMIN_PASSWORD}`).toString('base64')}`
                }
            });
    
        const body = await response.json();
        process.env.TOKEN = body.data.accessToken;
    }
    
    export default globalSetup;
    

    I then included the following lines in my playwright.config.ts:

    import { defineConfig, devices } from '@playwright/test';
    
    require('dotenv').config({ path: `.env.${process.env.ENVIRONMENT}` });
    
    export default defineConfig({
      globalSetup: require.resolve('./global-setup'),
      ...
    

    Lastly, on my tests, I just simply call the process.env.TOKEN with something like below:

    test('api that calls the auth token', async ({ request }) => {
      const url = '/my-api-endpoint';
    
      const response = await request.get(`${baseURL}${url}`, {
        headers: {
            'Authorization': `Bearer ${process.env.TOKEN}`,
            'Content-Type': 'application/json'
            }
      });