@serenity-js/web 3.0.0-rc.8 → 3.0.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 (413) hide show
  1. package/CHANGELOG.md +336 -73
  2. package/README.md +8 -12
  3. package/lib/errors/BrowserWindowClosedError.d.ts +15 -0
  4. package/lib/errors/BrowserWindowClosedError.d.ts.map +1 -0
  5. package/lib/errors/BrowserWindowClosedError.js +21 -0
  6. package/lib/errors/BrowserWindowClosedError.js.map +1 -0
  7. package/lib/errors/CookieMissingError.d.ts +11 -0
  8. package/lib/errors/CookieMissingError.d.ts.map +1 -0
  9. package/lib/errors/CookieMissingError.js +10 -0
  10. package/lib/errors/CookieMissingError.js.map +1 -1
  11. package/lib/errors/ModalDialogObstructsScreenshotError.d.ts +15 -0
  12. package/lib/errors/ModalDialogObstructsScreenshotError.d.ts.map +1 -0
  13. package/lib/errors/ModalDialogObstructsScreenshotError.js +21 -0
  14. package/lib/errors/ModalDialogObstructsScreenshotError.js.map +1 -0
  15. package/lib/errors/index.d.ts +3 -0
  16. package/lib/errors/index.d.ts.map +1 -0
  17. package/lib/errors/index.js +7 -1
  18. package/lib/errors/index.js.map +1 -1
  19. package/lib/expectations/index.d.ts +1 -1
  20. package/lib/expectations/index.d.ts.map +1 -0
  21. package/lib/expectations/index.js +5 -2
  22. package/lib/expectations/index.js.map +1 -1
  23. package/lib/expectations/isActive.d.ts +14 -8
  24. package/lib/expectations/isActive.d.ts.map +1 -0
  25. package/lib/expectations/isActive.js +17 -11
  26. package/lib/expectations/isActive.js.map +1 -1
  27. package/lib/expectations/isClickable.d.ts +14 -13
  28. package/lib/expectations/isClickable.d.ts.map +1 -0
  29. package/lib/expectations/isClickable.js +15 -17
  30. package/lib/expectations/isClickable.js.map +1 -1
  31. package/lib/expectations/isEnabled.d.ts +14 -7
  32. package/lib/expectations/isEnabled.d.ts.map +1 -0
  33. package/lib/expectations/isEnabled.js +17 -9
  34. package/lib/expectations/isEnabled.js.map +1 -1
  35. package/lib/expectations/isSelected.d.ts +14 -7
  36. package/lib/expectations/isSelected.d.ts.map +1 -0
  37. package/lib/expectations/isSelected.js +15 -9
  38. package/lib/expectations/isSelected.js.map +1 -1
  39. package/lib/expectations/isVisible.d.ts +14 -7
  40. package/lib/expectations/isVisible.d.ts.map +1 -0
  41. package/lib/expectations/isVisible.js +17 -9
  42. package/lib/expectations/isVisible.js.map +1 -1
  43. package/lib/index.d.ts +1 -1
  44. package/lib/index.d.ts.map +1 -0
  45. package/lib/index.js +5 -2
  46. package/lib/index.js.map +1 -1
  47. package/lib/screenplay/abilities/BrowseTheWeb.d.ts +88 -45
  48. package/lib/screenplay/abilities/BrowseTheWeb.d.ts.map +1 -0
  49. package/lib/screenplay/abilities/BrowseTheWeb.js +89 -19
  50. package/lib/screenplay/abilities/BrowseTheWeb.js.map +1 -1
  51. package/lib/screenplay/abilities/index.d.ts +1 -1
  52. package/lib/screenplay/abilities/index.d.ts.map +1 -0
  53. package/lib/screenplay/abilities/index.js +5 -2
  54. package/lib/screenplay/abilities/index.js.map +1 -1
  55. package/lib/screenplay/index.d.ts +1 -0
  56. package/lib/screenplay/index.d.ts.map +1 -0
  57. package/lib/screenplay/index.js +5 -1
  58. package/lib/screenplay/index.js.map +1 -1
  59. package/lib/screenplay/interactions/Clear.d.ts +50 -55
  60. package/lib/screenplay/interactions/Clear.d.ts.map +1 -0
  61. package/lib/screenplay/interactions/Clear.js +70 -63
  62. package/lib/screenplay/interactions/Clear.js.map +1 -1
  63. package/lib/screenplay/interactions/Click.d.ts +41 -50
  64. package/lib/screenplay/interactions/Click.d.ts.map +1 -0
  65. package/lib/screenplay/interactions/Click.js +45 -55
  66. package/lib/screenplay/interactions/Click.js.map +1 -1
  67. package/lib/screenplay/interactions/DoubleClick.d.ts +64 -67
  68. package/lib/screenplay/interactions/DoubleClick.d.ts.map +1 -0
  69. package/lib/screenplay/interactions/DoubleClick.js +68 -72
  70. package/lib/screenplay/interactions/DoubleClick.js.map +1 -1
  71. package/lib/screenplay/interactions/Enter.d.ts +42 -51
  72. package/lib/screenplay/interactions/Enter.d.ts.map +1 -0
  73. package/lib/screenplay/interactions/Enter.js +42 -52
  74. package/lib/screenplay/interactions/Enter.js.map +1 -1
  75. package/lib/screenplay/interactions/ExecuteScript.d.ts +144 -148
  76. package/lib/screenplay/interactions/ExecuteScript.d.ts.map +1 -0
  77. package/lib/screenplay/interactions/ExecuteScript.js +163 -185
  78. package/lib/screenplay/interactions/ExecuteScript.js.map +1 -1
  79. package/lib/screenplay/interactions/Hover.d.ts +40 -50
  80. package/lib/screenplay/interactions/Hover.d.ts.map +1 -0
  81. package/lib/screenplay/interactions/Hover.js +44 -55
  82. package/lib/screenplay/interactions/Hover.js.map +1 -1
  83. package/lib/screenplay/interactions/Navigate.d.ts +106 -113
  84. package/lib/screenplay/interactions/Navigate.d.ts.map +1 -0
  85. package/lib/screenplay/interactions/Navigate.js +124 -146
  86. package/lib/screenplay/interactions/Navigate.js.map +1 -1
  87. package/lib/screenplay/interactions/PageElementInteraction.d.ts +12 -28
  88. package/lib/screenplay/interactions/PageElementInteraction.d.ts.map +1 -0
  89. package/lib/screenplay/interactions/PageElementInteraction.js +12 -33
  90. package/lib/screenplay/interactions/PageElementInteraction.js.map +1 -1
  91. package/lib/screenplay/interactions/Press.d.ts +61 -55
  92. package/lib/screenplay/interactions/Press.d.ts.map +1 -0
  93. package/lib/screenplay/interactions/Press.js +83 -72
  94. package/lib/screenplay/interactions/Press.js.map +1 -1
  95. package/lib/screenplay/interactions/RightClick.d.ts +59 -65
  96. package/lib/screenplay/interactions/RightClick.d.ts.map +1 -0
  97. package/lib/screenplay/interactions/RightClick.js +63 -70
  98. package/lib/screenplay/interactions/RightClick.js.map +1 -1
  99. package/lib/screenplay/interactions/Scroll.d.ts +46 -64
  100. package/lib/screenplay/interactions/Scroll.d.ts.map +1 -0
  101. package/lib/screenplay/interactions/Scroll.js +49 -71
  102. package/lib/screenplay/interactions/Scroll.js.map +1 -1
  103. package/lib/screenplay/interactions/Select.d.ts +217 -193
  104. package/lib/screenplay/interactions/Select.d.ts.map +1 -0
  105. package/lib/screenplay/interactions/Select.js +218 -245
  106. package/lib/screenplay/interactions/Select.js.map +1 -1
  107. package/lib/screenplay/interactions/Switch.d.ts +105 -128
  108. package/lib/screenplay/interactions/Switch.d.ts.map +1 -0
  109. package/lib/screenplay/interactions/Switch.js +121 -172
  110. package/lib/screenplay/interactions/Switch.js.map +1 -1
  111. package/lib/screenplay/interactions/TakeScreenshot.d.ts +28 -50
  112. package/lib/screenplay/interactions/TakeScreenshot.d.ts.map +1 -0
  113. package/lib/screenplay/interactions/TakeScreenshot.js +32 -57
  114. package/lib/screenplay/interactions/TakeScreenshot.js.map +1 -1
  115. package/lib/screenplay/interactions/index.d.ts +2 -3
  116. package/lib/screenplay/interactions/index.d.ts.map +1 -0
  117. package/lib/screenplay/interactions/index.js +6 -4
  118. package/lib/screenplay/interactions/index.js.map +1 -1
  119. package/lib/screenplay/models/BrowserCapabilities.d.ts +24 -0
  120. package/lib/screenplay/models/BrowserCapabilities.d.ts.map +1 -0
  121. package/lib/screenplay/models/BrowserCapabilities.js.map +1 -0
  122. package/lib/screenplay/models/BrowsingSession.d.ts +69 -0
  123. package/lib/screenplay/models/BrowsingSession.d.ts.map +1 -0
  124. package/lib/screenplay/models/BrowsingSession.js +101 -0
  125. package/lib/screenplay/models/BrowsingSession.js.map +1 -0
  126. package/lib/screenplay/models/Cookie.d.ts +104 -64
  127. package/lib/screenplay/models/Cookie.d.ts.map +1 -0
  128. package/lib/screenplay/models/Cookie.js +110 -59
  129. package/lib/screenplay/models/Cookie.js.map +1 -1
  130. package/lib/screenplay/models/CookieData.d.ts +20 -58
  131. package/lib/screenplay/models/CookieData.d.ts.map +1 -0
  132. package/lib/{input → screenplay/models}/Key.d.ts +13 -9
  133. package/lib/screenplay/models/Key.d.ts.map +1 -0
  134. package/lib/{input → screenplay/models}/Key.js +16 -13
  135. package/lib/screenplay/models/Key.js.map +1 -0
  136. package/lib/screenplay/models/Locator.d.ts +29 -8
  137. package/lib/screenplay/models/Locator.d.ts.map +1 -0
  138. package/lib/screenplay/models/Locator.js +53 -7
  139. package/lib/screenplay/models/Locator.js.map +1 -1
  140. package/lib/screenplay/models/Page.d.ts +398 -36
  141. package/lib/screenplay/models/Page.d.ts.map +1 -0
  142. package/lib/screenplay/models/Page.js +209 -4
  143. package/lib/screenplay/models/Page.js.map +1 -1
  144. package/lib/screenplay/models/PageElement.d.ts +77 -5
  145. package/lib/screenplay/models/PageElement.d.ts.map +1 -0
  146. package/lib/screenplay/models/PageElement.js +29 -7
  147. package/lib/screenplay/models/PageElement.js.map +1 -1
  148. package/lib/screenplay/models/PageElements.d.ts +16 -3
  149. package/lib/screenplay/models/PageElements.d.ts.map +1 -0
  150. package/lib/screenplay/models/PageElements.js +21 -8
  151. package/lib/screenplay/models/PageElements.js.map +1 -1
  152. package/lib/screenplay/models/RootLocator.d.ts +25 -0
  153. package/lib/screenplay/models/RootLocator.d.ts.map +1 -0
  154. package/lib/screenplay/models/RootLocator.js +52 -0
  155. package/lib/screenplay/models/RootLocator.js.map +1 -0
  156. package/lib/screenplay/models/SelectOption.d.ts +25 -0
  157. package/lib/screenplay/models/SelectOption.d.ts.map +1 -0
  158. package/lib/screenplay/models/SelectOption.js +37 -0
  159. package/lib/screenplay/models/SelectOption.js.map +1 -0
  160. package/lib/screenplay/models/Switchable.d.ts +23 -0
  161. package/lib/screenplay/models/Switchable.d.ts.map +1 -0
  162. package/lib/screenplay/{interactions/WaitBuilder.js → models/Switchable.js} +1 -1
  163. package/lib/screenplay/models/Switchable.js.map +1 -0
  164. package/lib/screenplay/models/SwitchableOrigin.d.ts +18 -0
  165. package/lib/screenplay/models/SwitchableOrigin.d.ts.map +1 -0
  166. package/lib/screenplay/{interactions/EnterBuilder.js → models/SwitchableOrigin.js} +1 -1
  167. package/lib/screenplay/models/SwitchableOrigin.js.map +1 -0
  168. package/lib/screenplay/models/dialogs/AbsentModalDialog.d.ts +15 -0
  169. package/lib/screenplay/models/dialogs/AbsentModalDialog.d.ts.map +1 -0
  170. package/lib/screenplay/models/dialogs/AbsentModalDialog.js +24 -0
  171. package/lib/screenplay/models/dialogs/AbsentModalDialog.js.map +1 -0
  172. package/lib/screenplay/models/dialogs/AcceptedModalDialog.d.ts +17 -0
  173. package/lib/screenplay/models/dialogs/AcceptedModalDialog.d.ts.map +1 -0
  174. package/lib/screenplay/models/dialogs/AcceptedModalDialog.js +29 -0
  175. package/lib/screenplay/models/dialogs/AcceptedModalDialog.js.map +1 -0
  176. package/lib/screenplay/models/dialogs/DismissedModalDialog.d.ts +17 -0
  177. package/lib/screenplay/models/dialogs/DismissedModalDialog.d.ts.map +1 -0
  178. package/lib/screenplay/models/dialogs/DismissedModalDialog.js +29 -0
  179. package/lib/screenplay/models/dialogs/DismissedModalDialog.js.map +1 -0
  180. package/lib/screenplay/models/dialogs/ModalDialog.d.ts +168 -0
  181. package/lib/screenplay/models/dialogs/ModalDialog.d.ts.map +1 -0
  182. package/lib/screenplay/models/dialogs/ModalDialog.js +174 -0
  183. package/lib/screenplay/models/dialogs/ModalDialog.js.map +1 -0
  184. package/lib/screenplay/models/dialogs/ModalDialogHandler.d.ts +38 -0
  185. package/lib/screenplay/models/dialogs/ModalDialogHandler.d.ts.map +1 -0
  186. package/lib/screenplay/models/dialogs/ModalDialogHandler.js +30 -0
  187. package/lib/screenplay/models/dialogs/ModalDialogHandler.js.map +1 -0
  188. package/lib/screenplay/models/dialogs/index.d.ts +6 -0
  189. package/lib/screenplay/models/dialogs/index.d.ts.map +1 -0
  190. package/lib/screenplay/models/dialogs/index.js +22 -0
  191. package/lib/screenplay/models/dialogs/index.js.map +1 -0
  192. package/lib/screenplay/models/index.d.ts +9 -1
  193. package/lib/screenplay/models/index.d.ts.map +1 -0
  194. package/lib/screenplay/models/index.js +13 -2
  195. package/lib/screenplay/models/index.js.map +1 -1
  196. package/lib/screenplay/models/selectors/By.d.ts +38 -0
  197. package/lib/screenplay/models/selectors/By.d.ts.map +1 -0
  198. package/lib/screenplay/models/selectors/By.js +43 -0
  199. package/lib/screenplay/models/selectors/By.js.map +1 -1
  200. package/lib/screenplay/models/selectors/ByCss.d.ts +8 -0
  201. package/lib/screenplay/models/selectors/ByCss.d.ts.map +1 -0
  202. package/lib/screenplay/models/selectors/ByCss.js +7 -0
  203. package/lib/screenplay/models/selectors/ByCss.js.map +1 -1
  204. package/lib/screenplay/models/selectors/ByCssContainingText.d.ts +9 -0
  205. package/lib/screenplay/models/selectors/ByCssContainingText.d.ts.map +1 -0
  206. package/lib/screenplay/models/selectors/ByCssContainingText.js +8 -0
  207. package/lib/screenplay/models/selectors/ByCssContainingText.js.map +1 -1
  208. package/lib/screenplay/models/selectors/ByDeepCss.d.ts +14 -0
  209. package/lib/screenplay/models/selectors/ByDeepCss.d.ts.map +1 -0
  210. package/lib/screenplay/models/selectors/ByDeepCss.js +20 -0
  211. package/lib/screenplay/models/selectors/ByDeepCss.js.map +1 -0
  212. package/lib/screenplay/models/selectors/ById.d.ts +8 -0
  213. package/lib/screenplay/models/selectors/ById.d.ts.map +1 -0
  214. package/lib/screenplay/models/selectors/ById.js +7 -0
  215. package/lib/screenplay/models/selectors/ById.js.map +1 -1
  216. package/lib/screenplay/models/selectors/ByTagName.d.ts +8 -0
  217. package/lib/screenplay/models/selectors/ByTagName.d.ts.map +1 -0
  218. package/lib/screenplay/models/selectors/ByTagName.js +7 -0
  219. package/lib/screenplay/models/selectors/ByTagName.js.map +1 -1
  220. package/lib/screenplay/models/selectors/ByXPath.d.ts +8 -0
  221. package/lib/screenplay/models/selectors/ByXPath.d.ts.map +1 -0
  222. package/lib/screenplay/models/selectors/ByXPath.js +7 -0
  223. package/lib/screenplay/models/selectors/ByXPath.js.map +1 -1
  224. package/lib/screenplay/models/selectors/Selector.d.ts +6 -0
  225. package/lib/screenplay/models/selectors/Selector.d.ts.map +1 -0
  226. package/lib/screenplay/models/selectors/Selector.js +6 -1
  227. package/lib/screenplay/models/selectors/Selector.js.map +1 -1
  228. package/lib/screenplay/models/selectors/index.d.ts +2 -0
  229. package/lib/screenplay/models/selectors/index.d.ts.map +1 -0
  230. package/lib/screenplay/models/selectors/index.js +6 -1
  231. package/lib/screenplay/models/selectors/index.js.map +1 -1
  232. package/lib/screenplay/questions/Attribute.d.ts +115 -67
  233. package/lib/screenplay/questions/Attribute.d.ts.map +1 -0
  234. package/lib/screenplay/questions/Attribute.js +128 -74
  235. package/lib/screenplay/questions/Attribute.js.map +1 -1
  236. package/lib/screenplay/questions/CssClasses.d.ts +124 -79
  237. package/lib/screenplay/questions/CssClasses.d.ts.map +1 -0
  238. package/lib/screenplay/questions/CssClasses.js +132 -83
  239. package/lib/screenplay/questions/CssClasses.js.map +1 -1
  240. package/lib/screenplay/questions/LastScriptExecution.d.ts +42 -6
  241. package/lib/screenplay/questions/LastScriptExecution.d.ts.map +1 -0
  242. package/lib/screenplay/questions/LastScriptExecution.js +45 -7
  243. package/lib/screenplay/questions/LastScriptExecution.js.map +1 -1
  244. package/lib/screenplay/questions/Selected.d.ts +202 -171
  245. package/lib/screenplay/questions/Selected.d.ts.map +1 -0
  246. package/lib/screenplay/questions/Selected.js +225 -186
  247. package/lib/screenplay/questions/Selected.js.map +1 -1
  248. package/lib/screenplay/questions/Text.d.ts +101 -82
  249. package/lib/screenplay/questions/Text.d.ts.map +1 -0
  250. package/lib/screenplay/questions/Text.js +143 -92
  251. package/lib/screenplay/questions/Text.js.map +1 -1
  252. package/lib/screenplay/questions/Value.d.ts +77 -44
  253. package/lib/screenplay/questions/Value.d.ts.map +1 -0
  254. package/lib/screenplay/questions/Value.js +84 -47
  255. package/lib/screenplay/questions/Value.js.map +1 -1
  256. package/lib/screenplay/questions/index.d.ts +1 -0
  257. package/lib/screenplay/questions/index.d.ts.map +1 -0
  258. package/lib/screenplay/questions/index.js +5 -1
  259. package/lib/screenplay/questions/index.js.map +1 -1
  260. package/lib/scripts/index.d.ts +2 -0
  261. package/lib/scripts/index.d.ts.map +1 -0
  262. package/lib/{input → scripts}/index.js +6 -2
  263. package/lib/scripts/index.js.map +1 -0
  264. package/lib/scripts/isVisible.d.ts +2 -0
  265. package/lib/scripts/isVisible.d.ts.map +1 -0
  266. package/lib/scripts/isVisible.js +96 -0
  267. package/lib/scripts/isVisible.js.map +1 -0
  268. package/lib/stage/crew/index.d.ts +1 -0
  269. package/lib/stage/crew/index.d.ts.map +1 -0
  270. package/lib/stage/crew/index.js +5 -1
  271. package/lib/stage/crew/index.js.map +1 -1
  272. package/lib/stage/crew/photographer/Photographer.d.ts +126 -39
  273. package/lib/stage/crew/photographer/Photographer.d.ts.map +1 -0
  274. package/lib/stage/crew/photographer/Photographer.js +161 -42
  275. package/lib/stage/crew/photographer/Photographer.js.map +1 -1
  276. package/lib/stage/crew/photographer/index.d.ts +1 -0
  277. package/lib/stage/crew/photographer/index.d.ts.map +1 -0
  278. package/lib/stage/crew/photographer/index.js +5 -1
  279. package/lib/stage/crew/photographer/index.js.map +1 -1
  280. package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.d.ts +13 -12
  281. package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.d.ts.map +1 -0
  282. package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.js +22 -33
  283. package/lib/stage/crew/photographer/strategies/PhotoTakingStrategy.js.map +1 -1
  284. package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.d.ts +8 -8
  285. package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.d.ts.map +1 -0
  286. package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.js +7 -8
  287. package/lib/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.js.map +1 -1
  288. package/lib/stage/crew/photographer/strategies/TakePhotosOfFailures.d.ts +8 -7
  289. package/lib/stage/crew/photographer/strategies/TakePhotosOfFailures.d.ts.map +1 -0
  290. package/lib/stage/crew/photographer/strategies/TakePhotosOfFailures.js +7 -7
  291. package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.d.ts +8 -8
  292. package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.d.ts.map +1 -0
  293. package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.js +7 -8
  294. package/lib/stage/crew/photographer/strategies/TakePhotosOfInteractions.js.map +1 -1
  295. package/lib/stage/crew/photographer/strategies/index.d.ts +1 -0
  296. package/lib/stage/crew/photographer/strategies/index.d.ts.map +1 -0
  297. package/lib/stage/crew/photographer/strategies/index.js +5 -1
  298. package/lib/stage/crew/photographer/strategies/index.js.map +1 -1
  299. package/lib/stage/index.d.ts +1 -0
  300. package/lib/stage/index.d.ts.map +1 -0
  301. package/lib/stage/index.js +5 -1
  302. package/lib/stage/index.js.map +1 -1
  303. package/package.json +20 -43
  304. package/src/errors/BrowserWindowClosedError.ts +17 -0
  305. package/src/errors/CookieMissingError.ts +10 -0
  306. package/src/errors/ModalDialogObstructsScreenshotError.ts +17 -0
  307. package/src/errors/index.ts +2 -0
  308. package/src/expectations/index.ts +0 -1
  309. package/src/expectations/isActive.ts +23 -12
  310. package/src/expectations/isClickable.ts +22 -21
  311. package/src/expectations/isEnabled.ts +23 -9
  312. package/src/expectations/isSelected.ts +20 -10
  313. package/src/expectations/isVisible.ts +23 -9
  314. package/src/index.ts +0 -1
  315. package/src/screenplay/abilities/BrowseTheWeb.ts +95 -87
  316. package/src/screenplay/abilities/index.ts +0 -1
  317. package/src/screenplay/interactions/Clear.ts +75 -63
  318. package/src/screenplay/interactions/Click.ts +43 -54
  319. package/src/screenplay/interactions/DoubleClick.ts +66 -71
  320. package/src/screenplay/interactions/Enter.ts +41 -53
  321. package/src/screenplay/interactions/ExecuteScript.ts +207 -220
  322. package/src/screenplay/interactions/Hover.ts +42 -54
  323. package/src/screenplay/interactions/Navigate.ts +129 -156
  324. package/src/screenplay/interactions/PageElementInteraction.ts +14 -34
  325. package/src/screenplay/interactions/Press.ts +78 -69
  326. package/src/screenplay/interactions/RightClick.ts +61 -69
  327. package/src/screenplay/interactions/Scroll.ts +48 -71
  328. package/src/screenplay/interactions/Select.ts +229 -269
  329. package/src/screenplay/interactions/Switch.ts +123 -179
  330. package/src/screenplay/interactions/TakeScreenshot.ts +31 -57
  331. package/src/screenplay/interactions/index.ts +1 -3
  332. package/src/screenplay/models/BrowserCapabilities.ts +26 -0
  333. package/src/screenplay/models/BrowsingSession.ts +115 -0
  334. package/src/screenplay/models/Cookie.ts +115 -73
  335. package/src/screenplay/models/CookieData.ts +20 -58
  336. package/src/{input → screenplay/models}/Key.ts +12 -9
  337. package/src/screenplay/models/Locator.ts +43 -9
  338. package/src/screenplay/models/Page.ts +438 -37
  339. package/src/screenplay/models/PageElement.ts +92 -12
  340. package/src/screenplay/models/PageElements.ts +23 -9
  341. package/src/screenplay/models/RootLocator.ts +30 -0
  342. package/src/screenplay/models/SelectOption.ts +38 -0
  343. package/src/screenplay/models/Switchable.ts +24 -0
  344. package/src/screenplay/models/SwitchableOrigin.ts +18 -0
  345. package/src/screenplay/models/dialogs/AbsentModalDialog.ts +22 -0
  346. package/src/screenplay/models/dialogs/AcceptedModalDialog.ts +27 -0
  347. package/src/screenplay/models/dialogs/DismissedModalDialog.ts +27 -0
  348. package/src/screenplay/models/dialogs/ModalDialog.ts +200 -0
  349. package/src/screenplay/models/dialogs/ModalDialogHandler.ts +50 -0
  350. package/src/screenplay/models/dialogs/index.ts +5 -0
  351. package/src/screenplay/models/index.ts +8 -1
  352. package/src/screenplay/models/selectors/By.ts +45 -0
  353. package/src/screenplay/models/selectors/ByCss.ts +7 -0
  354. package/src/screenplay/models/selectors/ByCssContainingText.ts +8 -0
  355. package/src/screenplay/models/selectors/ByDeepCss.ts +15 -0
  356. package/src/screenplay/models/selectors/ById.ts +7 -0
  357. package/src/screenplay/models/selectors/ByTagName.ts +7 -0
  358. package/src/screenplay/models/selectors/ByXPath.ts +7 -0
  359. package/src/screenplay/models/selectors/Selector.ts +6 -1
  360. package/src/screenplay/models/selectors/index.ts +1 -0
  361. package/src/screenplay/questions/Attribute.ts +137 -76
  362. package/src/screenplay/questions/CssClasses.ts +135 -83
  363. package/src/screenplay/questions/LastScriptExecution.ts +45 -8
  364. package/src/screenplay/questions/Selected.ts +237 -191
  365. package/src/screenplay/questions/Text.ts +161 -96
  366. package/src/screenplay/questions/Value.ts +88 -48
  367. package/src/scripts/index.ts +1 -0
  368. package/src/scripts/isVisible.ts +113 -0
  369. package/src/stage/crew/photographer/Photographer.ts +142 -41
  370. package/src/stage/crew/photographer/strategies/PhotoTakingStrategy.ts +27 -42
  371. package/src/stage/crew/photographer/strategies/TakePhotosBeforeAndAfterInteractions.ts +7 -8
  372. package/src/stage/crew/photographer/strategies/TakePhotosOfFailures.ts +7 -7
  373. package/src/stage/crew/photographer/strategies/TakePhotosOfInteractions.ts +7 -8
  374. package/tsconfig.build.json +14 -0
  375. package/lib/expectations/ElementExpectation.d.ts +0 -83
  376. package/lib/expectations/ElementExpectation.js +0 -102
  377. package/lib/expectations/ElementExpectation.js.map +0 -1
  378. package/lib/input/Key.js.map +0 -1
  379. package/lib/input/index.d.ts +0 -1
  380. package/lib/input/index.js.map +0 -1
  381. package/lib/screenplay/abilities/BrowserCapabilities.d.ts +0 -5
  382. package/lib/screenplay/abilities/BrowserCapabilities.js.map +0 -1
  383. package/lib/screenplay/interactions/EnterBuilder.d.ts +0 -25
  384. package/lib/screenplay/interactions/EnterBuilder.js.map +0 -1
  385. package/lib/screenplay/interactions/PressBuilder.d.ts +0 -26
  386. package/lib/screenplay/interactions/PressBuilder.js +0 -3
  387. package/lib/screenplay/interactions/PressBuilder.js.map +0 -1
  388. package/lib/screenplay/interactions/SelectBuilder.d.ts +0 -33
  389. package/lib/screenplay/interactions/SelectBuilder.js +0 -3
  390. package/lib/screenplay/interactions/SelectBuilder.js.map +0 -1
  391. package/lib/screenplay/interactions/Wait.d.ts +0 -143
  392. package/lib/screenplay/interactions/Wait.js +0 -238
  393. package/lib/screenplay/interactions/Wait.js.map +0 -1
  394. package/lib/screenplay/interactions/WaitBuilder.d.ts +0 -32
  395. package/lib/screenplay/interactions/WaitBuilder.js.map +0 -1
  396. package/lib/screenplay/models/ModalDialog.d.ts +0 -9
  397. package/lib/screenplay/models/ModalDialog.js +0 -14
  398. package/lib/screenplay/models/ModalDialog.js.map +0 -1
  399. package/lib/screenplay/questions/ElementQuestion.d.ts +0 -33
  400. package/lib/screenplay/questions/ElementQuestion.js +0 -53
  401. package/lib/screenplay/questions/ElementQuestion.js.map +0 -1
  402. package/src/expectations/ElementExpectation.ts +0 -108
  403. package/src/input/index.ts +0 -1
  404. package/src/screenplay/abilities/BrowserCapabilities.ts +0 -5
  405. package/src/screenplay/interactions/EnterBuilder.ts +0 -28
  406. package/src/screenplay/interactions/PressBuilder.ts +0 -29
  407. package/src/screenplay/interactions/SelectBuilder.ts +0 -36
  408. package/src/screenplay/interactions/Wait.ts +0 -260
  409. package/src/screenplay/interactions/WaitBuilder.ts +0 -34
  410. package/src/screenplay/models/ModalDialog.ts +0 -19
  411. package/src/screenplay/questions/ElementQuestion.ts +0 -58
  412. package/tsconfig.eslint.json +0 -10
  413. /package/lib/screenplay/{abilities → models}/BrowserCapabilities.js +0 -0
@@ -1,225 +1,169 @@
1
- import { Activity, Answerable, AnswersQuestions, Interaction, PerformsActivities, Task, UsesAbilities } from '@serenity-js/core';
1
+ import { Activity, Actor, Answerable, AnswersQuestions, Interaction, Task, UsesAbilities } from '@serenity-js/core';
2
2
 
3
- import { BrowseTheWeb } from '../abilities';
4
- import { PageElement } from '../models';
3
+ import { Switchable } from '../models';
5
4
 
6
5
  /**
7
- * @desc
8
- * Instructs the {@link @serenity-js/core/lib/screenplay/actor~Actor}
9
- * to switch to a different [frame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/frame),
10
- * [inline frame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe),
11
- * or browser window/tab.
12
- *
13
- * @example <caption>Lean Page Object describing a login form, embedded in an iframe</caption>
14
- *
15
- * import { Target } from '@serenity-js/protractor';
16
- * import { by } from 'protractor';
17
- *
18
- * class LoginForm {
19
- * static iframe = Target.the('login form').located(by.tagName('iframe'));
20
- * static usernameField = Target.the('username field').located(by.css('[data-test="username"]'));
21
- * static passwordField = Target.the('password field').located(by.css('[data-test="password"]'));
22
- * static submitButton = Target.the('submit button').located(by.css(`button[type='submit']`));
23
- * }
24
- *
25
- * @example <caption>Switch to an iframe and back</caption>
26
- *
27
- * import { actorCalled } from '@serenity-js/core';
28
- * import { BrowseTheWeb, Switch, Enter, Click } from '@serenity-js/protractor';
29
- * import { protractor } from 'protractor';
30
- *
31
- * actorCalled('Francesca')
32
- * .whoCan(BrowseTheWeb.using(protractor.browser))
33
- * .attemptsTo(
34
- * Switch.toFrame(LoginForm.iframe),
35
- *
36
- * Enter.theValue('francesca@example.org').into(LoginForm.usernameField),
37
- * Enter.theValue('correct-horse-battery-staple').into(LoginForm.passwordField),
38
- * Click.on(LoginForm.submitButton),
39
- *
40
- * Switch.toParentFrame(),
41
- * );
42
- *
43
- * @example <caption>Perform activities in the context of an iframe</caption>
6
+ * Instructs an {@apilink Actor|actor} who has the {@apilink Ability|ability} to {@apilink BrowseTheWeb}
7
+ * to switch the context for future activities to a {@apilink Switchable}, such as a {@apilink Page} or a {@apilink PageElement}.
44
8
  *
45
- * import { actorCalled } from '@serenity-js/core';
46
- * import { BrowseTheWeb, Switch, Enter, Click } from '@serenity-js/protractor';
47
- * import { protractor } from 'protractor';
9
+ * Please note that when the {@apilink PageElement} implementing {@apilink Switchable} represents an {@apilink iframe},
10
+ * using {@apilink Switch} will result in switching the top-level browsing context to that {@apilink iframe}.
48
11
  *
49
- * actorCalled('Francesca')
50
- * .whoCan(BrowseTheWeb.using(protractor.browser))
51
- * .attemptsTo(
52
- * Switch.toFrame(LoginForm.iframe).and(
53
- * Enter.theValue('francesca@example.org').into(LoginForm.usernameField),
54
- * Enter.theValue('correct-horse-battery-staple').into(LoginForm.passwordField),
55
- * Click.on(LoginForm.submitButton),
56
- * ),
57
- * // Note that Switch.toParentFrame() is invoked automatically
58
- * );
12
+ * When the {@apilink PageElement} represents any other [HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement),
13
+ * using {@apilink Switch} sets [`HTMLElement#focus`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus)
14
+ * on the specified element. Assuming it can be focused.
59
15
  *
60
- * @example <caption>Switch to a new window/tab and back</caption>
16
+ * **Note:** The focused element is the element which will receive keyboard {@apilink Press} events by default.
61
17
  *
62
- * import { actorCalled } from '@serenity-js/core';
63
- * import { BrowseTheWeb, Switch, Close } from '@serenity-js/protractor';
64
- * import { protractor } from 'protractor';
18
+ * ## Perform activities in the context of an iframe
65
19
  *
66
- * actorCalled('Francesca')
67
- * .whoCan(BrowseTheWeb.using(protractor.browser))
68
- * .attemptsTo(
69
- * Switch.toNewWindow(), // or: Switch.toWindow(...)
20
+ * ```ts
21
+ * import { actorCalled } from '@serenity-js/core'
22
+ * import { By, Click, Enter, PageElement, Switch } from '@serenity-js/web'
70
23
  *
71
- * // perform some activities in the context of the new window
24
+ * // Lean Page Object describing a login form, embedded in an iframe
25
+ * class LoginForm {
26
+ * static iframe = () =>
27
+ * PageElement.located(By.css('iframe'))
28
+ * .describedAs('login form')
72
29
  *
73
- * Close.currentWindow(),
30
+ * static usernameField = () =>
31
+ * PageElement.located(By.css('[data-testid="username"]'))
32
+ * .describedAs('username field')
74
33
  *
75
- * Switch.toOriginalWindow(),
76
- * );
34
+ * static passwordField = () =>
35
+ * PageElement.located(By.css('[data-testid="password"]'))
36
+ * .describedAs('password field')
77
37
  *
78
- * @example <caption>Perform activities in the context of a different window/tab</caption>
79
- *
80
- * import { actorCalled } from '@serenity-js/core';
81
- * import { BrowseTheWeb, Switch, Close } from '@serenity-js/protractor';
82
- * import { protractor } from 'protractor';
83
- *
84
- * actorCalled('Francesca')
85
- * .whoCan(BrowseTheWeb.using(protractor.browser))
86
- * .attemptsTo(
87
- * Switch.toNewWindow().and(
88
- * // perform some activities in the context of the new window
89
- *
90
- * Close.currentWindow()
91
- * ),
92
- *
93
- * // Note that Switch.toOriginalWindow() is invoked automatically
94
- * );
38
+ * static submitButton = () =>
39
+ * PageElement.located(By.css('button[type="submit"]'))
40
+ * .describedAs('submit button')
41
+ * }
95
42
  *
96
- * @see {@link Close}
97
- * @see {@link BrowseTheWeb}
43
+ * await actorCalled('Francesca')
44
+ * .attemptsTo(
45
+ * Switch.to(LoginForm.iframe).and(
46
+ * Enter.theValue('francesca@example.org').into(LoginForm.usernameField()),
47
+ * Enter.theValue('correct-horse-battery-staple').into(LoginForm.passwordField()),
48
+ * Click.on(LoginForm.submitButton()),
49
+ * )
50
+ * )
51
+ * ```
52
+ *
53
+ * ## Perform activities in the context of another page
54
+ *
55
+ * ```ts
56
+ * import { actorCalled } from '@serenity-js/core'
57
+ * import { Click, Enter, Switch } from '@serenity-js/web'
58
+ *
59
+ * await actorCalled('Francesca')
60
+ * .whoCan(BrowseTheWebWithWebdriverIO.using(browser))
61
+ * .attemptsTo(
62
+ * Switch.to(Page.whichName(startsWith('popup'))).and(
63
+ * // perform some activities in the context of the new window
64
+ *
65
+ * // optionally, close the browser tab
66
+ * Page.current().close(),
67
+ * ),
68
+ *
69
+ * // Note that switching back to the original page happens automatically
70
+ * // after the last activity from the list finishes
71
+ * )
72
+ * ```
73
+ *
74
+ * ## Perform activities in the context of a focused page element
75
+ *
76
+ * ```ts
77
+ * import { Ensure, equals } from '@serenity-js/assertions'
78
+ * import { actorCalled } from '@serenity-js/core'
79
+ * import { Key, PageElement, Press, Switch, Value } from '@serenity-js/web'
80
+ *
81
+ * const inputField = () =>
82
+ * PageElement.located(By.css('input'));
83
+ *
84
+ * await actorCalled('Francesca')
85
+ * .whoCan(BrowseTheWebWithWebdriverIO.using(browser))
86
+ * .attemptsTo(
87
+ * Switch.to(inputField()).and(
88
+ * Press.the('h', 'e', 'l', 'l', 'o'),
89
+ * Press.the(Key.Tab),
90
+ * ),
91
+ * Ensure.that(Value.of(inputField()), equals('hello'))
92
+ * )
93
+ * ```
94
+ *
95
+ * ## Learn more
96
+ *
97
+ * - {@apilink BrowseTheWeb}
98
+ * - {@apilink Switchable}
99
+ * - {@apilink SwitchableOrigin}
100
+ *
101
+ * @group Activities
98
102
  */
99
- export class Switch {
103
+ export class Switch extends Interaction {
100
104
 
101
105
  /**
102
- * @desc
103
- * Switches the current [browsing context](https://w3c.github.io/webdriver/#dfn-current-browsing-context)
104
- * for future commands to a [frame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/frame)
105
- * or an [inline frame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)
106
- * identified by its name, index or `Question<ElementFinder>`.
107
- *
108
- * @param {Answerable<ElementFinder | number | string>} targetOrIndex
106
+ * Instructs the {@apilink Actor}
107
+ * to switch the context for future activities to a {@apilink Switchable},
108
+ * such as a {@apilink Page} or a {@apilink PageElement}.
109
109
  *
110
- * @returns {SwitchToFrame}
111
- *
112
- * @see {@link Switch.toParentFrame}
113
- * @see {@link Switch.toDefaultContent}
114
- * @see {@link Target}
110
+ * @param switchable
115
111
  */
116
- static toFrame(targetOrIndex: Answerable<PageElement | number | string>): SwitchToFrame {
117
- return new SwitchToFrame(targetOrIndex);
112
+ static to(switchable: Answerable<Switchable>): Switch {
113
+ return new Switch(switchable);
118
114
  }
119
115
 
120
- /**
121
- * @desc
122
- * Sets the current [browsing context](https://w3c.github.io/webdriver/#dfn-current-browsing-context)
123
- * for future commands to the parent of the current browsing context,
124
- * i.e. an `iframe` in which the current `iframe` is nested.
125
- *
126
- * If the current context is the top-level browsing context, the context remains unchanged.
127
- *
128
- * @returns {@serenity-js/core/lib/screenplay~Interaction}
129
- *
130
- * @see {@link Switch.toFrame}
131
- * @see https://w3c.github.io/webdriver/#switch-to-parent-frame
132
- * @see https://w3c.github.io/webdriver/#dfn-current-browsing-context
133
- */
134
- static toParentFrame(): Interaction {
135
- return new SwitchToParentFrame();
116
+ protected constructor(private readonly switchable: Answerable<Switchable>) {
117
+ super(`#actor switches to ${ switchable }`);
136
118
  }
137
119
 
138
120
  /**
139
- * @desc
140
- * Switches the current [browsing context](https://w3c.github.io/webdriver/#dfn-current-browsing-context)
141
- * for future commands to the first frame on the page, or the main document
142
- * when a page contains [`iframe`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)s.
143
- *
144
- * @returns {@serenity-js/core/lib/screenplay~Interaction}
121
+ * Instructs the {@apilink Actor}
122
+ * to switch the context for future activities to a {@apilink Switchable},
123
+ * such as a {@apilink Page} or a {@apilink PageElement},
124
+ * perform a sequence of `activities`, and then switch the context back.
145
125
  *
146
- * @see {@link Switch.toFrame}
126
+ * @param activities
127
+ * A sequence of activities to perform
147
128
  */
148
- static toDefaultContent(): Interaction {
149
- return new SwitchToDefaultContent();
150
- }
151
- }
152
-
153
- /**
154
- * @package
155
- */
156
- class SwitchToFrame extends Interaction {
157
- constructor(private readonly targetOrIndex: Answerable<PageElement | number | string>) {
158
- super();
159
- }
160
-
161
129
  and(...activities: Activity[]): Task {
162
- return new SwitchToFrameAndPerformActivities(this.targetOrIndex, activities);
130
+ return new SwitchAndPerformActivities(this.switchable, activities);
163
131
  }
164
132
 
165
- performAs(actor: UsesAbilities & AnswersQuestions): PromiseLike<void> {
166
- return actor.answer(this.targetOrIndex)
167
- .then((targetOrIndex: PageElement | number | string) => {
168
- return BrowseTheWeb.as(actor).switchToFrame(targetOrIndex);
169
- });
170
- }
133
+ /**
134
+ * @inheritDoc
135
+ */
136
+ async performAs(actor: UsesAbilities & AnswersQuestions): Promise<void> {
137
+ const switchable = await actor.answer(this.switchable);
171
138
 
172
- toString(): string {
173
- return `#actor switches to frame: ${ this.targetOrIndex }`;
139
+ await switchable.switchTo();
174
140
  }
175
141
  }
176
142
 
177
143
  /**
178
144
  * @package
179
145
  */
180
- class SwitchToFrameAndPerformActivities extends Task {
146
+ class SwitchAndPerformActivities extends Task {
181
147
  constructor(
182
- private readonly targetOrIndex: Answerable<PageElement | number | string>,
148
+ private readonly switchable: Answerable<Switchable>,
183
149
  private readonly activities: Activity[]
184
150
  ) {
185
- super();
151
+ super(`#actor switches to ${ switchable }`);
186
152
  }
187
153
 
188
- performAs(actor: PerformsActivities): PromiseLike<void> {
189
- return actor.attemptsTo(
190
- new SwitchToFrame(this.targetOrIndex),
191
- ...this.activities,
192
- new SwitchToParentFrame()
193
- )
194
- }
154
+ /**
155
+ * @inheritDoc
156
+ */
157
+ async performAs(actor: Actor): Promise<void> {
195
158
 
196
- toString(): string {
197
- return `#actor switches to frame: ${ this.targetOrIndex }`;
198
- }
199
- }
159
+ const switchable = await actor.answer(this.switchable);
200
160
 
201
- /**
202
- * @package
203
- */
204
- class SwitchToParentFrame extends Interaction {
205
- performAs(actor: UsesAbilities & AnswersQuestions): PromiseLike<void> {
206
- return BrowseTheWeb.as(actor).switchToParentFrame();
207
- }
208
-
209
- toString(): string {
210
- return `#actor switches to parent frame`;
211
- }
212
- }
161
+ const origin = await switchable.switchTo();
213
162
 
214
- /**
215
- * @package
216
- */
217
- class SwitchToDefaultContent extends Interaction {
218
- performAs(actor: UsesAbilities & AnswersQuestions): PromiseLike<void> {
219
- return BrowseTheWeb.as(actor).switchToDefaultContent();
220
- }
163
+ await actor.attemptsTo(
164
+ ...this.activities,
165
+ )
221
166
 
222
- toString(): string {
223
- return `#actor switches to default content`;
167
+ await origin.switchBack();
224
168
  }
225
169
  }
@@ -1,74 +1,58 @@
1
- import { Answerable, AnswersQuestions, CollectsArtifacts, Interaction, UsesAbilities } from '@serenity-js/core';
2
- import { formatted } from '@serenity-js/core/lib/io';
1
+ import { Answerable, AnswersQuestions, CollectsArtifacts, d, Interaction, UsesAbilities } from '@serenity-js/core';
3
2
  import { Name, Photo } from '@serenity-js/core/lib/model';
4
3
 
5
4
  import { BrowseTheWeb } from '../abilities';
6
5
 
7
6
  /**
8
- * @desc
9
- * Instructs the {@link @serenity-js/core/lib/screenplay/actor~Actor} to
10
- * take a screenshot and emit an {@link @serenity-js/core/lib/model~Artifact},
11
- * which can then be persisted by {@link @serenity-js/core/lib/stage/crew/artifact-archiver~ArtifactArchiver}
12
- * and reported by [Serenity BDD reporter](/modules/serenity-bdd).
7
+ * Instructs an {@apilink Actor|actor} who has the {@apilink Ability|ability} to {@apilink BrowseTheWeb}
8
+ * to take a screenshot and emit an {@apilink Artifact},
9
+ * which can then be persisted by {@apilink ArtifactArchiver}
10
+ * and reported by [Serenity BDD reporter](/api/serenity-bdd).
13
11
  *
14
- * @example <caption>Clicking on an element</caption>
15
- * import { actorCalled } from '@serenity-js/core';
16
- * import { BrowseTheWeb, Navigate, TakeScreenshot } from '@serenity-js/protractor';
17
- * import { protractor } from 'protractor';
12
+ * #### Taking a screenshot
18
13
  *
19
- * actorCalled('Tania')
20
- * .whoCan(BrowseTheWeb.using(protractor.browser))
21
- * .attemptsTo(
22
- * Navigate.to('/app'),
23
- * TakeScreenshot.of('my app'),
24
- * );
14
+ * ```ts
15
+ * import { actorCalled } from '@serenity-js/core';
16
+ * import { Navigate, TakeScreenshot } from '@serenity-js/protractor';
25
17
  *
26
- * @see {@link BrowseTheWeb}
27
- * @see {@link @serenity-js/core/lib/screenplay/actor~CollectsArtifacts}
28
- * @see {@link @serenity-js/core/lib/model~Artifact}
29
- * @see {@link @serenity-js/core/lib/stage/crew/artifact-archiver~ArtifactArchiver}
18
+ * await actorCalled('Tania')
19
+ * .attemptsTo(
20
+ * Navigate.to('/app'),
21
+ * TakeScreenshot.of('my app'),
22
+ * )
23
+ * ```
30
24
  *
31
- * @extends {@serenity-js/core/lib/screenplay~Interaction}
25
+ * ## Learn more
26
+ *
27
+ * - {@apilink BrowseTheWeb}
28
+ * - {@apilink CollectsArtifacts}
29
+ * - {@apilink Artifact}
30
+ * - {@apilink ArtifactArchiver}
31
+ *
32
+ * @group Activities
32
33
  */
33
34
  export class TakeScreenshot extends Interaction {
34
35
 
35
36
  /**
36
- * @desc
37
- * Instantiates this {@link @serenity-js/core/lib/screenplay~Interaction}.
37
+ * Instantiates this {@apilink Interaction}.
38
38
  *
39
- * @param {Answerable<string>} name
40
- * The name to associate the screenshot with
41
- *
42
- * @returns {@serenity-js/core/lib/screenplay~Interaction}
39
+ * @param name
40
+ * The name to give the emitted {@apilink Artifact}
43
41
  */
44
42
  static of(name: Answerable<string>): Interaction {
45
43
  return new TakeScreenshot(name);
46
44
  }
47
45
 
48
- /**
49
- * @param {Answerable<string>} name
50
- * The name to associate the screenshot with
51
- */
52
- constructor(private readonly name: Answerable<string>) {
53
- super();
46
+ protected constructor(private readonly name: Answerable<string>) {
47
+ super(d`#actor takes a screenshot of ${ name }`);
54
48
  }
55
49
 
56
50
  /**
57
- * @desc
58
- * Makes the provided {@link @serenity-js/core/lib/screenplay/actor~Actor}
59
- * perform this {@link @serenity-js/core/lib/screenplay~Interaction}.
60
- *
61
- * @param {UsesAbilities & AnswersQuestions} actor
62
- * An {@link @serenity-js/core/lib/screenplay/actor~Actor} to perform this {@link @serenity-js/core/lib/screenplay~Interaction}
63
- *
64
- * @returns {PromiseLike<void>}
65
- *
66
- * @see {@link @serenity-js/core/lib/screenplay/actor~Actor}
67
- * @see {@link @serenity-js/core/lib/screenplay/actor~UsesAbilities}
68
- * @see {@link @serenity-js/core/lib/screenplay/actor~AnswersQuestions}
51
+ * @inheritDoc
69
52
  */
70
53
  async performAs(actor: UsesAbilities & AnswersQuestions & CollectsArtifacts): Promise<void> {
71
- const screenshot = await BrowseTheWeb.as(actor).takeScreenshot();
54
+ const page = await BrowseTheWeb.as(actor).currentPage();
55
+ const screenshot = await page.takeScreenshot();
72
56
  const name = await actor.answer(this.name);
73
57
 
74
58
  actor.collect(
@@ -76,14 +60,4 @@ export class TakeScreenshot extends Interaction {
76
60
  new Name(name),
77
61
  );
78
62
  }
79
-
80
- /**
81
- * @desc
82
- * Generates a description to be used when reporting this {@link @serenity-js/core/lib/screenplay~Activity}.
83
- *
84
- * @returns {string}
85
- */
86
- toString(): string {
87
- return formatted `#actor takes a screenshot of ${this.name}`;
88
- }
89
63
  }
@@ -5,12 +5,10 @@ export * from './Enter';
5
5
  export * from './ExecuteScript';
6
6
  export * from './Hover';
7
7
  export * from './Navigate';
8
+ export * from './PageElementInteraction';
8
9
  export * from './Press';
9
- export * from './PressBuilder';
10
10
  export * from './RightClick';
11
11
  export * from './Scroll';
12
12
  export * from './Select';
13
- export * from './SelectBuilder';
14
13
  export * from './Switch';
15
14
  export * from './TakeScreenshot';
16
- export * from './Wait';
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Basic meta-data about the browser used in the test
3
+ *
4
+ * ## Learn more
5
+ *
6
+ * - {@apilink BrowseTheWeb.browserCapabilities}
7
+ *
8
+ * @group Models
9
+ */
10
+ export interface BrowserCapabilities {
11
+
12
+ /**
13
+ * Name of the operating system platform the test is executed on, like `darwin`, `linux` or `windows`.
14
+ */
15
+ platformName?: string;
16
+
17
+ /**
18
+ * Name of the Web browser the test is executed in, like `chrome`, `firefox` or `safari`.
19
+ */
20
+ browserName?: string;
21
+
22
+ /**
23
+ * Version number of the browser the test is executed in.
24
+ */
25
+ browserVersion?: string;
26
+ }
@@ -0,0 +1,115 @@
1
+ import { CorrelationId } from '@serenity-js/core/lib/model';
2
+
3
+ import { Page } from './Page';
4
+
5
+ /**
6
+ * Represents the pages open in the current browsing context.
7
+ *
8
+ * You'll need to use this class directly only if you're planning to integrate Serenity/JS
9
+ * with a new Web integration tool.
10
+ *
11
+ * @group Models
12
+ */
13
+ export abstract class BrowsingSession<Page_Type extends Page> {
14
+ protected currentBrowserPage: Page_Type;
15
+ protected readonly pages: Map<CorrelationId, Page_Type> = new Map<CorrelationId, Page_Type>();
16
+
17
+ async closePagesOtherThan(pageOfInterest: Page_Type): Promise<void> {
18
+ for (const page of await this.allPages()) {
19
+ if (! page.id.equals(pageOfInterest.id)) {
20
+ await page.close();
21
+ this.pages.delete(page.id);
22
+ }
23
+ }
24
+
25
+ await this.changeCurrentPageTo(pageOfInterest);
26
+ }
27
+
28
+ /**
29
+ * Opens a new browser page and associates it with a {@apilink Page} object.
30
+ */
31
+ protected abstract registerCurrentPage(): Promise<Page_Type>;
32
+
33
+ /**
34
+ * Returns a {@apilink Page} representing the currently active top-level browsing context.
35
+ */
36
+ async currentPage(): Promise<Page_Type> {
37
+ if (! this.currentBrowserPage || ! await this.currentBrowserPage.isPresent()) {
38
+ this.currentBrowserPage = await this.registerCurrentPage();
39
+ }
40
+
41
+ return this.currentBrowserPage;
42
+ }
43
+
44
+ /**
45
+ * Registers specified {@apilink Page|pages} to be managed by this {@apilink BrowsingSession}.
46
+ *
47
+ * @param pages
48
+ */
49
+ register(...pages: Page_Type[]): void {
50
+ for(const page of pages) {
51
+ this.pages.set(page.id, page);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Informs this {@apilink BrowsingSession} that it should no longer manage {@apilink Page|pages}
57
+ * identified by the given `pageIds`.
58
+ *
59
+ * @param pageIds
60
+ */
61
+ deregister(...pageIds: CorrelationId[]): void {
62
+ for(const pageId of pageIds) {
63
+ this.pages.delete(pageId);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Returns a {@apilink Page|pages} representing all the available
69
+ * top-level browsing context, e.g. all the open browser tabs.
70
+ */
71
+ async allPages(): Promise<Array<Page_Type>> {
72
+ return Array.from(this.pages.values()) as Page_Type[];
73
+ }
74
+
75
+ /**
76
+ * Returns the ids of any {@apilink Page|pages} this {@apilink BrowsingSession} is aware of.
77
+ */
78
+ registeredPageIds(): Array<CorrelationId> {
79
+ return Array.from(this.pages.keys());
80
+ }
81
+
82
+ /**
83
+ * Informs the {@apilink BrowsingSession} that the "current page" has changed to `page`.
84
+ *
85
+ * Please note that different Web integration tools have a different definition of what a "current page" is.
86
+ * For example, Selenium or WebdriverIO use a single "focused" window that a developer
87
+ * needs to explicitly "switch to" in their tests in order to interact with it.
88
+ * This is similar to how a regular user would interact with Web pages;
89
+ * switching from one tab to another, but not interacting with more than one
90
+ * window/tab simultaneously.
91
+ *
92
+ * Playwright and Puppeteer, on the other hand, don't have a concept of the "current" page at all, since they
93
+ * allow the developer to interact with multiple open tabs/windows at the same time.
94
+ *
95
+ * Web integration-specific implementations of this class should override this method to define
96
+ * how the concept of the "current page" should be interpreted by Serenity/JS.
97
+ *
98
+ * @param page
99
+ */
100
+ async changeCurrentPageTo(page: Page_Type): Promise<void> {
101
+ this.currentBrowserPage = page;
102
+ }
103
+
104
+ /**
105
+ * Closes all the pages available in this browsing context
106
+ */
107
+ async closeAllPages(): Promise<void> {
108
+ for (const page of this.pages.values()) {
109
+ await page.close();
110
+ }
111
+
112
+ this.pages.clear();
113
+ this.currentBrowserPage = undefined;
114
+ }
115
+ }