Skip to content

Commit

Permalink
test: improve hooks tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalets committed Oct 28, 2024
1 parent 5d0ad3c commit d46e36a
Show file tree
Hide file tree
Showing 24 changed files with 202 additions and 229 deletions.
1 change: 0 additions & 1 deletion test/hooks-error/test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,5 @@ function execPlaywrightWithErrorInHook(hook) {

function expectCalls(prefix, stdout, expectedCalls) {
const calls = stdout.split('\n').filter((line) => line.startsWith(prefix));

expect(calls).toEqual(expectedCalls.map((call) => prefix + call));
}
2 changes: 1 addition & 1 deletion test/hooks-order/features/sample.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Feature: hooks
Feature: sample

Background: bg
Given Step bg
Expand Down
20 changes: 0 additions & 20 deletions test/hooks-order/features/steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import timers from 'node:timers/promises';

import { Given, Before, BeforeAll, After, AfterAll } from './fixtures';

// const calls: string[] = [];
const delay = async () => await timers.setTimeout(50);

Before(async function ({ $tags, $testInfo, page, track }) {
Expand Down Expand Up @@ -58,22 +57,3 @@ Given('Step {int}', async ({ track }, n: number) => {
Given('Step bg', async ({ track }) => {
track(`Step bg`);
});

/*
function track(hookTitle: string) {
logger.log(`track: ${hookTitle}`);
// calls.push(hookTitle);
const shouldThrow = process.env.ERROR && hookTitle.startsWith(process.env.ERROR);
if (shouldThrow) {
throw new Error(hookTitle);
}
// const isBeforeAll = hookTitle.startsWith('BeforeAll');
// const isLastHook = hookTitle.startsWith('AfterAll 1 ');
// if ((shouldThrow && isBeforeAll) || isLastHook) {
// logger.log(['Start', ...calls, 'End'].join('\n'));
// }
// if (shouldThrow) {
// throw new Error(hookTitle);
// }
}
*/
2 changes: 1 addition & 1 deletion test/hooks-order/test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ test(`${testDir.name} (1 worker)`, () => {
]);
});

test(`${testDir.name} (2 worker)`, () => {
test(`${testDir.name} (2 workers)`, () => {
const stdout = execPlaywrightTest(testDir.name, `${DEFAULT_CMD} --workers=2 --fully-parallel`);

// worker 0
Expand Down
26 changes: 21 additions & 5 deletions test/hooks-tags/features/fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
import timers from 'node:timers/promises';
import { test as base, createBdd } from 'playwright-bdd';

const logger = console;

export const test = base.extend<{ fixtureForFoo: void; fixtureForBar: void }>({
fixtureForFoo: async ({}, use) => {
logger.log(`setup fixture for foo`);
export const test = base.extend<
{ fixtureForFoo: void; fixtureForBar: void },
{ track: (s: string) => unknown }
>({
fixtureForFoo: async ({ track }, use) => {
// tiny delay to have always foo after bar
await timers.setTimeout(50);
track(`setup fixture for foo`);
await use();
},

fixtureForBar: async ({}, use) => {
logger.log(`setup fixture for bar`);
fixtureForBar: async ({ track }, use) => {
track(`setup fixture for bar`);
await use();
},

track: [
async ({}, use, workerInfo) => {
const fn = (hookTitle: string) => {
logger.log(`worker ${workerInfo.workerIndex}: ${hookTitle}`);
};
await use(fn);
},
{ scope: 'worker' },
],
});

export const { Given, Before, After, AfterAll } = createBdd(test);
29 changes: 0 additions & 29 deletions test/hooks-tags/features/hooks.ts

This file was deleted.

4 changes: 2 additions & 2 deletions test/hooks-tags/features/sample.feature
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Feature: hooks

@bar
Scenario: scenario 1
Given State 1
Given Step 1

Scenario: scenario 2
Given State 2
Given Step 2
4 changes: 2 additions & 2 deletions test/hooks-tags/features/sample2.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Feature: sample
Feature: sample 2

Scenario: scenario 3
Given step in sample2
Given Step 3
28 changes: 21 additions & 7 deletions test/hooks-tags/features/steps.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import { Given } from './fixtures';
import { track } from './track';
import { expect } from '@playwright/test';
import { Given, Before, After } from './fixtures';

const logger = console;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Before('@bar', async function ({ $testInfo, $tags, track, fixtureForBar }) {
track(`Before @bar ${$testInfo.title}`);
expect($tags).toEqual(['@foo', '@bar']);
});

// eslint-disable-next-line @typescript-eslint/no-unused-vars
Before({ tags: '@foo and not @bar' }, async ({ $testInfo, track, fixtureForFoo }) => {
track(`Before @foo and not @bar ${$testInfo.title}`);
});

After('@bar', async function ({ $testInfo, $tags, track }) {
track(`After @bar ${$testInfo.title}`);
expect($tags).toEqual(['@foo', '@bar']);
});

Given('State {int}', async ({ $testInfo }) => {
track(`Step ${$testInfo.title}`);
After({ tags: '@foo and not @bar' }, async ({ $testInfo, track }) => {
track(`After @foo and not @bar ${$testInfo.title}`);
});

Given('step in sample2', async () => {
logger.log(`step in sample2`);
Given('Step {int}', async ({ $step, track }) => {
track($step.title);
});
5 changes: 0 additions & 5 deletions test/hooks-tags/features/track.ts

This file was deleted.

94 changes: 41 additions & 53 deletions test/hooks-tags/test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,18 @@ const pwSupportsTags = playwrightVersion >= '1.42.0';
test(`${testDir.name} (run all tests)`, () => {
const stdout = execPlaywrightTest(testDir.name);

expect(stdout).toContain('setup fixture for foo');
expect(stdout).toContain('setup fixture for bar');
expect(stdout).toContain('step in sample2');

expectHookCalls(stdout, [
expectCalls('worker 0: ', stdout, [
'setup fixture for bar',
'setup fixture for foo',
'Before @bar scenario 1',
'Step scenario 1',
'Step 1',
'After @bar scenario 1',
'setup fixture for bar',
'setup fixture for foo',
'Before @foo and not @bar scenario 2',
'Step scenario 2',
'Step 2',
'After @foo and not @bar scenario 2',
'Step 3',
]);
});

Expand All @@ -34,12 +35,10 @@ test(`${testDir.name} (gen only bar)`, () => {
`${BDDGEN_CMD} --tags "@bar" && ${PLAYWRIGHT_CMD}`,
);

expect(stdout).not.toContain('setup fixture for foo');
expect(stdout).toContain('setup fixture for bar');

expectHookCalls(stdout, [
'Before @bar scenario 1', // prettier-ignore
'Step scenario 1',
expectCalls('worker 0: ', stdout, [
'setup fixture for bar', // prettier-ignore
'Before @bar scenario 1',
'Step 1',
'After @bar scenario 1',
]);
});
Expand All @@ -50,14 +49,12 @@ test(`${testDir.name} (gen not bar)`, () => {
`${BDDGEN_CMD} --tags "not @bar" && ${PLAYWRIGHT_CMD}`,
);

expect(stdout).toContain('setup fixture for foo');
expect(stdout).not.toContain('setup fixture for bar');
expect(stdout).toContain('step in sample2');

expectHookCalls(stdout, [
'Before @foo and not @bar scenario 2', // prettier-ignore
'Step scenario 2',
expectCalls('worker 0: ', stdout, [
'setup fixture for foo', // prettier-ignore
'Before @foo and not @bar scenario 2',
'Step 2',
'After @foo and not @bar scenario 2',
'Step 3',
]);
});

Expand All @@ -67,16 +64,15 @@ test(`${testDir.name} (run bar)`, { skip: !pwSupportsTags }, () => {
`${BDDGEN_CMD} && ${PLAYWRIGHT_CMD} --grep "@bar"`,
);

// initialization of fixtureForFoo is expected,
// b/c both scenarios are in the same file.
// We can't know beforehand, which will it be filtered with PW tags in runtime.
// Looks like a minor issue.
expect(stdout).toContain('setup fixture for foo');
expect(stdout).toContain('setup fixture for bar');

expectHookCalls(stdout, [
'Before @bar scenario 1', // prettier-ignore
'Step scenario 1',
expectCalls('worker 0: ', stdout, [
// initialization of fixtureForFoo is expected,
// b/c both scenarios are in the same file.
// We can't know beforehand, which scenarios will be filtered with PW tags in runtime.
// Looks like a minor issue.
'setup fixture for bar', // prettier-ignore
'setup fixture for foo',
'Before @bar scenario 1',
'Step 1',
'After @bar scenario 1',
]);
});
Expand All @@ -87,18 +83,17 @@ test(`${testDir.name} (run not bar)`, { skip: !pwSupportsTags }, () => {
`${BDDGEN_CMD} && ${PLAYWRIGHT_CMD} --grep-invert "@bar"`,
);

expect(stdout).toContain('setup fixture for foo');
// initialization of fixtureForBar is expected,
// b/c both scenarios are in the same file.
// We can't know beforehand, which will it be filtered with PW tags in runtime.
// Looks like a minor issue.
expect(stdout).toContain('setup fixture for bar');
expect(stdout).toContain('step in sample2');

expectHookCalls(stdout, [
'Before @foo and not @bar scenario 2', // prettier-ignore
'Step scenario 2',
expectCalls('worker 0: ', stdout, [
// initialization of fixtureForBar is expected,
// b/c both scenarios are in the same file.
// We can't know beforehand, which will it be filtered with PW tags in runtime.
// Looks like a minor issue.
'setup fixture for bar', // prettier-ignore
'setup fixture for foo',
'Before @foo and not @bar scenario 2',
'Step 2',
'After @foo and not @bar scenario 2',
'Step 3',
]);
});

Expand All @@ -108,11 +103,7 @@ test(`${testDir.name} (gen not foo)`, () => {
`${BDDGEN_CMD} --tags "not @foo" && ${PLAYWRIGHT_CMD}`,
);

expect(stdout).toContain('step in sample2');

expect(stdout).not.toContain('setup fixture for foo');
expect(stdout).not.toContain('setup fixture for bar');
expectHookCalls(stdout, []);
expectCalls('worker 0: ', stdout, ['Step 3']);
});

test(`${testDir.name} (run not foo)`, { skip: !pwSupportsTags }, () => {
Expand All @@ -121,13 +112,10 @@ test(`${testDir.name} (run not foo)`, { skip: !pwSupportsTags }, () => {
`${BDDGEN_CMD} && ${PLAYWRIGHT_CMD} --grep-invert "@foo"`,
);

expect(stdout).toContain('step in sample2');

expect(stdout).not.toContain('setup fixture for foo');
expect(stdout).not.toContain('setup fixture for bar');
expectHookCalls(stdout, []);
expectCalls('worker 0: ', stdout, ['Step 3']);
});

function expectHookCalls(stdout, hookCalls) {
expect(stdout).toContain(['Start', ...hookCalls, 'End'].join('\n'));
function expectCalls(prefix, stdout, expectedCalls) {
const calls = stdout.split('\n').filter((line) => line.startsWith(prefix));
expect(calls).toEqual(expectedCalls.map((call) => prefix + call));
}
22 changes: 22 additions & 0 deletions test/hooks-timeout/features/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import timers from 'node:timers/promises';
import { test as base, createBdd } from 'playwright-bdd';

const logger = console;

export const test = base.extend<object, { track: (s: string) => unknown }>({
track: [
async ({}, use, workerInfo) => {
const fn = async (hookTitle: string) => {
logger.log(`worker ${workerInfo.workerIndex}: ${hookTitle}`);
const shouldTimeout = process.env.TIMEOUT && hookTitle.startsWith(process.env.TIMEOUT);
if (shouldTimeout) {
await timers.setTimeout(100);
}
};
await use(fn);
},
{ scope: 'worker' },
],
});

export const { Given, Before, BeforeAll, After, AfterAll } = createBdd(test);
File renamed without changes.
43 changes: 43 additions & 0 deletions test/hooks-timeout/features/steps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Given, Before, BeforeAll, After, AfterAll } from './fixtures';

// scenario hooks

Before({ timeout: 5 }, async function ({ $testInfo, track }) {
await track(`Before 1 ${$testInfo.title}`);
});

Before(async ({ $testInfo, track }) => {
await track(`Before 2 ${$testInfo.title}`);
});

After(async function ({ $testInfo, track }) {
await track(`After 1 ${$testInfo.title}`);
});

After({ timeout: 5 }, async ({ $testInfo, track }) => {
await track(`After 2 ${$testInfo.title}`);
});

// worker hooks

BeforeAll({ timeout: 5 }, async function ({ track }) {
await track(`BeforeAll 1`);
});

BeforeAll(async ({ track }) => {
await track(`BeforeAll 2`);
});

AfterAll(async function ({ track }) {
await track(`AfterAll 1`);
});

AfterAll({ timeout: 5 }, async ({ track }) => {
await track(`AfterAll 2`);
});

// step

Given('State {int}', async ({ $testInfo, track }) => {
await track(`Step ${$testInfo.title}`);
});
Loading

0 comments on commit d46e36a

Please sign in to comment.