-
-
Notifications
You must be signed in to change notification settings - Fork 50
/
Copy pathtestTypeImpl.ts
100 lines (90 loc) · 3.56 KB
/
testTypeImpl.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* Helpers to deal with Playwright test internal stuff.
* See: https://github.com/microsoft/playwright/blob/main/packages/playwright-test/src/common/testType.ts
*/
import { test, Fixtures, TestInfo } from '@playwright/test';
import { Location } from '@playwright/test/reporter';
import { getSymbolByName } from '../utils';
import { TestTypeCommon } from './types';
import { playwrightVersion } from './utils';
type FixturesWithLocation = {
fixtures: Fixtures;
location: Location;
};
const testTypeSymbol = getSymbolByName(test, 'testType');
/**
* Returns test fixtures using Symbol.
*/
function getTestFixtures(test: TestTypeCommon) {
return getTestImpl(test).fixtures as FixturesWithLocation[];
}
function getTestImpl(test: TestTypeCommon) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return test[testTypeSymbol] as any;
}
// Partial copy of Playwright's TestStepInternal
// See: https://github.com/microsoft/playwright/blob/main/packages/playwright/src/worker/testInfo.ts#L32
interface TestStepInternal {
title: string;
category: 'hook' | 'fixture' | 'test.step' | string;
location?: Location;
}
/**
* Run step with location pointing to Given, When, Then call.
*/
// eslint-disable-next-line max-params
export async function runStepWithCustomLocation(
test: TestTypeCommon,
stepText: string,
location: Location,
body: () => unknown,
) {
// Since PW 1.43 testInfo._runAsStep was replaced with a more complex logic.
// To run step with a custom location, we hijack testInfo._addStep()
// so that it appends location for the bdd step calls.
// Finally we call test.step(), that internally invokes testInfo._addStep().
// See: https://github.com/microsoft/playwright/blob/release-1.43/packages/playwright/src/common/testType.ts#L262
// See: https://github.com/microsoft/playwright/blob/release-1.43/packages/playwright/src/worker/testInfo.ts#L247
if (playwrightVersion >= '1.43.0') {
const testInfo = test.info() as TestInfo & {
_addStep: (data: TestStepInternal) => unknown;
bddStepLocations: Map<string, Location>;
};
if (!testInfo.bddStepLocations) {
testInfo.bddStepLocations = new Map();
const origAddStep = testInfo._addStep;
testInfo._addStep = function (data: TestStepInternal) {
if (data.category === 'test.step' && this.bddStepLocations.has(data.title)) {
data.location = this.bddStepLocations.get(data.title);
}
return origAddStep.call(this, data);
};
}
testInfo.bddStepLocations.set(stepText, location);
return test.step(stepText, body);
} else {
const testInfo = test.info() as TestInfo & {
// testInfo._runAsStep is not public
// See: https://github.com/microsoft/playwright/blob/main/packages/playwright/src/common/testType.ts#L221
_runAsStep: (data: TestStepInternal, fn: () => unknown) => unknown;
};
return testInfo._runAsStep({ category: 'test.step', title: stepText, location }, async () => {
return await body();
});
}
}
/**
* Returns true if test contains all fixtures of subtest.
* - test was extended from subtest
* - test is a result of mergeTests(subtest, ...)
*/
export function isTestContainsSubtest(test: TestTypeCommon, subtest: TestTypeCommon) {
if (test === subtest) return true;
const testFixtures = new Set(getTestFixtures(test).map((f) => locationToString(f.location)));
return getTestFixtures(subtest).every((f) => {
return testFixtures.has(locationToString(f.location));
});
}
function locationToString({ file, line, column }: Location) {
return `${file}:${line}:${column}`;
}