skip to Main Content

in fixtures.ts I perform some API calls that create objects in database and returns their ids.

After all tests are done, I need clean the created objects in database.

How do I pass the ids to global.teardown.ts?


What I have

I import fixtures module with a singleton array of guid in global.teardown.ts but the module is reinitialized and array is empty.

global.teardown.ts

import { entityGuidsToDelete, api } from './fixtures'

async function globalTeardown() {
    //not working yet, because the array is always empty
    for(const entityGuid of entityGuidsToDelete) { 
        await api.deleteEntity(entityGuid);
    }
}

export default globalTeardown;

playwright.config.ts

export default defineConfig({
  ...
  /* Configure projects for major browsers */
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
  ],

  globalTeardown: require.resolve('./global-teardown')
});
type Fixtures = {
  userApi: Api;
  newEntity: LegalEntityModel;
};

export const entityGuidsToDelete = new Array<string>();

export const test = base.extend<Fixtures>({
 ...
 newEntity: async ({ userApi }, use) => {
    const newEntity = await createNewEntity()
    entityGuidsToDelete.push(newEntity.id); //this is being called
    await use(newEntity);
  }  
}

export { expect } from '@playwright/test';

2

Answers


  1. I would use an scope worker fixture:

    import { test as base } from '@playwright/test';
    
    export const test = base.extend({
      entities: [async ({}, use) => {
        const array = [];
        await use(array);
      }, { scope: 'worker' }],
      forEachWorker: [async ({entities}, use) => {
        // This code runs before all the tests in the worker process.
        await use();
        // Do something with entities
      }, { scope: 'worker', auto: true }], 
    });
    
    export { expect } from '@playwright/test';
    

    In this example an entities array will be created per worker. Then, you can use that fixture in the forEachWork and do something with them after use.

    This is how you can use it on a test:

    import { test, expect } from './fixtures';
    
    test.describe('Example test suite', () => {
      test('first dummy test', async ({ page, entities }) => {
        // Empty test
        entities.push('entity1');
      });
    
      test('second dummy test', async ({ page, entities }) => {
        // Empty test
        entities.push('entity2');
      });
    
      test('third dummy test', async ({ page, entities }) => {
        // Empty test
        entities.push('entity3');
      });
    });
    
    Login or Signup to reply.
  2. The good news for this is you already have pretty much everything you need, you just have to reorganize a bit.

    export const test = test.extend<Fixtures>({
      newEntity: async ({userApi}, use) => {
        const newEntity = await createNewEntity();
        await use(newEntity);
        // everything after `await use()` is teardown
        try {
          await userApi.deleteEntity(newEntity.id);
        } catch (e) {
          console.error(`Failed to delete entity with ID ${newEntity.id ??
          'unknown'} : ${e}`);
        }
      },
    });
    

    What happens now is, every time an entity is created by a fixture, your cleanup will automatically run once that test is over. No need to collect all of the IDs for-loop over them afterward.

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