@serenity-js/webdriverio 2.32.2 → 3.0.0-rc.0
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 +73 -0
- package/lib/adapter/WebdriverIOFrameworkAdapter.js +1 -1
- package/lib/adapter/WebdriverIOFrameworkAdapter.js.map +1 -1
- package/lib/adapter/WebdriverIONotifier.d.ts +35 -1
- package/lib/adapter/WebdriverIONotifier.js +174 -13
- package/lib/adapter/WebdriverIONotifier.js.map +1 -1
- package/lib/index.d.ts +0 -3
- package/lib/index.js +0 -3
- package/lib/index.js.map +1 -1
- package/lib/screenplay/abilities/{BrowseTheWeb.d.ts → BrowseTheWebWithWebdriverIO.d.ts} +79 -23
- package/lib/screenplay/abilities/{BrowseTheWeb.js → BrowseTheWebWithWebdriverIO.js} +160 -25
- package/lib/screenplay/abilities/BrowseTheWebWithWebdriverIO.js.map +1 -0
- package/lib/screenplay/abilities/index.d.ts +1 -1
- package/lib/screenplay/abilities/index.js +1 -1
- package/lib/screenplay/abilities/index.js.map +1 -1
- package/lib/screenplay/index.d.ts +1 -2
- package/lib/screenplay/index.js +1 -2
- package/lib/screenplay/index.js.map +1 -1
- package/lib/screenplay/models/WebdriverIOCookie.d.ts +8 -0
- package/lib/screenplay/models/WebdriverIOCookie.js +39 -0
- package/lib/screenplay/models/WebdriverIOCookie.js.map +1 -0
- package/lib/screenplay/models/WebdriverIOModalDialog.d.ts +11 -0
- package/lib/screenplay/models/WebdriverIOModalDialog.js +40 -0
- package/lib/screenplay/models/WebdriverIOModalDialog.js.map +1 -0
- package/lib/screenplay/models/WebdriverIONativeElementRoot.d.ts +2 -0
- package/lib/screenplay/{interactions/EnterBuilder.js → models/WebdriverIONativeElementRoot.js} +1 -1
- package/lib/screenplay/models/WebdriverIONativeElementRoot.js.map +1 -0
- package/lib/screenplay/models/WebdriverIOPage.d.ts +24 -0
- package/lib/screenplay/models/WebdriverIOPage.js +98 -0
- package/lib/screenplay/models/WebdriverIOPage.js.map +1 -0
- package/lib/screenplay/models/WebdriverIOPageElement.d.ts +22 -0
- package/lib/screenplay/models/WebdriverIOPageElement.js +75 -0
- package/lib/screenplay/models/WebdriverIOPageElement.js.map +1 -0
- package/lib/screenplay/models/WebdriverIOPageElements.d.ts +15 -0
- package/lib/screenplay/models/WebdriverIOPageElements.js +65 -0
- package/lib/screenplay/models/WebdriverIOPageElements.js.map +1 -0
- package/lib/screenplay/models/index.d.ts +6 -0
- package/lib/{input → screenplay/models}/index.js +6 -1
- package/lib/screenplay/models/index.js.map +1 -0
- package/package.json +22 -32
- package/src/adapter/WebdriverIOFrameworkAdapter.ts +2 -0
- package/src/adapter/WebdriverIONotifier.ts +225 -23
- package/src/index.ts +0 -3
- package/src/screenplay/abilities/{BrowseTheWeb.ts → BrowseTheWebWithWebdriverIO.ts} +200 -31
- package/src/screenplay/abilities/index.ts +1 -1
- package/src/screenplay/index.ts +1 -2
- package/src/screenplay/models/WebdriverIOCookie.ts +44 -0
- package/src/screenplay/models/WebdriverIOModalDialog.ts +45 -0
- package/src/screenplay/models/WebdriverIONativeElementRoot.ts +3 -0
- package/src/screenplay/models/WebdriverIOPage.ts +120 -0
- package/src/screenplay/models/WebdriverIOPageElement.ts +92 -0
- package/src/screenplay/models/WebdriverIOPageElements.ts +91 -0
- package/src/screenplay/models/index.ts +6 -0
- package/lib/expectations/ElementExpectation.d.ts +0 -11
- package/lib/expectations/ElementExpectation.js +0 -27
- package/lib/expectations/ElementExpectation.js.map +0 -1
- package/lib/expectations/index.d.ts +0 -6
- package/lib/expectations/index.js +0 -19
- package/lib/expectations/index.js.map +0 -1
- package/lib/expectations/isActive.d.ts +0 -15
- package/lib/expectations/isActive.js +0 -21
- package/lib/expectations/isActive.js.map +0 -1
- package/lib/expectations/isClickable.d.ts +0 -20
- package/lib/expectations/isClickable.js +0 -26
- package/lib/expectations/isClickable.js.map +0 -1
- package/lib/expectations/isEnabled.d.ts +0 -14
- package/lib/expectations/isEnabled.js +0 -20
- package/lib/expectations/isEnabled.js.map +0 -1
- package/lib/expectations/isPresent.d.ts +0 -15
- package/lib/expectations/isPresent.js +0 -21
- package/lib/expectations/isPresent.js.map +0 -1
- package/lib/expectations/isSelected.d.ts +0 -14
- package/lib/expectations/isSelected.js +0 -20
- package/lib/expectations/isSelected.js.map +0 -1
- package/lib/expectations/isVisible.d.ts +0 -14
- package/lib/expectations/isVisible.js +0 -20
- package/lib/expectations/isVisible.js.map +0 -1
- package/lib/input/Key.d.ts +0 -73
- package/lib/input/Key.js +0 -84
- package/lib/input/Key.js.map +0 -1
- package/lib/input/index.d.ts +0 -1
- package/lib/input/index.js.map +0 -1
- package/lib/screenplay/abilities/BrowseTheWeb.js.map +0 -1
- package/lib/screenplay/interactions/Clear.d.ts +0 -79
- package/lib/screenplay/interactions/Clear.js +0 -97
- package/lib/screenplay/interactions/Clear.js.map +0 -1
- package/lib/screenplay/interactions/Click.d.ts +0 -73
- package/lib/screenplay/interactions/Click.js +0 -84
- package/lib/screenplay/interactions/Click.js.map +0 -1
- package/lib/screenplay/interactions/DoubleClick.d.ts +0 -90
- package/lib/screenplay/interactions/DoubleClick.js +0 -101
- package/lib/screenplay/interactions/DoubleClick.js.map +0 -1
- package/lib/screenplay/interactions/Enter.d.ts +0 -73
- package/lib/screenplay/interactions/Enter.js +0 -87
- package/lib/screenplay/interactions/Enter.js.map +0 -1
- package/lib/screenplay/interactions/EnterBuilder.d.ts +0 -25
- package/lib/screenplay/interactions/EnterBuilder.js.map +0 -1
- package/lib/screenplay/interactions/ExecuteScript.d.ts +0 -206
- package/lib/screenplay/interactions/ExecuteScript.js +0 -311
- package/lib/screenplay/interactions/ExecuteScript.js.map +0 -1
- package/lib/screenplay/interactions/Hover.d.ts +0 -78
- package/lib/screenplay/interactions/Hover.js +0 -89
- package/lib/screenplay/interactions/Hover.js.map +0 -1
- package/lib/screenplay/interactions/Navigate.d.ts +0 -141
- package/lib/screenplay/interactions/Navigate.js +0 -197
- package/lib/screenplay/interactions/Navigate.js.map +0 -1
- package/lib/screenplay/interactions/Press.d.ts +0 -84
- package/lib/screenplay/interactions/Press.js +0 -152
- package/lib/screenplay/interactions/Press.js.map +0 -1
- package/lib/screenplay/interactions/PressBuilder.d.ts +0 -26
- package/lib/screenplay/interactions/PressBuilder.js +0 -3
- package/lib/screenplay/interactions/PressBuilder.js.map +0 -1
- package/lib/screenplay/interactions/RightClick.d.ts +0 -89
- package/lib/screenplay/interactions/RightClick.js +0 -100
- package/lib/screenplay/interactions/RightClick.js.map +0 -1
- package/lib/screenplay/interactions/Scroll.d.ts +0 -75
- package/lib/screenplay/interactions/Scroll.js +0 -86
- package/lib/screenplay/interactions/Scroll.js.map +0 -1
- package/lib/screenplay/interactions/Wait.d.ts +0 -143
- package/lib/screenplay/interactions/Wait.js +0 -247
- package/lib/screenplay/interactions/Wait.js.map +0 -1
- package/lib/screenplay/interactions/WaitBuilder.d.ts +0 -32
- package/lib/screenplay/interactions/WaitBuilder.js +0 -3
- package/lib/screenplay/interactions/WaitBuilder.js.map +0 -1
- package/lib/screenplay/interactions/WebElementInteraction.d.ts +0 -37
- package/lib/screenplay/interactions/WebElementInteraction.js +0 -52
- package/lib/screenplay/interactions/WebElementInteraction.js.map +0 -1
- package/lib/screenplay/interactions/index.d.ts +0 -13
- package/lib/screenplay/interactions/index.js +0 -26
- package/lib/screenplay/interactions/index.js.map +0 -1
- package/lib/screenplay/questions/Attribute.d.ts +0 -82
- package/lib/screenplay/questions/Attribute.js +0 -102
- package/lib/screenplay/questions/Attribute.js.map +0 -1
- package/lib/screenplay/questions/CSSClasses.d.ts +0 -92
- package/lib/screenplay/questions/CSSClasses.js +0 -112
- package/lib/screenplay/questions/CSSClasses.js.map +0 -1
- package/lib/screenplay/questions/LastScriptExecution.d.ts +0 -14
- package/lib/screenplay/questions/LastScriptExecution.js +0 -22
- package/lib/screenplay/questions/LastScriptExecution.js.map +0 -1
- package/lib/screenplay/questions/NestedTargetBuilder.d.ts +0 -27
- package/lib/screenplay/questions/NestedTargetBuilder.js +0 -3
- package/lib/screenplay/questions/NestedTargetBuilder.js.map +0 -1
- package/lib/screenplay/questions/TargetBuilder.d.ts +0 -25
- package/lib/screenplay/questions/TargetBuilder.js +0 -3
- package/lib/screenplay/questions/TargetBuilder.js.map +0 -1
- package/lib/screenplay/questions/Text.d.ts +0 -95
- package/lib/screenplay/questions/Text.js +0 -130
- package/lib/screenplay/questions/Text.js.map +0 -1
- package/lib/screenplay/questions/Value.d.ts +0 -63
- package/lib/screenplay/questions/Value.js +0 -78
- package/lib/screenplay/questions/Value.js.map +0 -1
- package/lib/screenplay/questions/Website.d.ts +0 -21
- package/lib/screenplay/questions/Website.js +0 -31
- package/lib/screenplay/questions/Website.js.map +0 -1
- package/lib/screenplay/questions/index.d.ts +0 -10
- package/lib/screenplay/questions/index.js +0 -23
- package/lib/screenplay/questions/index.js.map +0 -1
- package/lib/screenplay/questions/lists.d.ts +0 -86
- package/lib/screenplay/questions/lists.js +0 -137
- package/lib/screenplay/questions/lists.js.map +0 -1
- package/lib/screenplay/questions/locators.d.ts +0 -196
- package/lib/screenplay/questions/locators.js +0 -219
- package/lib/screenplay/questions/locators.js.map +0 -1
- package/lib/screenplay/questions/targets.d.ts +0 -254
- package/lib/screenplay/questions/targets.js +0 -334
- package/lib/screenplay/questions/targets.js.map +0 -1
- package/lib/stage/crew/index.d.ts +0 -1
- package/lib/stage/crew/index.js +0 -14
- package/lib/stage/crew/index.js.map +0 -1
- package/lib/stage/crew/photographer/Photographer.d.ts +0 -83
- package/lib/stage/crew/photographer/Photographer.js +0 -102
- package/lib/stage/crew/photographer/Photographer.js.map +0 -1
- package/lib/stage/crew/photographer/index.d.ts +0 -2
- package/lib/stage/crew/photographer/index.js +0 -15
- package/lib/stage/crew/photographer/index.js.map +0 -1
- package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.d.ts +0 -28
- package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.js +0 -65
- package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.js.map +0 -1
- package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.d.ts +0 -18
- package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.js +0 -30
- package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.js.map +0 -1
- package/lib/stage/crew/photographer/strategies/TakePhotosOfFailures.d.ts +0 -17
- package/lib/stage/crew/photographer/strategies/TakePhotosOfFailures.js +0 -28
- package/lib/stage/crew/photographer/strategies/TakePhotosOfFailures.js.map +0 -1
- package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.d.ts +0 -19
- package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.js +0 -28
- package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.js.map +0 -1
- package/lib/stage/crew/photographer/strategies/index.d.ts +0 -4
- package/lib/stage/crew/photographer/strategies/index.js +0 -17
- package/lib/stage/crew/photographer/strategies/index.js.map +0 -1
- package/lib/stage/index.d.ts +0 -1
- package/lib/stage/index.js +0 -14
- package/lib/stage/index.js.map +0 -1
- package/src/expectations/ElementExpectation.ts +0 -31
- package/src/expectations/index.ts +0 -6
- package/src/expectations/isActive.ts +0 -21
- package/src/expectations/isClickable.ts +0 -26
- package/src/expectations/isEnabled.ts +0 -19
- package/src/expectations/isPresent.ts +0 -20
- package/src/expectations/isSelected.ts +0 -19
- package/src/expectations/isVisible.ts +0 -19
- package/src/input/Key.ts +0 -83
- package/src/input/index.ts +0 -1
- package/src/screenplay/interactions/Clear.ts +0 -102
- package/src/screenplay/interactions/Click.ts +0 -85
- package/src/screenplay/interactions/DoubleClick.ts +0 -102
- package/src/screenplay/interactions/Enter.ts +0 -93
- package/src/screenplay/interactions/EnterBuilder.ts +0 -27
- package/src/screenplay/interactions/ExecuteScript.ts +0 -344
- package/src/screenplay/interactions/Hover.ts +0 -90
- package/src/screenplay/interactions/Navigate.ts +0 -208
- package/src/screenplay/interactions/Press.ts +0 -172
- package/src/screenplay/interactions/PressBuilder.ts +0 -28
- package/src/screenplay/interactions/RightClick.ts +0 -100
- package/src/screenplay/interactions/Scroll.ts +0 -87
- package/src/screenplay/interactions/Wait.ts +0 -267
- package/src/screenplay/interactions/WaitBuilder.ts +0 -34
- package/src/screenplay/interactions/WebElementInteraction.ts +0 -56
- package/src/screenplay/interactions/index.ts +0 -13
- package/src/screenplay/questions/Attribute.ts +0 -112
- package/src/screenplay/questions/CSSClasses.ts +0 -116
- package/src/screenplay/questions/LastScriptExecution.ts +0 -21
- package/src/screenplay/questions/NestedTargetBuilder.ts +0 -30
- package/src/screenplay/questions/TargetBuilder.ts +0 -27
- package/src/screenplay/questions/Text.ts +0 -140
- package/src/screenplay/questions/Value.ts +0 -82
- package/src/screenplay/questions/Website.ts +0 -34
- package/src/screenplay/questions/index.ts +0 -10
- package/src/screenplay/questions/lists.ts +0 -161
- package/src/screenplay/questions/locators.ts +0 -254
- package/src/screenplay/questions/targets.ts +0 -401
- package/src/stage/crew/index.ts +0 -1
- package/src/stage/crew/photographer/Photographer.ts +0 -108
- package/src/stage/crew/photographer/index.ts +0 -2
- package/src/stage/crew/photographer/strategies/PhotoTakingStrategy.ts +0 -103
- package/src/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.ts +0 -28
- package/src/stage/crew/photographer/strategies/TakePhotosOfFailures.ts +0 -26
- package/src/stage/crew/photographer/strategies/TakePhotosOfInteractions.ts +0 -26
- package/src/stage/crew/photographer/strategies/index.ts +0 -4
- package/src/stage/index.ts +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { LogicError, Stage, StageCrewMember } from '@serenity-js/core';
|
|
2
|
-
import { DomainEvent, SceneFinished, SceneStarts, TestSuiteFinished, TestSuiteStarts } from '@serenity-js/core/lib/events';
|
|
2
|
+
import { AsyncOperationAttempted, AsyncOperationCompleted, DomainEvent, SceneFinished, SceneStarts, TestRunFinishes, TestSuiteFinished, TestSuiteStarts } from '@serenity-js/core/lib/events';
|
|
3
3
|
import {
|
|
4
4
|
CorrelationId,
|
|
5
|
+
Description,
|
|
5
6
|
ExecutionCompromised,
|
|
6
7
|
ExecutionFailedWithAssertionError,
|
|
7
8
|
ExecutionFailedWithError,
|
|
@@ -12,20 +13,35 @@ import {
|
|
|
12
13
|
ProblemIndication,
|
|
13
14
|
TestSuiteDetails,
|
|
14
15
|
} from '@serenity-js/core/lib/model';
|
|
15
|
-
import { Suite } from '@wdio/reporter/build/stats/suite';
|
|
16
|
-
import { Test } from '@wdio/reporter/build/stats/test';
|
|
16
|
+
import { Suite as suiteStats } from '@wdio/reporter/build/stats/suite';
|
|
17
|
+
import { Test as testStats } from '@wdio/reporter/build/stats/test';
|
|
18
|
+
import { RemoteCapability } from '@wdio/types/build/Capabilities';
|
|
19
|
+
import * as frameworks from '@wdio/types/build/Frameworks';
|
|
17
20
|
import type { EventEmitter } from 'events';
|
|
18
21
|
import { match } from 'tiny-types';
|
|
19
22
|
|
|
23
|
+
import { WebdriverIOConfig } from './WebdriverIOConfig';
|
|
24
|
+
|
|
20
25
|
/**
|
|
21
26
|
* @package
|
|
22
27
|
*/
|
|
23
28
|
export class WebdriverIONotifier implements StageCrewMember {
|
|
24
29
|
|
|
30
|
+
/**
|
|
31
|
+
* We don't have access to the "context" object produced by Mocha,
|
|
32
|
+
* and can't assume that other test runners have a similar concept.
|
|
33
|
+
* Since, at the time of writing, none of the WebdriverIO rely on this parameter
|
|
34
|
+
* using a dummy seems to be sufficient.
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
private static dummmyContext = {};
|
|
38
|
+
|
|
25
39
|
private readonly events = new EventLog();
|
|
26
40
|
private readonly suites: TestSuiteDetails[] = [];
|
|
27
41
|
|
|
28
42
|
constructor(
|
|
43
|
+
private readonly config: WebdriverIOConfig,
|
|
44
|
+
private readonly capabilities: RemoteCapability,
|
|
29
45
|
private readonly reporter: EventEmitter,
|
|
30
46
|
private readonly successThreshold: Outcome | { Code: number },
|
|
31
47
|
private readonly cid: string,
|
|
@@ -46,28 +62,42 @@ export class WebdriverIONotifier implements StageCrewMember {
|
|
|
46
62
|
.when(TestSuiteFinished, WebdriverIONotifier.prototype.onTestSuiteFinished.bind(this))
|
|
47
63
|
.when(SceneStarts, WebdriverIONotifier.prototype.onSceneStarts.bind(this))
|
|
48
64
|
.when(SceneFinished, WebdriverIONotifier.prototype.onSceneFinished.bind(this))
|
|
65
|
+
.when(TestRunFinishes, WebdriverIONotifier.prototype.onTestRunFinishes.bind(this))
|
|
49
66
|
.else(() => void 0);
|
|
50
67
|
}
|
|
51
68
|
|
|
69
|
+
private onTestRunFinishes(): Promise<any> {
|
|
70
|
+
return this.invokeHooks('after', this.config.after, [this.failures, this.capabilities, this.specs]);
|
|
71
|
+
}
|
|
72
|
+
|
|
52
73
|
failureCount(): number {
|
|
53
74
|
return this.failures;
|
|
54
75
|
}
|
|
55
76
|
|
|
56
|
-
private onTestSuiteStarts(started: TestSuiteStarts) {
|
|
77
|
+
private onTestSuiteStarts(started: TestSuiteStarts): Promise<any> {
|
|
57
78
|
this.events.record(started.details.correlationId, started);
|
|
58
|
-
|
|
79
|
+
|
|
80
|
+
const suite = this.suiteStartEventFrom(started);
|
|
81
|
+
|
|
82
|
+
this.reporter.emit('suite:start', suite);
|
|
59
83
|
|
|
60
84
|
this.suites.push(started.details);
|
|
85
|
+
|
|
86
|
+
return this.invokeHooks('beforeSuite', this.config.beforeSuite, [suite as any]); // todo: correct types
|
|
61
87
|
}
|
|
62
88
|
|
|
63
|
-
private onTestSuiteFinished(finished: TestSuiteFinished) {
|
|
89
|
+
private onTestSuiteFinished(finished: TestSuiteFinished): Promise<any> {
|
|
64
90
|
this.suites.pop();
|
|
65
91
|
|
|
66
92
|
const started = this.events.getByCorrelationId<TestSuiteStarts>(finished.details.correlationId);
|
|
67
|
-
|
|
93
|
+
const suite = this.suiteEndEventFrom(started, finished);
|
|
94
|
+
|
|
95
|
+
this.reporter.emit('suite:end', suite);
|
|
96
|
+
|
|
97
|
+
return this.invokeHooks('afterSuite', this.config.afterSuite, [suite as any]); // todo: correct types
|
|
68
98
|
}
|
|
69
99
|
|
|
70
|
-
private suiteStartEventFrom(started: TestSuiteStarts): Suite {
|
|
100
|
+
private suiteStartEventFrom(started: TestSuiteStarts): suiteStats & frameworks.Suite {
|
|
71
101
|
return {
|
|
72
102
|
type: 'suite:start',
|
|
73
103
|
uid: started.details.correlationId.value,
|
|
@@ -85,7 +115,7 @@ export class WebdriverIONotifier implements StageCrewMember {
|
|
|
85
115
|
return this.suites.map(suite => suite.name.value).concat(name).join(' ');
|
|
86
116
|
}
|
|
87
117
|
|
|
88
|
-
private suiteEndEventFrom(started: TestSuiteStarts, finished: TestSuiteFinished): Suite {
|
|
118
|
+
private suiteEndEventFrom(started: TestSuiteStarts, finished: TestSuiteFinished): suiteStats & frameworks.Suite {
|
|
89
119
|
return {
|
|
90
120
|
...this.suiteStartEventFrom(started),
|
|
91
121
|
type: 'suite:end',
|
|
@@ -99,6 +129,8 @@ export class WebdriverIONotifier implements StageCrewMember {
|
|
|
99
129
|
this.events.record(started.sceneId, started);
|
|
100
130
|
|
|
101
131
|
this.reporter.emit(test.type, test);
|
|
132
|
+
|
|
133
|
+
return this.invokeHooks('beforeTest', this.config.beforeTest, [ this.testFrom(started), WebdriverIONotifier.dummmyContext ]);
|
|
102
134
|
}
|
|
103
135
|
|
|
104
136
|
private onSceneFinished(finished: SceneFinished) {
|
|
@@ -108,37 +140,59 @@ export class WebdriverIONotifier implements StageCrewMember {
|
|
|
108
140
|
}
|
|
109
141
|
|
|
110
142
|
const started = this.events.getByCorrelationId<SceneStarts>(finished.sceneId);
|
|
143
|
+
let testEnd: testStats;
|
|
111
144
|
|
|
112
145
|
if (this.willBeRetried(finished.outcome)) {
|
|
113
|
-
|
|
146
|
+
testEnd = this.testEndEventFrom(started, finished);
|
|
114
147
|
|
|
115
148
|
const type = 'test:retry';
|
|
116
149
|
|
|
117
150
|
this.reporter.emit(type, {
|
|
118
|
-
...
|
|
151
|
+
...testEnd,
|
|
119
152
|
type,
|
|
120
153
|
error: this.errorFrom(finished.outcome),
|
|
121
154
|
});
|
|
122
155
|
|
|
123
156
|
} else {
|
|
124
157
|
|
|
125
|
-
const
|
|
126
|
-
this.reporter.emit(
|
|
158
|
+
const testResultEvent = this.testResultEventFrom(started, finished);
|
|
159
|
+
this.reporter.emit(testResultEvent.type, testResultEvent);
|
|
127
160
|
|
|
128
|
-
|
|
161
|
+
testEnd = this.testEndEventFrom(started, finished);
|
|
129
162
|
this.reporter.emit(testEnd.type, testEnd);
|
|
130
163
|
}
|
|
164
|
+
|
|
165
|
+
return this.invokeHooks('afterTest', this.config.afterTest, [ this.testFrom(started), WebdriverIONotifier.dummmyContext, this.testResultFrom(started, finished) ]);
|
|
131
166
|
}
|
|
132
167
|
|
|
133
168
|
private willBeRetried(outcome: Outcome): outcome is ExecutionIgnored {
|
|
134
169
|
return outcome instanceof ExecutionIgnored;
|
|
135
170
|
}
|
|
136
171
|
|
|
137
|
-
private
|
|
138
|
-
|
|
172
|
+
private testShortTitleFrom(started: SceneStarts): string {
|
|
173
|
+
return started.details.name.value
|
|
139
174
|
.replace(new RegExp(`^.*?(${ this.parentSuiteName() })`), '')
|
|
140
175
|
.trim();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private testFrom(started: SceneStarts): frameworks.Test {
|
|
179
|
+
const
|
|
180
|
+
title = this.testShortTitleFrom(started);
|
|
141
181
|
|
|
182
|
+
return {
|
|
183
|
+
ctx: WebdriverIONotifier.dummmyContext,
|
|
184
|
+
file: started.details.location.path.value,
|
|
185
|
+
fullName: this.suiteNamesConcatenatedWith(title),
|
|
186
|
+
fullTitle: this.suiteNamesConcatenatedWith(title),
|
|
187
|
+
parent: this.parentSuiteName(),
|
|
188
|
+
pending: false,
|
|
189
|
+
title,
|
|
190
|
+
type: 'test' // I _think_ it's either 'test' or 'hook' - https://github.com/mochajs/mocha/blob/0ea732c1169c678ef116c3eb452cc94758fff150/lib/test.js#L31
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private testStartEventFrom(started: SceneStarts): testStats {
|
|
195
|
+
const title = this.testShortTitleFrom(started);
|
|
142
196
|
return {
|
|
143
197
|
type: 'test:start',
|
|
144
198
|
title,
|
|
@@ -156,7 +210,95 @@ export class WebdriverIONotifier implements StageCrewMember {
|
|
|
156
210
|
return this.suites[this.suites.length - 1]?.name.value || '';
|
|
157
211
|
}
|
|
158
212
|
|
|
159
|
-
|
|
213
|
+
/**
|
|
214
|
+
* test status is 'passed' | 'pending' | 'skipped' | 'failed' | 'broken' | 'canceled'
|
|
215
|
+
* Since this is not documented, we're mimicking other WebdriverIO reporters, for example:
|
|
216
|
+
* https://github.com/webdriverio/webdriverio/blob/7415f3126e15a733b51721492e4995ceafae6046/packages/wdio-allure-reporter/src/constants.ts#L3-L9
|
|
217
|
+
*
|
|
218
|
+
* @param started
|
|
219
|
+
* @param finished
|
|
220
|
+
* @private
|
|
221
|
+
*/
|
|
222
|
+
private testResultFrom(started: SceneStarts, finished: SceneFinished): frameworks.TestResult {
|
|
223
|
+
const duration = finished.timestamp.diff(started.timestamp).inMilliseconds();
|
|
224
|
+
const defaultRetries = { attempts: 0, limit: 0 };
|
|
225
|
+
|
|
226
|
+
const passedOrFailed = (outcome: Outcome): boolean =>
|
|
227
|
+
this.whenSuccessful<boolean>(outcome, true, false);
|
|
228
|
+
|
|
229
|
+
return match<Outcome, frameworks.TestResult>(finished.outcome)
|
|
230
|
+
.when(ExecutionCompromised, (outcome: ExecutionCompromised) => {
|
|
231
|
+
const error = this.errorFrom(outcome);
|
|
232
|
+
return {
|
|
233
|
+
duration,
|
|
234
|
+
error,
|
|
235
|
+
exception: error.message,
|
|
236
|
+
passed: passedOrFailed(outcome),
|
|
237
|
+
status: 'broken',
|
|
238
|
+
retries: defaultRetries
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
.when(ExecutionFailedWithError, (outcome: ExecutionFailedWithError) => {
|
|
242
|
+
const error = this.errorFrom(outcome);
|
|
243
|
+
return {
|
|
244
|
+
duration,
|
|
245
|
+
error,
|
|
246
|
+
exception: error.message,
|
|
247
|
+
passed: passedOrFailed(outcome),
|
|
248
|
+
status: 'broken',
|
|
249
|
+
retries: defaultRetries
|
|
250
|
+
}
|
|
251
|
+
})
|
|
252
|
+
.when(ExecutionFailedWithAssertionError, (outcome: ExecutionFailedWithAssertionError) => {
|
|
253
|
+
const error = this.errorFrom(outcome);
|
|
254
|
+
return {
|
|
255
|
+
duration,
|
|
256
|
+
error,
|
|
257
|
+
exception: error.message,
|
|
258
|
+
passed: passedOrFailed(outcome),
|
|
259
|
+
status: 'failed',
|
|
260
|
+
retries: defaultRetries
|
|
261
|
+
}
|
|
262
|
+
})
|
|
263
|
+
.when(ImplementationPending, (outcome: ImplementationPending) => {
|
|
264
|
+
const error = this.errorFrom(outcome);
|
|
265
|
+
return {
|
|
266
|
+
duration,
|
|
267
|
+
error,
|
|
268
|
+
exception: error.message,
|
|
269
|
+
passed: passedOrFailed(outcome),
|
|
270
|
+
status: 'pending',
|
|
271
|
+
retries: defaultRetries
|
|
272
|
+
}
|
|
273
|
+
})
|
|
274
|
+
.when(ExecutionIgnored, (outcome: ExecutionIgnored) => {
|
|
275
|
+
const error = this.errorFrom(outcome);
|
|
276
|
+
return {
|
|
277
|
+
duration,
|
|
278
|
+
error,
|
|
279
|
+
exception: error.message,
|
|
280
|
+
passed: passedOrFailed(outcome),
|
|
281
|
+
status: 'canceled', // fixme: mark as canceled for now for the lack of a better alternative;
|
|
282
|
+
retries: defaultRetries // consider capturing info about retries from Mocha and putting it on the ExecutionIgnored event so we can pass it on
|
|
283
|
+
}
|
|
284
|
+
})
|
|
285
|
+
.when(ExecutionSkipped, (outcome: ExecutionSkipped) => ({
|
|
286
|
+
duration,
|
|
287
|
+
exception: '',
|
|
288
|
+
passed: passedOrFailed(outcome),
|
|
289
|
+
status: 'skipped',
|
|
290
|
+
retries: defaultRetries
|
|
291
|
+
}))
|
|
292
|
+
.else(() => ({
|
|
293
|
+
duration,
|
|
294
|
+
exception: '',
|
|
295
|
+
passed: true,
|
|
296
|
+
status: 'passed',
|
|
297
|
+
retries: defaultRetries
|
|
298
|
+
}));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private testEndEventFrom(started: SceneStarts, finished: SceneFinished): testStats {
|
|
160
302
|
const duration = finished.timestamp.diff(started.timestamp).inMilliseconds();
|
|
161
303
|
return {
|
|
162
304
|
...this.testStartEventFrom(started),
|
|
@@ -165,15 +307,19 @@ export class WebdriverIONotifier implements StageCrewMember {
|
|
|
165
307
|
};
|
|
166
308
|
}
|
|
167
309
|
|
|
168
|
-
private
|
|
310
|
+
private whenSuccessful<O>(outcome: Outcome, resultWhenSuccessful: O, resultWhenNotSuccessful: O): O {
|
|
311
|
+
return ! outcome.isWorseThan(this.successThreshold) && (outcome instanceof ProblemIndication)
|
|
312
|
+
? resultWhenSuccessful
|
|
313
|
+
: resultWhenNotSuccessful
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
private testResultEventFrom(started: SceneStarts, finished: SceneFinished): testStats {
|
|
169
317
|
const test = this.testEndEventFrom(started, finished)
|
|
170
318
|
|
|
171
|
-
const unlessSuccessful = (outcome: Outcome, type:
|
|
172
|
-
|
|
173
|
-
? 'test:pass'
|
|
174
|
-
: type;
|
|
319
|
+
const unlessSuccessful = (outcome: Outcome, type: testStats['type']) =>
|
|
320
|
+
this.whenSuccessful<testStats['type']>(outcome, 'test:pass', type);
|
|
175
321
|
|
|
176
|
-
return match<Outcome,
|
|
322
|
+
return match<Outcome, testStats>(finished.outcome)
|
|
177
323
|
.when(ExecutionCompromised, (outcome: ExecutionCompromised) => ({
|
|
178
324
|
...test,
|
|
179
325
|
type: unlessSuccessful(outcome, 'test:fail'),
|
|
@@ -231,6 +377,62 @@ export class WebdriverIONotifier implements StageCrewMember {
|
|
|
231
377
|
actual: error.actual
|
|
232
378
|
}
|
|
233
379
|
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* @see https://github.com/webdriverio/webdriverio/blob/main/packages/wdio-utils/src/shim.ts
|
|
383
|
+
* @param hookName
|
|
384
|
+
* @param hookFunctions
|
|
385
|
+
* @param args
|
|
386
|
+
* @private
|
|
387
|
+
*/
|
|
388
|
+
private invokeHooks<Result, InnerArguments extends any[]>(
|
|
389
|
+
hookName: string,
|
|
390
|
+
hookFunctions: ((...parameters: InnerArguments) => Promise<Result> | Result) | Array<((...parameters: InnerArguments) => Result)>,
|
|
391
|
+
args: InnerArguments
|
|
392
|
+
): Promise<Array<Result | Error>> {
|
|
393
|
+
|
|
394
|
+
const hooks = ! Array.isArray(hookFunctions)
|
|
395
|
+
? [ hookFunctions ]
|
|
396
|
+
: hookFunctions;
|
|
397
|
+
|
|
398
|
+
const asyncOperationId = CorrelationId.create();
|
|
399
|
+
|
|
400
|
+
this.stage.announce(new AsyncOperationAttempted(
|
|
401
|
+
new Description(`[WebdriverIONotifier#invokeHooks] Invoking ${ hookName } hook`),
|
|
402
|
+
asyncOperationId,
|
|
403
|
+
));
|
|
404
|
+
|
|
405
|
+
return Promise.all(hooks.map((hook) => new Promise<Result | Error>((resolve) => {
|
|
406
|
+
let result
|
|
407
|
+
|
|
408
|
+
try {
|
|
409
|
+
result = hook(...args);
|
|
410
|
+
} catch (error) {
|
|
411
|
+
return resolve(error);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* if a promise is returned make sure we don't have a catch handler
|
|
416
|
+
* so in case of a rejection it won't cause the hook to fail
|
|
417
|
+
*/
|
|
418
|
+
if (result && typeof result.then === 'function') {
|
|
419
|
+
return result.then(resolve, (error: Error) => {
|
|
420
|
+
resolve(error);
|
|
421
|
+
})
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
resolve(result);
|
|
425
|
+
}))).
|
|
426
|
+
then(results => {
|
|
427
|
+
|
|
428
|
+
this.stage.announce(new AsyncOperationCompleted(
|
|
429
|
+
new Description(`[WebdriverIONotifier#invokeHooks] Invoking ${ hookName } hook completed`),
|
|
430
|
+
asyncOperationId,
|
|
431
|
+
));
|
|
432
|
+
|
|
433
|
+
return results;
|
|
434
|
+
});
|
|
435
|
+
}
|
|
234
436
|
}
|
|
235
437
|
|
|
236
438
|
class EventLog {
|
package/src/index.ts
CHANGED
|
@@ -12,7 +12,4 @@ const adapterFactory = new WebdriverIOFrameworkAdapterFactory(
|
|
|
12
12
|
export default adapterFactory;
|
|
13
13
|
|
|
14
14
|
export { WebdriverIOConfig } from './adapter';
|
|
15
|
-
export * from './expectations';
|
|
16
|
-
export * from './input';
|
|
17
15
|
export * from './screenplay';
|
|
18
|
-
export * from './stage';
|