@serenity-js/webdriverio 2.32.5 → 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.
Files changed (240) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/lib/adapter/WebdriverIOFrameworkAdapter.js +1 -1
  3. package/lib/adapter/WebdriverIOFrameworkAdapter.js.map +1 -1
  4. package/lib/adapter/WebdriverIONotifier.d.ts +35 -1
  5. package/lib/adapter/WebdriverIONotifier.js +174 -13
  6. package/lib/adapter/WebdriverIONotifier.js.map +1 -1
  7. package/lib/index.d.ts +0 -3
  8. package/lib/index.js +0 -3
  9. package/lib/index.js.map +1 -1
  10. package/lib/screenplay/abilities/{BrowseTheWeb.d.ts → BrowseTheWebWithWebdriverIO.d.ts} +79 -23
  11. package/lib/screenplay/abilities/{BrowseTheWeb.js → BrowseTheWebWithWebdriverIO.js} +160 -25
  12. package/lib/screenplay/abilities/BrowseTheWebWithWebdriverIO.js.map +1 -0
  13. package/lib/screenplay/abilities/index.d.ts +1 -1
  14. package/lib/screenplay/abilities/index.js +1 -1
  15. package/lib/screenplay/abilities/index.js.map +1 -1
  16. package/lib/screenplay/index.d.ts +1 -2
  17. package/lib/screenplay/index.js +1 -2
  18. package/lib/screenplay/index.js.map +1 -1
  19. package/lib/screenplay/models/WebdriverIOCookie.d.ts +8 -0
  20. package/lib/screenplay/models/WebdriverIOCookie.js +39 -0
  21. package/lib/screenplay/models/WebdriverIOCookie.js.map +1 -0
  22. package/lib/screenplay/models/WebdriverIOModalDialog.d.ts +11 -0
  23. package/lib/screenplay/models/WebdriverIOModalDialog.js +40 -0
  24. package/lib/screenplay/models/WebdriverIOModalDialog.js.map +1 -0
  25. package/lib/screenplay/models/WebdriverIONativeElementRoot.d.ts +2 -0
  26. package/lib/screenplay/{interactions/EnterBuilder.js → models/WebdriverIONativeElementRoot.js} +1 -1
  27. package/lib/screenplay/models/WebdriverIONativeElementRoot.js.map +1 -0
  28. package/lib/screenplay/models/WebdriverIOPage.d.ts +24 -0
  29. package/lib/screenplay/models/WebdriverIOPage.js +98 -0
  30. package/lib/screenplay/models/WebdriverIOPage.js.map +1 -0
  31. package/lib/screenplay/models/WebdriverIOPageElement.d.ts +22 -0
  32. package/lib/screenplay/models/WebdriverIOPageElement.js +75 -0
  33. package/lib/screenplay/models/WebdriverIOPageElement.js.map +1 -0
  34. package/lib/screenplay/models/WebdriverIOPageElements.d.ts +15 -0
  35. package/lib/screenplay/models/WebdriverIOPageElements.js +65 -0
  36. package/lib/screenplay/models/WebdriverIOPageElements.js.map +1 -0
  37. package/lib/screenplay/models/index.d.ts +6 -0
  38. package/lib/{input → screenplay/models}/index.js +6 -1
  39. package/lib/screenplay/models/index.js.map +1 -0
  40. package/package.json +11 -21
  41. package/src/adapter/WebdriverIOFrameworkAdapter.ts +2 -0
  42. package/src/adapter/WebdriverIONotifier.ts +225 -23
  43. package/src/index.ts +0 -3
  44. package/src/screenplay/abilities/{BrowseTheWeb.ts → BrowseTheWebWithWebdriverIO.ts} +200 -31
  45. package/src/screenplay/abilities/index.ts +1 -1
  46. package/src/screenplay/index.ts +1 -2
  47. package/src/screenplay/models/WebdriverIOCookie.ts +44 -0
  48. package/src/screenplay/models/WebdriverIOModalDialog.ts +45 -0
  49. package/src/screenplay/models/WebdriverIONativeElementRoot.ts +3 -0
  50. package/src/screenplay/models/WebdriverIOPage.ts +120 -0
  51. package/src/screenplay/models/WebdriverIOPageElement.ts +92 -0
  52. package/src/screenplay/models/WebdriverIOPageElements.ts +91 -0
  53. package/src/screenplay/models/index.ts +6 -0
  54. package/lib/expectations/ElementExpectation.d.ts +0 -11
  55. package/lib/expectations/ElementExpectation.js +0 -27
  56. package/lib/expectations/ElementExpectation.js.map +0 -1
  57. package/lib/expectations/index.d.ts +0 -6
  58. package/lib/expectations/index.js +0 -19
  59. package/lib/expectations/index.js.map +0 -1
  60. package/lib/expectations/isActive.d.ts +0 -15
  61. package/lib/expectations/isActive.js +0 -21
  62. package/lib/expectations/isActive.js.map +0 -1
  63. package/lib/expectations/isClickable.d.ts +0 -20
  64. package/lib/expectations/isClickable.js +0 -26
  65. package/lib/expectations/isClickable.js.map +0 -1
  66. package/lib/expectations/isEnabled.d.ts +0 -14
  67. package/lib/expectations/isEnabled.js +0 -20
  68. package/lib/expectations/isEnabled.js.map +0 -1
  69. package/lib/expectations/isPresent.d.ts +0 -15
  70. package/lib/expectations/isPresent.js +0 -21
  71. package/lib/expectations/isPresent.js.map +0 -1
  72. package/lib/expectations/isSelected.d.ts +0 -14
  73. package/lib/expectations/isSelected.js +0 -20
  74. package/lib/expectations/isSelected.js.map +0 -1
  75. package/lib/expectations/isVisible.d.ts +0 -14
  76. package/lib/expectations/isVisible.js +0 -20
  77. package/lib/expectations/isVisible.js.map +0 -1
  78. package/lib/input/Key.d.ts +0 -73
  79. package/lib/input/Key.js +0 -84
  80. package/lib/input/Key.js.map +0 -1
  81. package/lib/input/index.d.ts +0 -1
  82. package/lib/input/index.js.map +0 -1
  83. package/lib/screenplay/abilities/BrowseTheWeb.js.map +0 -1
  84. package/lib/screenplay/interactions/Clear.d.ts +0 -79
  85. package/lib/screenplay/interactions/Clear.js +0 -97
  86. package/lib/screenplay/interactions/Clear.js.map +0 -1
  87. package/lib/screenplay/interactions/Click.d.ts +0 -73
  88. package/lib/screenplay/interactions/Click.js +0 -84
  89. package/lib/screenplay/interactions/Click.js.map +0 -1
  90. package/lib/screenplay/interactions/DoubleClick.d.ts +0 -90
  91. package/lib/screenplay/interactions/DoubleClick.js +0 -101
  92. package/lib/screenplay/interactions/DoubleClick.js.map +0 -1
  93. package/lib/screenplay/interactions/Enter.d.ts +0 -73
  94. package/lib/screenplay/interactions/Enter.js +0 -87
  95. package/lib/screenplay/interactions/Enter.js.map +0 -1
  96. package/lib/screenplay/interactions/EnterBuilder.d.ts +0 -25
  97. package/lib/screenplay/interactions/EnterBuilder.js.map +0 -1
  98. package/lib/screenplay/interactions/ExecuteScript.d.ts +0 -206
  99. package/lib/screenplay/interactions/ExecuteScript.js +0 -311
  100. package/lib/screenplay/interactions/ExecuteScript.js.map +0 -1
  101. package/lib/screenplay/interactions/Hover.d.ts +0 -78
  102. package/lib/screenplay/interactions/Hover.js +0 -89
  103. package/lib/screenplay/interactions/Hover.js.map +0 -1
  104. package/lib/screenplay/interactions/Navigate.d.ts +0 -141
  105. package/lib/screenplay/interactions/Navigate.js +0 -197
  106. package/lib/screenplay/interactions/Navigate.js.map +0 -1
  107. package/lib/screenplay/interactions/Press.d.ts +0 -84
  108. package/lib/screenplay/interactions/Press.js +0 -152
  109. package/lib/screenplay/interactions/Press.js.map +0 -1
  110. package/lib/screenplay/interactions/PressBuilder.d.ts +0 -26
  111. package/lib/screenplay/interactions/PressBuilder.js +0 -3
  112. package/lib/screenplay/interactions/PressBuilder.js.map +0 -1
  113. package/lib/screenplay/interactions/RightClick.d.ts +0 -89
  114. package/lib/screenplay/interactions/RightClick.js +0 -100
  115. package/lib/screenplay/interactions/RightClick.js.map +0 -1
  116. package/lib/screenplay/interactions/Scroll.d.ts +0 -75
  117. package/lib/screenplay/interactions/Scroll.js +0 -86
  118. package/lib/screenplay/interactions/Scroll.js.map +0 -1
  119. package/lib/screenplay/interactions/Wait.d.ts +0 -143
  120. package/lib/screenplay/interactions/Wait.js +0 -247
  121. package/lib/screenplay/interactions/Wait.js.map +0 -1
  122. package/lib/screenplay/interactions/WaitBuilder.d.ts +0 -32
  123. package/lib/screenplay/interactions/WaitBuilder.js +0 -3
  124. package/lib/screenplay/interactions/WaitBuilder.js.map +0 -1
  125. package/lib/screenplay/interactions/WebElementInteraction.d.ts +0 -37
  126. package/lib/screenplay/interactions/WebElementInteraction.js +0 -52
  127. package/lib/screenplay/interactions/WebElementInteraction.js.map +0 -1
  128. package/lib/screenplay/interactions/index.d.ts +0 -13
  129. package/lib/screenplay/interactions/index.js +0 -26
  130. package/lib/screenplay/interactions/index.js.map +0 -1
  131. package/lib/screenplay/questions/Attribute.d.ts +0 -82
  132. package/lib/screenplay/questions/Attribute.js +0 -102
  133. package/lib/screenplay/questions/Attribute.js.map +0 -1
  134. package/lib/screenplay/questions/CSSClasses.d.ts +0 -92
  135. package/lib/screenplay/questions/CSSClasses.js +0 -112
  136. package/lib/screenplay/questions/CSSClasses.js.map +0 -1
  137. package/lib/screenplay/questions/LastScriptExecution.d.ts +0 -14
  138. package/lib/screenplay/questions/LastScriptExecution.js +0 -22
  139. package/lib/screenplay/questions/LastScriptExecution.js.map +0 -1
  140. package/lib/screenplay/questions/NestedTargetBuilder.d.ts +0 -27
  141. package/lib/screenplay/questions/NestedTargetBuilder.js +0 -3
  142. package/lib/screenplay/questions/NestedTargetBuilder.js.map +0 -1
  143. package/lib/screenplay/questions/TargetBuilder.d.ts +0 -25
  144. package/lib/screenplay/questions/TargetBuilder.js +0 -3
  145. package/lib/screenplay/questions/TargetBuilder.js.map +0 -1
  146. package/lib/screenplay/questions/Text.d.ts +0 -95
  147. package/lib/screenplay/questions/Text.js +0 -130
  148. package/lib/screenplay/questions/Text.js.map +0 -1
  149. package/lib/screenplay/questions/Value.d.ts +0 -63
  150. package/lib/screenplay/questions/Value.js +0 -78
  151. package/lib/screenplay/questions/Value.js.map +0 -1
  152. package/lib/screenplay/questions/Website.d.ts +0 -21
  153. package/lib/screenplay/questions/Website.js +0 -31
  154. package/lib/screenplay/questions/Website.js.map +0 -1
  155. package/lib/screenplay/questions/index.d.ts +0 -10
  156. package/lib/screenplay/questions/index.js +0 -23
  157. package/lib/screenplay/questions/index.js.map +0 -1
  158. package/lib/screenplay/questions/lists.d.ts +0 -86
  159. package/lib/screenplay/questions/lists.js +0 -137
  160. package/lib/screenplay/questions/lists.js.map +0 -1
  161. package/lib/screenplay/questions/locators.d.ts +0 -196
  162. package/lib/screenplay/questions/locators.js +0 -219
  163. package/lib/screenplay/questions/locators.js.map +0 -1
  164. package/lib/screenplay/questions/targets.d.ts +0 -254
  165. package/lib/screenplay/questions/targets.js +0 -334
  166. package/lib/screenplay/questions/targets.js.map +0 -1
  167. package/lib/stage/crew/index.d.ts +0 -1
  168. package/lib/stage/crew/index.js +0 -14
  169. package/lib/stage/crew/index.js.map +0 -1
  170. package/lib/stage/crew/photographer/Photographer.d.ts +0 -83
  171. package/lib/stage/crew/photographer/Photographer.js +0 -102
  172. package/lib/stage/crew/photographer/Photographer.js.map +0 -1
  173. package/lib/stage/crew/photographer/index.d.ts +0 -2
  174. package/lib/stage/crew/photographer/index.js +0 -15
  175. package/lib/stage/crew/photographer/index.js.map +0 -1
  176. package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.d.ts +0 -28
  177. package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.js +0 -65
  178. package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.js.map +0 -1
  179. package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.d.ts +0 -18
  180. package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.js +0 -30
  181. package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.js.map +0 -1
  182. package/lib/stage/crew/photographer/strategies/TakePhotosOfFailures.d.ts +0 -17
  183. package/lib/stage/crew/photographer/strategies/TakePhotosOfFailures.js +0 -28
  184. package/lib/stage/crew/photographer/strategies/TakePhotosOfFailures.js.map +0 -1
  185. package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.d.ts +0 -19
  186. package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.js +0 -28
  187. package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.js.map +0 -1
  188. package/lib/stage/crew/photographer/strategies/index.d.ts +0 -4
  189. package/lib/stage/crew/photographer/strategies/index.js +0 -17
  190. package/lib/stage/crew/photographer/strategies/index.js.map +0 -1
  191. package/lib/stage/index.d.ts +0 -1
  192. package/lib/stage/index.js +0 -14
  193. package/lib/stage/index.js.map +0 -1
  194. package/src/expectations/ElementExpectation.ts +0 -31
  195. package/src/expectations/index.ts +0 -6
  196. package/src/expectations/isActive.ts +0 -21
  197. package/src/expectations/isClickable.ts +0 -26
  198. package/src/expectations/isEnabled.ts +0 -19
  199. package/src/expectations/isPresent.ts +0 -20
  200. package/src/expectations/isSelected.ts +0 -19
  201. package/src/expectations/isVisible.ts +0 -19
  202. package/src/input/Key.ts +0 -83
  203. package/src/input/index.ts +0 -1
  204. package/src/screenplay/interactions/Clear.ts +0 -102
  205. package/src/screenplay/interactions/Click.ts +0 -85
  206. package/src/screenplay/interactions/DoubleClick.ts +0 -102
  207. package/src/screenplay/interactions/Enter.ts +0 -93
  208. package/src/screenplay/interactions/EnterBuilder.ts +0 -27
  209. package/src/screenplay/interactions/ExecuteScript.ts +0 -344
  210. package/src/screenplay/interactions/Hover.ts +0 -90
  211. package/src/screenplay/interactions/Navigate.ts +0 -208
  212. package/src/screenplay/interactions/Press.ts +0 -172
  213. package/src/screenplay/interactions/PressBuilder.ts +0 -28
  214. package/src/screenplay/interactions/RightClick.ts +0 -100
  215. package/src/screenplay/interactions/Scroll.ts +0 -87
  216. package/src/screenplay/interactions/Wait.ts +0 -267
  217. package/src/screenplay/interactions/WaitBuilder.ts +0 -34
  218. package/src/screenplay/interactions/WebElementInteraction.ts +0 -56
  219. package/src/screenplay/interactions/index.ts +0 -13
  220. package/src/screenplay/questions/Attribute.ts +0 -112
  221. package/src/screenplay/questions/CSSClasses.ts +0 -116
  222. package/src/screenplay/questions/LastScriptExecution.ts +0 -21
  223. package/src/screenplay/questions/NestedTargetBuilder.ts +0 -30
  224. package/src/screenplay/questions/TargetBuilder.ts +0 -27
  225. package/src/screenplay/questions/Text.ts +0 -140
  226. package/src/screenplay/questions/Value.ts +0 -82
  227. package/src/screenplay/questions/Website.ts +0 -34
  228. package/src/screenplay/questions/index.ts +0 -10
  229. package/src/screenplay/questions/lists.ts +0 -161
  230. package/src/screenplay/questions/locators.ts +0 -254
  231. package/src/screenplay/questions/targets.ts +0 -401
  232. package/src/stage/crew/index.ts +0 -1
  233. package/src/stage/crew/photographer/Photographer.ts +0 -108
  234. package/src/stage/crew/photographer/index.ts +0 -2
  235. package/src/stage/crew/photographer/strategies/PhotoTakingStrategy.ts +0 -103
  236. package/src/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.ts +0 -28
  237. package/src/stage/crew/photographer/strategies/TakePhotosOfFailures.ts +0 -26
  238. package/src/stage/crew/photographer/strategies/TakePhotosOfInteractions.ts +0 -26
  239. package/src/stage/crew/photographer/strategies/index.ts +0 -4
  240. package/src/stage/index.ts +0 -1
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebdriverIOPageElement = void 0;
4
+ const web_1 = require("@serenity-js/web");
5
+ class WebdriverIOPageElement extends web_1.PageElement {
6
+ of(parent) {
7
+ return new WebdriverIOPageElement(() => parent.nativeElement(), this.locator);
8
+ }
9
+ async clearValue() {
10
+ const element = await this.nativeElement();
11
+ return element.clearValue();
12
+ }
13
+ async click() {
14
+ const element = await this.nativeElement();
15
+ return element.click();
16
+ }
17
+ async doubleClick() {
18
+ const element = await this.nativeElement();
19
+ return element.doubleClick();
20
+ }
21
+ async enterValue(value) {
22
+ const element = await this.nativeElement();
23
+ return element.addValue(value);
24
+ }
25
+ async scrollIntoView() {
26
+ const element = await this.nativeElement();
27
+ return element.scrollIntoView();
28
+ }
29
+ async hoverOver() {
30
+ const element = await this.nativeElement();
31
+ return element.moveTo();
32
+ }
33
+ async rightClick() {
34
+ const element = await this.nativeElement();
35
+ return element.click({ button: 'right' });
36
+ }
37
+ async attribute(name) {
38
+ const element = await this.nativeElement();
39
+ return element.getAttribute(name);
40
+ }
41
+ async text() {
42
+ const element = await this.nativeElement();
43
+ return element.getText();
44
+ }
45
+ async value() {
46
+ const element = await this.nativeElement();
47
+ return element.getValue();
48
+ }
49
+ async isActive() {
50
+ const element = await this.nativeElement();
51
+ return element.isFocused();
52
+ }
53
+ async isClickable() {
54
+ const element = await this.nativeElement();
55
+ return element.isClickable();
56
+ }
57
+ async isDisplayed() {
58
+ const element = await this.nativeElement();
59
+ return element.isDisplayed();
60
+ }
61
+ async isEnabled() {
62
+ const element = await this.nativeElement();
63
+ return element.isEnabled();
64
+ }
65
+ async isPresent() {
66
+ const element = await this.nativeElement();
67
+ return element.isExisting();
68
+ }
69
+ async isSelected() {
70
+ const element = await this.nativeElement();
71
+ return element.isSelected();
72
+ }
73
+ }
74
+ exports.WebdriverIOPageElement = WebdriverIOPageElement;
75
+ //# sourceMappingURL=WebdriverIOPageElement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebdriverIOPageElement.js","sourceRoot":"","sources":["../../../src/screenplay/models/WebdriverIOPageElement.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { PageElement, PageElements } from '@serenity-js/web';
2
+ import * as wdio from 'webdriverio';
3
+ import { WebdriverIONativeElementRoot } from './WebdriverIONativeElementRoot';
4
+ import { WebdriverIOPageElement } from './WebdriverIOPageElement';
5
+ export declare class WebdriverIOPageElements extends PageElements<WebdriverIONativeElementRoot, wdio.ElementArray, wdio.Element<'async'>> {
6
+ of(parent: PageElement<WebdriverIONativeElementRoot, wdio.Element<'async'>>): WebdriverIOPageElements;
7
+ count(): Promise<number>;
8
+ first(): Promise<WebdriverIOPageElement>;
9
+ last(): Promise<WebdriverIOPageElement>;
10
+ get(index: number): Promise<WebdriverIOPageElement>;
11
+ private elementAt;
12
+ map<O>(fn: (element: PageElement, index?: number, elements?: PageElements) => Promise<O> | O): Promise<O[]>;
13
+ filter(fn: (element: PageElement, index?: number) => Promise<boolean> | boolean): WebdriverIOPageElements;
14
+ forEach(fn: (element: PageElement, index?: number, elements?: PageElements) => Promise<void> | void): Promise<void>;
15
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebdriverIOPageElements = void 0;
4
+ const core_1 = require("@serenity-js/core");
5
+ const web_1 = require("@serenity-js/web");
6
+ const WebdriverIOPageElement_1 = require("./WebdriverIOPageElement");
7
+ class WebdriverIOPageElements extends web_1.PageElements {
8
+ of(parent) {
9
+ return new WebdriverIOPageElements(() => parent.nativeElement(), this.locator);
10
+ }
11
+ async count() {
12
+ const elements = await this.nativeElementList();
13
+ return elements.length;
14
+ }
15
+ first() {
16
+ return this.elementAt(0);
17
+ }
18
+ async last() {
19
+ const elements = await this.nativeElementList();
20
+ const index = elements.length - 1;
21
+ return this.elementAt(index);
22
+ }
23
+ get(index) {
24
+ return this.elementAt(index);
25
+ }
26
+ async elementAt(index) {
27
+ const elements = await this.nativeElementList();
28
+ if (!elements[index]) {
29
+ throw new core_1.LogicError(`There's no item at index ${index}`);
30
+ }
31
+ return new WebdriverIOPageElement_1.WebdriverIOPageElement(this.context, () => elements[index]);
32
+ }
33
+ async map(fn) {
34
+ const elements = await this.nativeElementList();
35
+ return Promise.all(elements.map((element, index) => fn(new WebdriverIOPageElement_1.WebdriverIOPageElement(this.context, () => element), index, this)));
36
+ }
37
+ filter(fn) {
38
+ return new WebdriverIOPageElements(this.context, async (context) => {
39
+ const elements = await this.locator(context);
40
+ const matching = await Promise.all(elements.map(async (nativeElement, index) => {
41
+ const element = new WebdriverIOPageElement_1.WebdriverIOPageElement(this.context, () => nativeElement);
42
+ const matches = await fn(element, index);
43
+ return matches
44
+ ? nativeElement
45
+ : undefined;
46
+ }));
47
+ const results = matching.filter((element) => {
48
+ return element !== undefined;
49
+ });
50
+ results.selector = elements.selector;
51
+ results.parent = elements.parent;
52
+ results.foundWith = elements.foundWith;
53
+ results.props = elements.props;
54
+ return results;
55
+ });
56
+ }
57
+ async forEach(fn) {
58
+ const elements = await this.nativeElementList();
59
+ return elements.reduce((previous, element, index) => {
60
+ return previous.then(() => fn(new WebdriverIOPageElement_1.WebdriverIOPageElement(this.context, () => element), index, this));
61
+ }, Promise.resolve());
62
+ }
63
+ }
64
+ exports.WebdriverIOPageElements = WebdriverIOPageElements;
65
+ //# sourceMappingURL=WebdriverIOPageElements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebdriverIOPageElements.js","sourceRoot":"","sources":["../../../src/screenplay/models/WebdriverIOPageElements.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './WebdriverIOCookie';
2
+ export * from './WebdriverIOModalDialog';
3
+ export * from './WebdriverIONativeElementRoot';
4
+ export * from './WebdriverIOPage';
5
+ export * from './WebdriverIOPageElement';
6
+ export * from './WebdriverIOPageElements';
@@ -10,5 +10,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
10
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- __exportStar(require("./Key"), exports);
13
+ __exportStar(require("./WebdriverIOCookie"), exports);
14
+ __exportStar(require("./WebdriverIOModalDialog"), exports);
15
+ __exportStar(require("./WebdriverIONativeElementRoot"), exports);
16
+ __exportStar(require("./WebdriverIOPage"), exports);
17
+ __exportStar(require("./WebdriverIOPageElement"), exports);
18
+ __exportStar(require("./WebdriverIOPageElements"), exports);
14
19
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,sDAAoC;AACpC,2DAAyC;AACzC,iEAA+C;AAC/C,oDAAkC;AAClC,2DAAyC;AACzC,4DAA0C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serenity-js/webdriverio",
3
- "version": "2.32.5",
3
+ "version": "3.0.0-rc.0",
4
4
  "description": "Serenity/JS reporter and Screenplay Pattern library for WebdriverIO",
5
5
  "author": {
6
6
  "name": "Jan Molak",
@@ -33,12 +33,7 @@
33
33
  "clean": "rimraf .nyc_output lib target",
34
34
  "lint": "eslint --ext ts --config ../../.eslintrc.js .",
35
35
  "lint:fix": "npm run lint -- --fix",
36
- "test": "npm run test:mocha && npm run test:wdio",
37
- "test:mocha": "nyc --report-dir ../../target/coverage/webdriverio/mocha mocha --config ../../.mocharc.yml 'spec/adapter/**/*.spec.*'",
38
- "test:wdio": "cross-env PORT=8080 start-server-and-test test:wdio:start-server http://localhost:8080 test:wdio:run",
39
- "test:wdio:start-server": "static-content-server",
40
- "test:wdio:run": "nyc --report-dir ../../target/coverage/webdriverio/wdio wdio ./spec/wdio.conf.ts",
41
- "wdio": "wdio ./spec/wdio.conf.ts",
36
+ "test": "nyc --report-dir ../../target/coverage/webdriverio/mocha mocha --config ../../.mocharc.yml 'spec/adapter/**/*.spec.*'",
42
37
  "compile": "tsc --project tsconfig.json",
43
38
  "site": "esdoc -c .esdoc.js"
44
39
  },
@@ -50,11 +45,12 @@
50
45
  "url": "https://github.com/serenity-js/serenity-js/issues"
51
46
  },
52
47
  "engines": {
53
- "node": "^12 || ^14 || ^16",
48
+ "node": "^14 || ^16",
54
49
  "npm": "^6 || ^7 || ^8"
55
50
  },
56
51
  "dependencies": {
57
- "@serenity-js/core": "2.32.5",
52
+ "@serenity-js/core": "3.0.0-rc.0",
53
+ "@serenity-js/web": "3.0.0-rc.0",
58
54
  "@wdio/reporter": "^7.16.3",
59
55
  "@wdio/types": "^7.16.3",
60
56
  "deepmerge": "^4.2.2",
@@ -62,10 +58,11 @@
62
58
  "tiny-types": "^1.16.1"
63
59
  },
64
60
  "peerDependencies": {
65
- "@serenity-js/cucumber": "^2.29.0",
66
- "@serenity-js/jasmine": "^2.29.0",
67
- "@serenity-js/mocha": "^2.29.0",
68
- "@wdio/cli": "^7.16.10"
61
+ "@serenity-js/cucumber": "^2.32.5",
62
+ "@serenity-js/jasmine": "^2.32.5",
63
+ "@serenity-js/mocha": "^2.32.5",
64
+ "@wdio/cli": "^7.16.10",
65
+ "webdriverio": "^7.16.10"
69
66
  },
70
67
  "peerDependenciesMeta": {
71
68
  "@serenity-js/cucumber": {
@@ -81,13 +78,6 @@
81
78
  "devDependencies": {
82
79
  "@documentation/esdoc-template": "2.0.0",
83
80
  "@integration/testing-tools": "2.0.0",
84
- "@integration/web-testing-tools": "2.0.0",
85
- "@serenity-js/assertions": "2.32.5",
86
- "@serenity-js/console-reporter": "2.32.5",
87
- "@serenity-js/cucumber": "2.32.5",
88
- "@serenity-js/jasmine": "2.32.5",
89
- "@serenity-js/mocha": "2.32.5",
90
- "@serenity-js/rest": "2.32.5",
91
81
  "@types/mocha": "^9.0.0",
92
82
  "@wdio/cli": "^7.16.10",
93
83
  "@wdio/devtools-service": "^7.16.10",
@@ -122,5 +112,5 @@
122
112
  "cache": true,
123
113
  "all": false
124
114
  },
125
- "gitHead": "d6dce465bdafee180a8f2af2a27b676c1654c853"
115
+ "gitHead": "a63381d088cc068bc3edcbd1eb59a7e609cb6a8c"
126
116
  }
@@ -44,6 +44,8 @@ export class WebdriverIOFrameworkAdapter {
44
44
  ]));
45
45
 
46
46
  this.notifier = new WebdriverIONotifier(
47
+ config,
48
+ capabilities,
47
49
  reporter,
48
50
  this.adapter.successThreshold(),
49
51
  cid,
@@ -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
- this.reporter.emit('suite:start', this.suiteStartEventFrom(started));
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
- this.reporter.emit('suite:end', this.suiteEndEventFrom(started, finished));
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
- const testResult = this.testEndEventFrom(started, finished);
146
+ testEnd = this.testEndEventFrom(started, finished);
114
147
 
115
148
  const type = 'test:retry';
116
149
 
117
150
  this.reporter.emit(type, {
118
- ...testResult,
151
+ ...testEnd,
119
152
  type,
120
153
  error: this.errorFrom(finished.outcome),
121
154
  });
122
155
 
123
156
  } else {
124
157
 
125
- const testResult = this.testResultEventFrom(started, finished);
126
- this.reporter.emit(testResult.type, testResult);
158
+ const testResultEvent = this.testResultEventFrom(started, finished);
159
+ this.reporter.emit(testResultEvent.type, testResultEvent);
127
160
 
128
- const testEnd = this.testEndEventFrom(started, finished);
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 testStartEventFrom(started: SceneStarts): Test {
138
- const title = started.details.name.value
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
- private testEndEventFrom(started: SceneStarts, finished: SceneFinished): Test {
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 testResultEventFrom(started: SceneStarts, finished: SceneFinished): Test {
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: Test['type']) =>
172
- ! outcome.isWorseThan(this.successThreshold) && (outcome instanceof ProblemIndication)
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, Test>(finished.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';