@serenity-js/playwright-test 3.31.17 → 3.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +6 -5
- package/lib/api/PlaywrightTestConfig.d.ts +7 -6
- package/lib/api/PlaywrightTestConfig.d.ts.map +1 -1
- package/lib/api/WorkerEventStreamReader.d.ts +13 -0
- package/lib/api/WorkerEventStreamReader.d.ts.map +1 -0
- package/lib/api/WorkerEventStreamReader.js +58 -0
- package/lib/api/WorkerEventStreamReader.js.map +1 -0
- package/lib/api/WorkerEventStreamWriter.d.ts +24 -0
- package/lib/api/WorkerEventStreamWriter.d.ts.map +1 -0
- package/lib/api/WorkerEventStreamWriter.js +86 -0
- package/lib/api/WorkerEventStreamWriter.js.map +1 -0
- package/lib/api/index.d.ts +1 -2
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.js +1 -2
- package/lib/api/index.js.map +1 -1
- package/lib/api/serenity-fixtures.d.ts +377 -0
- package/lib/api/serenity-fixtures.d.ts.map +1 -0
- package/lib/api/{SerenityOptions.js → serenity-fixtures.js} +1 -1
- package/lib/api/serenity-fixtures.js.map +1 -0
- package/lib/api/test-api.d.ts +27 -15
- package/lib/api/test-api.d.ts.map +1 -1
- package/lib/api/test-api.js +126 -104
- package/lib/api/test-api.js.map +1 -1
- package/lib/events/EventFactory.d.ts +16 -0
- package/lib/events/EventFactory.d.ts.map +1 -0
- package/lib/events/EventFactory.js +94 -0
- package/lib/events/EventFactory.js.map +1 -0
- package/lib/events/PlaywrightSceneId.d.ts +7 -0
- package/lib/events/PlaywrightSceneId.d.ts.map +1 -0
- package/lib/events/PlaywrightSceneId.js +19 -0
- package/lib/events/PlaywrightSceneId.js.map +1 -0
- package/lib/events/index.d.ts +3 -0
- package/lib/events/index.d.ts.map +1 -0
- package/lib/events/index.js +19 -0
- package/lib/events/index.js.map +1 -0
- package/lib/reporter/PlaywrightErrorParser.d.ts +7 -0
- package/lib/reporter/PlaywrightErrorParser.d.ts.map +1 -0
- package/lib/reporter/PlaywrightErrorParser.js +28 -0
- package/lib/reporter/PlaywrightErrorParser.js.map +1 -0
- package/lib/reporter/PlaywrightEventBuffer.d.ts +25 -0
- package/lib/reporter/PlaywrightEventBuffer.d.ts.map +1 -0
- package/lib/reporter/PlaywrightEventBuffer.js +147 -0
- package/lib/reporter/PlaywrightEventBuffer.js.map +1 -0
- package/lib/reporter/PlaywrightTestSceneIdFactory.d.ts +8 -0
- package/lib/reporter/PlaywrightTestSceneIdFactory.d.ts.map +1 -0
- package/lib/reporter/PlaywrightTestSceneIdFactory.js +15 -0
- package/lib/reporter/PlaywrightTestSceneIdFactory.js.map +1 -0
- package/lib/reporter/SerenityReporterForPlaywrightTest.d.ts +15 -22
- package/lib/reporter/SerenityReporterForPlaywrightTest.d.ts.map +1 -1
- package/lib/reporter/SerenityReporterForPlaywrightTest.js +62 -163
- package/lib/reporter/SerenityReporterForPlaywrightTest.js.map +1 -1
- package/lib/reporter/index.d.ts +0 -2
- package/lib/reporter/index.d.ts.map +1 -1
- package/lib/reporter/index.js +0 -2
- package/lib/reporter/index.js.map +1 -1
- package/package.json +9 -9
- package/src/api/PlaywrightTestConfig.ts +7 -6
- package/src/api/WorkerEventStreamReader.ts +27 -0
- package/src/api/WorkerEventStreamWriter.ts +117 -0
- package/src/api/index.ts +1 -2
- package/src/api/serenity-fixtures.ts +392 -0
- package/src/api/test-api.ts +187 -99
- package/src/events/EventFactory.ts +204 -0
- package/src/events/PlaywrightSceneId.ts +20 -0
- package/src/events/index.ts +2 -0
- package/src/reporter/PlaywrightErrorParser.ts +35 -0
- package/src/reporter/PlaywrightEventBuffer.ts +251 -0
- package/src/reporter/PlaywrightTestSceneIdFactory.ts +14 -0
- package/src/reporter/SerenityReporterForPlaywrightTest.ts +89 -250
- package/src/reporter/index.ts +0 -2
- package/lib/api/SerenityFixtures.d.ts +0 -130
- package/lib/api/SerenityFixtures.d.ts.map +0 -1
- package/lib/api/SerenityFixtures.js +0 -3
- package/lib/api/SerenityFixtures.js.map +0 -1
- package/lib/api/SerenityOptions.d.ts +0 -271
- package/lib/api/SerenityOptions.d.ts.map +0 -1
- package/lib/api/SerenityOptions.js.map +0 -1
- package/lib/reporter/DomainEventBuffer.d.ts +0 -11
- package/lib/reporter/DomainEventBuffer.d.ts.map +0 -1
- package/lib/reporter/DomainEventBuffer.js +0 -24
- package/lib/reporter/DomainEventBuffer.js.map +0 -1
- package/lib/reporter/PlaywrightAttachments.d.ts +0 -2
- package/lib/reporter/PlaywrightAttachments.d.ts.map +0 -1
- package/lib/reporter/PlaywrightAttachments.js +0 -5
- package/lib/reporter/PlaywrightAttachments.js.map +0 -1
- package/src/api/SerenityFixtures.ts +0 -132
- package/src/api/SerenityOptions.ts +0 -277
- package/src/reporter/DomainEventBuffer.ts +0 -28
- package/src/reporter/PlaywrightAttachments.ts +0 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PlaywrightEventBuffer = void 0;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const core_1 = require("@serenity-js/core");
|
|
9
|
+
const events_1 = require("@serenity-js/core/lib/events");
|
|
10
|
+
const io_1 = require("@serenity-js/core/lib/io");
|
|
11
|
+
const model_1 = require("@serenity-js/core/lib/model");
|
|
12
|
+
const WorkerEventStreamReader_1 = require("../api/WorkerEventStreamReader");
|
|
13
|
+
const WorkerEventStreamWriter_1 = require("../api/WorkerEventStreamWriter");
|
|
14
|
+
const events_2 = require("../events");
|
|
15
|
+
const PlaywrightErrorParser_1 = require("./PlaywrightErrorParser");
|
|
16
|
+
class PlaywrightEventBuffer {
|
|
17
|
+
errorParser = new PlaywrightErrorParser_1.PlaywrightErrorParser();
|
|
18
|
+
eventStreamReader = new WorkerEventStreamReader_1.WorkerEventStreamReader();
|
|
19
|
+
eventFactory;
|
|
20
|
+
events = new Map();
|
|
21
|
+
deferredSceneFinishedEvents = new Map();
|
|
22
|
+
configure(config) {
|
|
23
|
+
this.eventFactory = new events_2.EventFactory(io_1.Path.from(config.rootDir));
|
|
24
|
+
}
|
|
25
|
+
appendTestStart(test, result) {
|
|
26
|
+
this.events.set(this.sceneId(test, result).value, this.eventFactory.createSceneStartEvents(test, result));
|
|
27
|
+
}
|
|
28
|
+
appendRetryableSceneEvents(test, result) {
|
|
29
|
+
const sceneId = this.sceneId(test, result);
|
|
30
|
+
const sceneEndTime = new core_1.Timestamp(result.startTime).plus(core_1.Duration.ofMilliseconds(result.duration));
|
|
31
|
+
this.events.get(sceneId.value).push(new events_1.RetryableSceneDetected(sceneId, sceneEndTime));
|
|
32
|
+
if (result.retry > 0 || result.status !== 'passed') {
|
|
33
|
+
this.events.get(sceneId.value).push(new events_1.SceneTagged(sceneId, new model_1.ArbitraryTag('retried'), // todo: replace with a dedicated tag
|
|
34
|
+
sceneEndTime));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
deferAppendingSceneFinishedEvent(test, result) {
|
|
38
|
+
const sceneId = this.sceneId(test, result);
|
|
39
|
+
const scenarioOutcome = this.outcomeFrom(test, result);
|
|
40
|
+
this.deferredSceneFinishedEvents.set(sceneId.value, {
|
|
41
|
+
event: this.eventFactory.createSceneFinishedEvent(test, result, scenarioOutcome),
|
|
42
|
+
outputDirectory: test.parent.project().outputDir,
|
|
43
|
+
workerIndex: result.workerIndex,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
determineScenarioOutcome(worstInteractionOutcome, scenarioOutcome) {
|
|
47
|
+
if (worstInteractionOutcome instanceof model_1.ExecutionFailedWithAssertionError) {
|
|
48
|
+
return worstInteractionOutcome;
|
|
49
|
+
}
|
|
50
|
+
return worstInteractionOutcome.isWorseThan(scenarioOutcome)
|
|
51
|
+
? worstInteractionOutcome
|
|
52
|
+
: scenarioOutcome;
|
|
53
|
+
}
|
|
54
|
+
appendCrashedWorkerEvents(test, result) {
|
|
55
|
+
const workerStreamId = WorkerEventStreamWriter_1.WorkerEventStreamWriter.workerStreamIdFor(result.workerIndex).value;
|
|
56
|
+
const sceneId = this.sceneId(test, result);
|
|
57
|
+
this.events.get(sceneId.value).push(...this.readEventStream(test.parent.project().outputDir, workerStreamId, sceneId.value));
|
|
58
|
+
}
|
|
59
|
+
appendSceneEvents(test, result) {
|
|
60
|
+
const sceneId = this.sceneId(test, result);
|
|
61
|
+
this.events.get(sceneId.value).push(...this.readEventStream(test.parent.project().outputDir, sceneId.value));
|
|
62
|
+
}
|
|
63
|
+
readEventStream(outputDirectory, streamId, expectedSceneId = streamId) {
|
|
64
|
+
const pathToEventStreamFile = node_path_1.default.join(outputDirectory, 'serenity', streamId, 'events.ndjson');
|
|
65
|
+
if (this.eventStreamReader.hasStream(pathToEventStreamFile)) {
|
|
66
|
+
return this.eventStreamReader.read(pathToEventStreamFile, (event) => {
|
|
67
|
+
// re-attach events from orphaned beforeAll to the test case
|
|
68
|
+
const hasSceneId = event.value['sceneId'] !== undefined;
|
|
69
|
+
const isAttachedToScene = event.value['sceneId'] === expectedSceneId;
|
|
70
|
+
if (hasSceneId && !isAttachedToScene) {
|
|
71
|
+
event.value['sceneId'] = expectedSceneId;
|
|
72
|
+
}
|
|
73
|
+
return event;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
appendSceneFinishedEvent(test, result) {
|
|
79
|
+
const sceneId = this.sceneId(test, result);
|
|
80
|
+
const worstInteractionOutcome = this.determineWorstInteractionOutcome(this.events.get(sceneId.value));
|
|
81
|
+
const scenarioOutcome = this.determineScenarioOutcome(worstInteractionOutcome, this.outcomeFrom(test, result));
|
|
82
|
+
this.events.get(sceneId.value).push(this.eventFactory.createSceneFinishedEvent(test, result, scenarioOutcome));
|
|
83
|
+
}
|
|
84
|
+
flush(test, result) {
|
|
85
|
+
const sceneId = this.sceneId(test, result);
|
|
86
|
+
const events = this.events.get(sceneId.value);
|
|
87
|
+
if (!events) {
|
|
88
|
+
throw new core_1.LogicError(`No events found for test: ${sceneId.value}`);
|
|
89
|
+
}
|
|
90
|
+
this.events.delete(sceneId.value);
|
|
91
|
+
return events;
|
|
92
|
+
}
|
|
93
|
+
flushAllDeferred() {
|
|
94
|
+
const allEvents = [];
|
|
95
|
+
for (const [testId, events] of this.events.entries()) {
|
|
96
|
+
const scenarioEvents = [];
|
|
97
|
+
scenarioEvents.push(...events);
|
|
98
|
+
if (this.deferredSceneFinishedEvents.has(testId)) {
|
|
99
|
+
const lastRecordedEvent = scenarioEvents.at(-1);
|
|
100
|
+
const deferredSceneFinished = this.deferredSceneFinishedEvents.get(testId);
|
|
101
|
+
const eventStream = this.readEventStream(deferredSceneFinished.outputDirectory, deferredSceneFinished.event.sceneId.value);
|
|
102
|
+
const firstEventSinceLastIndex = eventStream.findIndex(event => lastRecordedEvent.equals(event));
|
|
103
|
+
const eventsSinceLast = firstEventSinceLastIndex === -1
|
|
104
|
+
? eventStream
|
|
105
|
+
: eventStream.slice(firstEventSinceLastIndex);
|
|
106
|
+
scenarioEvents.push(...eventsSinceLast);
|
|
107
|
+
const worstInteractionOutcome = this.determineWorstInteractionOutcome(scenarioEvents);
|
|
108
|
+
const sceneFinishedEvent = new events_1.SceneFinished(deferredSceneFinished.event.sceneId, deferredSceneFinished.event.details, this.determineScenarioOutcome(worstInteractionOutcome, deferredSceneFinished.event.outcome), deferredSceneFinished.event.timestamp);
|
|
109
|
+
scenarioEvents.push(sceneFinishedEvent);
|
|
110
|
+
}
|
|
111
|
+
allEvents.push(...scenarioEvents);
|
|
112
|
+
}
|
|
113
|
+
this.events.clear();
|
|
114
|
+
this.deferredSceneFinishedEvents.clear();
|
|
115
|
+
return allEvents;
|
|
116
|
+
}
|
|
117
|
+
determineWorstInteractionOutcome(events) {
|
|
118
|
+
let worstInteractionOutcome = new model_1.ExecutionSuccessful();
|
|
119
|
+
for (const event of events) {
|
|
120
|
+
if (event instanceof events_1.InteractionFinished && event.outcome.isWorseThan(worstInteractionOutcome)) {
|
|
121
|
+
worstInteractionOutcome = event.outcome;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return worstInteractionOutcome;
|
|
125
|
+
}
|
|
126
|
+
outcomeFrom(test, result) {
|
|
127
|
+
const outcome = test.outcome();
|
|
128
|
+
if (outcome === 'skipped') {
|
|
129
|
+
return new model_1.ExecutionSkipped();
|
|
130
|
+
}
|
|
131
|
+
if (outcome === 'unexpected' && result.status === 'passed') {
|
|
132
|
+
return new model_1.ExecutionFailedWithError(new core_1.LogicError(`Scenario expected to fail, but ${result.status}`));
|
|
133
|
+
}
|
|
134
|
+
if (['failed', 'interrupted', 'timedOut'].includes(result.status)) {
|
|
135
|
+
if (test.retries > result.retry) {
|
|
136
|
+
return new model_1.ExecutionIgnored(this.errorParser.errorFrom(result.error));
|
|
137
|
+
}
|
|
138
|
+
return new model_1.ExecutionFailedWithError(this.errorParser.errorFrom(result.error));
|
|
139
|
+
}
|
|
140
|
+
return new model_1.ExecutionSuccessful();
|
|
141
|
+
}
|
|
142
|
+
sceneId(test, result) {
|
|
143
|
+
return events_2.PlaywrightSceneId.from(test.parent.project()?.name, test, result);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
exports.PlaywrightEventBuffer = PlaywrightEventBuffer;
|
|
147
|
+
//# sourceMappingURL=PlaywrightEventBuffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaywrightEventBuffer.js","sourceRoot":"","sources":["../../src/reporter/PlaywrightEventBuffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CorrelationIdFactory } from '@serenity-js/core/lib/model';
|
|
2
|
+
import { CorrelationId } from '@serenity-js/core/lib/model';
|
|
3
|
+
export declare class PlaywrightTestSceneIdFactory implements CorrelationIdFactory {
|
|
4
|
+
private testId;
|
|
5
|
+
setTestId(testId: string): void;
|
|
6
|
+
create(): CorrelationId;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=PlaywrightTestSceneIdFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaywrightTestSceneIdFactory.d.ts","sourceRoot":"","sources":["../../src/reporter/PlaywrightTestSceneIdFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,qBAAa,4BAA6B,YAAW,oBAAoB;IACrE,OAAO,CAAC,MAAM,CAAgB;IAE9B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,MAAM,IAAI,aAAa;CAG1B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaywrightTestSceneIdFactory = void 0;
|
|
4
|
+
const model_1 = require("@serenity-js/core/lib/model");
|
|
5
|
+
class PlaywrightTestSceneIdFactory {
|
|
6
|
+
testId;
|
|
7
|
+
setTestId(testId) {
|
|
8
|
+
this.testId = new model_1.CorrelationId(testId);
|
|
9
|
+
}
|
|
10
|
+
create() {
|
|
11
|
+
return this.testId;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.PlaywrightTestSceneIdFactory = PlaywrightTestSceneIdFactory;
|
|
15
|
+
//# sourceMappingURL=PlaywrightTestSceneIdFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaywrightTestSceneIdFactory.js","sourceRoot":"","sources":["../../src/reporter/PlaywrightTestSceneIdFactory.ts"],"names":[],"mappings":";;;AACA,uDAA4D;AAE5D,MAAa,4BAA4B;IAC7B,MAAM,CAAgB;IAE9B,SAAS,CAAC,MAAc;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,qBAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM;QACF,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;CACJ;AAVD,oEAUC"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { FullConfig } from '@playwright/test';
|
|
2
|
-
import type { Reporter, Suite, TestCase, TestError, TestResult } from '@playwright/test/reporter';
|
|
3
|
-
import type { ClassDescription,
|
|
2
|
+
import type { FullResult, Reporter, Suite, TestCase, TestError, TestResult } from '@playwright/test/reporter';
|
|
3
|
+
import type { ClassDescription, StageCrewMember, StageCrewMemberBuilder } from '@serenity-js/core';
|
|
4
4
|
import type { OutputStream } from '@serenity-js/core/lib/adapter';
|
|
5
|
-
import { RequirementsHierarchy } from '@serenity-js/core/lib/io';
|
|
6
5
|
/**
|
|
7
6
|
* Configuration object accepted by `@serenity-js/playwright-test` reporter.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
8
|
+
* For usage examples, see:
|
|
9
|
+
* - [`SerenityFixtures`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/)
|
|
10
|
+
* - [`SerenityWorkerFixtures`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/)
|
|
10
11
|
*/
|
|
11
12
|
export interface SerenityReporterForPlaywrightTestConfig {
|
|
12
13
|
/**
|
|
@@ -15,7 +16,7 @@ export interface SerenityReporterForPlaywrightTestConfig {
|
|
|
15
16
|
* Note that the `crew` can also be configured using [class descriptions](https://serenity-js.org/api/core/#ClassDescription).
|
|
16
17
|
*
|
|
17
18
|
* #### Learn more
|
|
18
|
-
* - [`
|
|
19
|
+
* - [`SerenityFixtures`](https://serenity-js.org/api/playwright-test/interface/SerenityFixtures/)
|
|
19
20
|
* - [`SerenityConfig.crew`](https://serenity-js.org/api/core/class/SerenityConfig/#crew)
|
|
20
21
|
*/
|
|
21
22
|
crew?: Array<StageCrewMember | StageCrewMemberBuilder | ClassDescription>;
|
|
@@ -35,31 +36,23 @@ export interface SerenityReporterForPlaywrightTestConfig {
|
|
|
35
36
|
* Serenity/JS [stage crew members](https://serenity-js.org/api/core/interface/StageCrewMember/).
|
|
36
37
|
*/
|
|
37
38
|
export declare class SerenityReporterForPlaywrightTest implements Reporter {
|
|
39
|
+
private readonly errorParser;
|
|
40
|
+
private readonly sceneIdFactory;
|
|
38
41
|
private readonly serenity;
|
|
39
|
-
private requirementsHierarchy;
|
|
40
|
-
private errorParser;
|
|
41
|
-
private sceneIds;
|
|
42
42
|
private unhandledError?;
|
|
43
|
+
private readonly eventBuffer;
|
|
44
|
+
private readonly suiteTestCounts;
|
|
43
45
|
/**
|
|
44
46
|
* @param config
|
|
45
|
-
* @param serenity
|
|
46
|
-
* Instance of [`Serenity`](https://serenity-js.org/api/core/class/Serenity/), specific to the Node process running this Serenity reporter.
|
|
47
|
-
* Note that Playwright runs test workers and reporters in separate processes.
|
|
48
|
-
* @param requirementsHierarchy
|
|
49
|
-
* Root directory of the requirements hierarchy, used to determine capabilities and themes.
|
|
50
47
|
*/
|
|
51
|
-
constructor(config: SerenityReporterForPlaywrightTestConfig
|
|
48
|
+
constructor(config: SerenityReporterForPlaywrightTestConfig);
|
|
52
49
|
onBegin(config: FullConfig, suite: Suite): void;
|
|
53
|
-
|
|
50
|
+
private countTestsPerSuite;
|
|
51
|
+
onTestBegin(test: TestCase, result: TestResult): void;
|
|
54
52
|
onTestEnd(test: TestCase, result: TestResult): void;
|
|
53
|
+
private countPendingAfterAllHooks;
|
|
55
54
|
onError(error: TestError): void;
|
|
56
|
-
|
|
57
|
-
private outcomeFrom;
|
|
58
|
-
private scenarioDetailsFrom;
|
|
59
|
-
onEnd(): Promise<void>;
|
|
60
|
-
private emit;
|
|
61
|
-
private announceRetryIfNeeded;
|
|
62
|
-
private now;
|
|
55
|
+
onEnd(fullResult: FullResult): Promise<void>;
|
|
63
56
|
printsToStdio(): boolean;
|
|
64
57
|
}
|
|
65
58
|
//# sourceMappingURL=SerenityReporterForPlaywrightTest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SerenityReporterForPlaywrightTest.d.ts","sourceRoot":"","sources":["../../src/reporter/SerenityReporterForPlaywrightTest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAG,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"SerenityReporterForPlaywrightTest.d.ts","sourceRoot":"","sources":["../../src/reporter/SerenityReporterForPlaywrightTest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAG,MAAM,2BAA2B,CAAC;AAC/G,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAEnG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAUlE;;;;;;GAMG;AACH,MAAM,WAAW,uCAAuC;IACpD;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,eAAe,GAAG,sBAAsB,GAAG,gBAAgB,CAAC,CAAC;IAE1E;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B;AAED;;;;GAIG;AACH,qBAAa,iCAAkC,YAAW,QAAQ;IAC9D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA+B;IAE3D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA+B;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,cAAc,CAAC,CAAQ;IAE/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsD;IAClF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4B;IAE5D;;OAEG;gBACS,MAAM,EAAE,uCAAuC;IAW3D,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAO/C,OAAO,CAAC,kBAAkB;IAY1B,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAcrD,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAuBnD,OAAO,CAAC,yBAAyB;IAkBjC,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAMzB,KAAK,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA2ClD,aAAa,IAAI,OAAO;CAG3B"}
|
|
@@ -1,217 +1,116 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.SerenityReporterForPlaywrightTest = void 0;
|
|
37
4
|
const core_1 = require("@serenity-js/core");
|
|
38
|
-
const events = __importStar(require("@serenity-js/core/lib/events"));
|
|
39
5
|
const events_1 = require("@serenity-js/core/lib/events");
|
|
40
|
-
const io_1 = require("@serenity-js/core/lib/io");
|
|
41
6
|
const model_1 = require("@serenity-js/core/lib/model");
|
|
42
|
-
const
|
|
7
|
+
const PlaywrightErrorParser_1 = require("./PlaywrightErrorParser");
|
|
8
|
+
const PlaywrightEventBuffer_1 = require("./PlaywrightEventBuffer");
|
|
9
|
+
const PlaywrightTestSceneIdFactory_1 = require("./PlaywrightTestSceneIdFactory");
|
|
43
10
|
/**
|
|
44
11
|
* Serenity/JS reporter that receives notifications from Playwright Test and emits them as
|
|
45
12
|
* Serenity/JS [Serenity/JS domain events](https://serenity-js.org/api/core-events/class/DomainEvent/) which can be used by
|
|
46
13
|
* Serenity/JS [stage crew members](https://serenity-js.org/api/core/interface/StageCrewMember/).
|
|
47
14
|
*/
|
|
48
15
|
class SerenityReporterForPlaywrightTest {
|
|
16
|
+
errorParser = new PlaywrightErrorParser_1.PlaywrightErrorParser();
|
|
17
|
+
sceneIdFactory;
|
|
49
18
|
serenity;
|
|
50
|
-
requirementsHierarchy;
|
|
51
|
-
errorParser = new PlaywrightErrorParser();
|
|
52
|
-
sceneIds = new Map();
|
|
53
19
|
unhandledError;
|
|
20
|
+
eventBuffer = new PlaywrightEventBuffer_1.PlaywrightEventBuffer();
|
|
21
|
+
suiteTestCounts = new Map();
|
|
54
22
|
/**
|
|
55
23
|
* @param config
|
|
56
|
-
* @param serenity
|
|
57
|
-
* Instance of [`Serenity`](https://serenity-js.org/api/core/class/Serenity/), specific to the Node process running this Serenity reporter.
|
|
58
|
-
* Note that Playwright runs test workers and reporters in separate processes.
|
|
59
|
-
* @param requirementsHierarchy
|
|
60
|
-
* Root directory of the requirements hierarchy, used to determine capabilities and themes.
|
|
61
24
|
*/
|
|
62
|
-
constructor(config
|
|
63
|
-
this.
|
|
64
|
-
this.
|
|
25
|
+
constructor(config) {
|
|
26
|
+
this.sceneIdFactory = new PlaywrightTestSceneIdFactory_1.PlaywrightTestSceneIdFactory();
|
|
27
|
+
this.serenity = new core_1.Serenity(new core_1.Clock(), process.cwd(), this.sceneIdFactory);
|
|
65
28
|
this.serenity.configure(config);
|
|
66
29
|
}
|
|
67
30
|
onBegin(config, suite) {
|
|
68
|
-
this.
|
|
69
|
-
this.serenity.announce(new events_1.TestRunStarts(this.
|
|
31
|
+
this.eventBuffer.configure(config);
|
|
32
|
+
this.serenity.announce(new events_1.TestRunStarts(this.serenity.currentTime()));
|
|
33
|
+
this.countTestsPerSuite(suite);
|
|
34
|
+
}
|
|
35
|
+
countTestsPerSuite(suite) {
|
|
36
|
+
suite.allTests().forEach(test => {
|
|
37
|
+
let currentSuite = test.parent;
|
|
38
|
+
while (currentSuite) {
|
|
39
|
+
const count = this.suiteTestCounts.get(currentSuite) ?? 0;
|
|
40
|
+
this.suiteTestCounts.set(currentSuite, count + 1);
|
|
41
|
+
currentSuite = currentSuite.parent;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
70
44
|
}
|
|
71
|
-
onTestBegin(test) {
|
|
72
|
-
|
|
73
|
-
this.sceneIds.set(test.id, currentSceneId);
|
|
74
|
-
const { scenarioDetails, scenarioTags } = this.scenarioDetailsFrom(test);
|
|
75
|
-
const tags = [
|
|
76
|
-
...scenarioTags,
|
|
77
|
-
...test.tags.flatMap(tag => model_1.Tags.from(tag)),
|
|
78
|
-
];
|
|
79
|
-
this.emit(new events_1.SceneStarts(currentSceneId, scenarioDetails, this.serenity.currentTime()), ...this.requirementsHierarchy
|
|
80
|
-
.requirementTagsFor(scenarioDetails.location.path, scenarioDetails.category.value)
|
|
81
|
-
.map(tag => new events_1.SceneTagged(currentSceneId, tag, this.serenity.currentTime())), new events_1.TestRunnerDetected(currentSceneId, new model_1.Name('Playwright'), this.serenity.currentTime()), ...tags.map(tag => new events_1.SceneTagged(currentSceneId, tag, this.serenity.currentTime())));
|
|
45
|
+
onTestBegin(test, result) {
|
|
46
|
+
this.eventBuffer.appendTestStart(test, result);
|
|
82
47
|
}
|
|
83
48
|
// TODO might be nice to support that by emitting TestStepStarted / Finished
|
|
84
49
|
// onStepBegin(test: TestCase, _result: TestResult, step: TestStep): void {
|
|
85
50
|
// // console.log('>> onStepBegin');
|
|
86
51
|
// }
|
|
52
|
+
// todo: add stdout -> Log https://github.com/microsoft/playwright/blob/main/packages/playwright/src/reporters/list.ts#L67
|
|
87
53
|
// onStepEnd(test: TestCase, _result: TestResult, step: TestStep): void {
|
|
88
54
|
// // console.log('>> onStepEnd');
|
|
89
55
|
// }
|
|
90
56
|
onTestEnd(test, result) {
|
|
91
|
-
this.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
for (const attachment of result.attachments) {
|
|
95
|
-
if (!(attachment.contentType === PlaywrightAttachments_1.SERENITY_JS_DOMAIN_EVENTS_ATTACHMENT_CONTENT_TYPE && attachment.body)) {
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
const messages = JSON.parse(attachment.body.toString());
|
|
99
|
-
for (const message of messages) {
|
|
100
|
-
if (message.value.sceneId === 'unknown') {
|
|
101
|
-
message.value.sceneId = currentSceneId.value;
|
|
102
|
-
}
|
|
103
|
-
const event = events[message.type].fromJSON(message.value);
|
|
104
|
-
this.serenity.announce(event);
|
|
105
|
-
if (event instanceof events_1.InteractionFinished && event.outcome.isWorseThan(worstInteractionOutcome)) {
|
|
106
|
-
worstInteractionOutcome = event.outcome;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
57
|
+
const pendingAfterAllHooks = this.countPendingAfterAllHooks(test);
|
|
58
|
+
if (test.retries > 0) {
|
|
59
|
+
this.eventBuffer.appendRetryableSceneEvents(test, result);
|
|
109
60
|
}
|
|
110
|
-
|
|
111
|
-
this.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
this.
|
|
61
|
+
this.eventBuffer.appendCrashedWorkerEvents(test, result);
|
|
62
|
+
this.eventBuffer.appendSceneEvents(test, result);
|
|
63
|
+
if (pendingAfterAllHooks === 0) {
|
|
64
|
+
this.eventBuffer.appendSceneFinishedEvent(test, result);
|
|
65
|
+
const events = this.eventBuffer.flush(test, result);
|
|
66
|
+
this.serenity.announce(...events);
|
|
116
67
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (worstInteractionOutcome instanceof model_1.ExecutionFailedWithAssertionError) {
|
|
120
|
-
return worstInteractionOutcome;
|
|
68
|
+
else {
|
|
69
|
+
this.eventBuffer.deferAppendingSceneFinishedEvent(test, result);
|
|
121
70
|
}
|
|
122
|
-
return worstInteractionOutcome.isWorseThan(scenarioOutcome)
|
|
123
|
-
? worstInteractionOutcome
|
|
124
|
-
: scenarioOutcome;
|
|
125
71
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (['failed', 'interrupted', 'timedOut'].includes(result.status)) {
|
|
135
|
-
if (test.retries > result.retry) {
|
|
136
|
-
return new model_1.ExecutionIgnored(this.errorParser.errorFrom(result.error));
|
|
72
|
+
countPendingAfterAllHooks(test) {
|
|
73
|
+
let currentSuite = test.parent;
|
|
74
|
+
const pendingAfterAllHooks = [];
|
|
75
|
+
while (currentSuite) {
|
|
76
|
+
const remainingSuites = (this.suiteTestCounts.get(currentSuite) || 0) - 1;
|
|
77
|
+
this.suiteTestCounts.set(currentSuite, remainingSuites);
|
|
78
|
+
if (remainingSuites === 0 && currentSuite['_hooks'].some((hook) => hook.type === 'afterAll')) {
|
|
79
|
+
pendingAfterAllHooks.push(currentSuite);
|
|
137
80
|
}
|
|
138
|
-
|
|
81
|
+
currentSuite = currentSuite.parent;
|
|
139
82
|
}
|
|
140
|
-
return
|
|
83
|
+
return pendingAfterAllHooks.length;
|
|
141
84
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const name = scenarioName || describeOrItBlockTitle;
|
|
147
|
-
const featureName = scenarioName ? describeOrItBlockTitle : fileName;
|
|
148
|
-
return {
|
|
149
|
-
scenarioDetails: new model_1.ScenarioDetails(new model_1.Name(model_1.Tags.stripFrom(name)), new model_1.Category(model_1.Tags.stripFrom(featureName)), new io_1.FileSystemLocation(path, test.location.line, test.location.column)),
|
|
150
|
-
scenarioTags: model_1.Tags.from(`${featureName} ${name}`),
|
|
151
|
-
};
|
|
85
|
+
onError(error) {
|
|
86
|
+
if (!this.unhandledError) {
|
|
87
|
+
this.unhandledError = this.errorParser.errorFrom(error);
|
|
88
|
+
}
|
|
152
89
|
}
|
|
153
|
-
async onEnd() {
|
|
154
|
-
|
|
90
|
+
async onEnd(fullResult) {
|
|
91
|
+
const deferredEvents = this.eventBuffer.flushAllDeferred();
|
|
92
|
+
this.serenity.announce(...deferredEvents);
|
|
93
|
+
const fullDuration = core_1.Duration.ofMilliseconds(Math.round(fullResult.duration));
|
|
94
|
+
const endTime = new core_1.Timestamp(fullResult.startTime).plus(fullDuration);
|
|
95
|
+
this.serenity.announce(new events_1.TestRunFinishes(endTime));
|
|
155
96
|
try {
|
|
156
97
|
await this.serenity.waitForNextCue();
|
|
157
|
-
const outcome = this.unhandledError
|
|
158
|
-
new model_1.ExecutionFailedWithError(this.unhandledError)
|
|
98
|
+
const outcome = this.unhandledError
|
|
99
|
+
? new model_1.ExecutionFailedWithError(this.unhandledError)
|
|
159
100
|
: new model_1.ExecutionSuccessful();
|
|
160
|
-
this.serenity.announce(new events_1.TestRunFinished(outcome,
|
|
101
|
+
this.serenity.announce(new events_1.TestRunFinished(outcome, endTime));
|
|
161
102
|
}
|
|
162
103
|
catch (error) {
|
|
163
|
-
this.serenity.announce(new events_1.TestRunFinished(new model_1.ExecutionFailedWithError(error),
|
|
104
|
+
this.serenity.announce(new events_1.TestRunFinished(new model_1.ExecutionFailedWithError(error), endTime));
|
|
164
105
|
throw error;
|
|
165
106
|
}
|
|
166
107
|
}
|
|
167
|
-
// TODO emit a text artifact with stdout
|
|
108
|
+
// TODO emit a text artifact with stdout
|
|
168
109
|
// reporter.onStdErr(chunk, test, result)
|
|
169
110
|
// reporter.onStdOut(chunk, test, result)
|
|
170
|
-
emit(...events) {
|
|
171
|
-
events.forEach((event) => {
|
|
172
|
-
this.serenity.announce(event);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
announceRetryIfNeeded(test, result) {
|
|
176
|
-
if (test.retries === 0) {
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
const currentSceneId = this.sceneIds.get(test.id);
|
|
180
|
-
this.emit(new events_1.RetryableSceneDetected(currentSceneId, this.now()), new events_1.SceneTagged(currentSceneId, new model_1.ArbitraryTag('retried'), // todo: replace with a dedicated tag
|
|
181
|
-
this.now()));
|
|
182
|
-
if (result.retry > 0) {
|
|
183
|
-
this.emit(new events_1.SceneTagged(currentSceneId, new model_1.ExecutionRetriedTag(result.retry), this.serenity.currentTime()));
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
now() {
|
|
187
|
-
return this.serenity.currentTime();
|
|
188
|
-
}
|
|
189
111
|
printsToStdio() {
|
|
190
112
|
return true;
|
|
191
113
|
}
|
|
192
114
|
}
|
|
193
115
|
exports.SerenityReporterForPlaywrightTest = SerenityReporterForPlaywrightTest;
|
|
194
|
-
class PlaywrightErrorParser {
|
|
195
|
-
static ascii = new RegExp('[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))', // eslint-disable-line no-control-regex
|
|
196
|
-
'g');
|
|
197
|
-
errorFrom(testError) {
|
|
198
|
-
const message = testError.message && PlaywrightErrorParser.stripAsciiFrom(testError.message);
|
|
199
|
-
let stack = testError.stack && PlaywrightErrorParser.stripAsciiFrom(testError.stack);
|
|
200
|
-
// TODO: Do I need to process it?
|
|
201
|
-
// const value = testError.value;
|
|
202
|
-
const prologue = `Error: ${message}`;
|
|
203
|
-
if (stack && message && stack.startsWith(prologue)) {
|
|
204
|
-
stack = stack.slice(prologue.length);
|
|
205
|
-
}
|
|
206
|
-
if (testError.cause) {
|
|
207
|
-
stack += `\nCaused by: ${this.errorFrom(testError.cause).stack}`;
|
|
208
|
-
}
|
|
209
|
-
const error = new Error(message);
|
|
210
|
-
error.stack = stack;
|
|
211
|
-
return error;
|
|
212
|
-
}
|
|
213
|
-
static stripAsciiFrom(text) {
|
|
214
|
-
return text.replace(this.ascii, '');
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
116
|
//# sourceMappingURL=SerenityReporterForPlaywrightTest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SerenityReporterForPlaywrightTest.js","sourceRoot":"","sources":["../../src/reporter/SerenityReporterForPlaywrightTest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SerenityReporterForPlaywrightTest.js","sourceRoot":"","sources":["../../src/reporter/SerenityReporterForPlaywrightTest.ts"],"names":[],"mappings":"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"}
|
package/lib/reporter/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,qCAAqC,CAAC"}
|
package/lib/reporter/index.js
CHANGED
|
@@ -14,8 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./DomainEventBuffer"), exports);
|
|
18
|
-
__exportStar(require("./PlaywrightAttachments"), exports);
|
|
19
17
|
__exportStar(require("./PlaywrightStepReporter"), exports);
|
|
20
18
|
__exportStar(require("./SerenityReporterForPlaywrightTest"), exports);
|
|
21
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reporter/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAyC;AACzC,sEAAoD"}
|