@itmetsam/samurai-framework 0.9.0 → 0.12.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 (331) hide show
  1. package/README.md +4 -5
  2. package/dist/assert/assertion-error.d.ts +1 -1
  3. package/dist/assert/expect.d.ts +5 -50
  4. package/dist/assert/expect.js +5 -182
  5. package/dist/assert/locator-assertions.d.ts +22 -0
  6. package/dist/assert/locator-assertions.js +61 -0
  7. package/dist/assert/pending-assertions.d.ts +7 -0
  8. package/dist/assert/pending-assertions.js +40 -0
  9. package/dist/assert/text-match.d.ts +4 -0
  10. package/dist/assert/text-match.js +11 -0
  11. package/dist/assert/value-assertions.d.ts +23 -0
  12. package/dist/assert/value-assertions.js +82 -0
  13. package/dist/browser/browser-context.d.ts +0 -1
  14. package/dist/browser/browser-context.js +13 -5
  15. package/dist/browser/browser-finder.js +5 -9
  16. package/dist/browser/browser.d.ts +3 -31
  17. package/dist/browser/browser.js +36 -219
  18. package/dist/browser/chrome-launch.d.ts +14 -1
  19. package/dist/browser/chrome-launch.js +44 -1
  20. package/dist/browser/dialog-handling.d.ts +32 -0
  21. package/dist/browser/dialog-handling.js +85 -0
  22. package/dist/browser/document-watcher.d.ts +44 -0
  23. package/dist/browser/document-watcher.js +160 -0
  24. package/dist/browser/download-folders.d.ts +0 -1
  25. package/dist/browser/download-folders.js +7 -15
  26. package/dist/browser/download.js +5 -10
  27. package/dist/browser/downloads-dir.js +2 -2
  28. package/dist/browser/emit.d.ts +7 -0
  29. package/dist/browser/emit.js +16 -0
  30. package/dist/browser/emulation.d.ts +1 -1
  31. package/dist/browser/emulation.js +54 -18
  32. package/dist/browser/file-chooser.js +4 -11
  33. package/dist/browser/history.d.ts +6 -0
  34. package/dist/browser/history.js +89 -0
  35. package/dist/browser/index.d.ts +2 -0
  36. package/dist/browser/index.js +2 -0
  37. package/dist/browser/init-script.d.ts +2 -0
  38. package/dist/browser/init-script.js +16 -0
  39. package/dist/browser/launch-firefox.d.ts +20 -0
  40. package/dist/browser/launch-firefox.js +66 -0
  41. package/dist/browser/launch-flags.d.ts +18 -0
  42. package/dist/browser/launch-flags.js +100 -0
  43. package/dist/browser/lazy.d.ts +21 -0
  44. package/dist/browser/lazy.js +44 -0
  45. package/dist/browser/page-events.d.ts +44 -0
  46. package/dist/browser/page-events.js +58 -0
  47. package/dist/browser/page-logs.js +2 -9
  48. package/dist/browser/page-navigation.d.ts +58 -0
  49. package/dist/browser/page-navigation.js +108 -0
  50. package/dist/browser/page-network.d.ts +69 -0
  51. package/dist/browser/page-network.js +163 -0
  52. package/dist/browser/page-settings.d.ts +35 -0
  53. package/dist/browser/page-settings.js +51 -0
  54. package/dist/browser/page-transfers.d.ts +36 -0
  55. package/dist/browser/page-transfers.js +50 -0
  56. package/dist/browser/page.d.ts +39 -154
  57. package/dist/browser/page.js +134 -758
  58. package/dist/browser/pdf.d.ts +1 -1
  59. package/dist/browser/session.d.ts +16 -0
  60. package/dist/browser/session.js +32 -0
  61. package/dist/browser/viewport.d.ts +19 -0
  62. package/dist/browser/viewport.js +72 -0
  63. package/dist/browser/warm-up.d.ts +1 -1
  64. package/dist/browser/warm-up.js +2 -1
  65. package/dist/browsers/index.d.ts +1 -1
  66. package/dist/browsers/index.js +1 -1
  67. package/dist/browsers/pins.d.ts +0 -2
  68. package/dist/browsers/pins.js +0 -2
  69. package/dist/browsers/store.d.ts +0 -2
  70. package/dist/browsers/store.js +1 -2
  71. package/dist/cli/args.d.ts +19 -7
  72. package/dist/cli/args.js +18 -9
  73. package/dist/cli/browsers.d.ts +1 -2
  74. package/dist/cli/browsers.js +2 -2
  75. package/dist/cli/console-reporter.d.ts +4 -0
  76. package/dist/cli/console-reporter.js +15 -7
  77. package/dist/cli/flow-reporter.js +2 -1
  78. package/dist/cli/flow.d.ts +1 -2
  79. package/dist/cli/flow.js +25 -22
  80. package/dist/cli/init.js +3 -8
  81. package/dist/cli/io.d.ts +10 -0
  82. package/dist/cli/io.js +1 -0
  83. package/dist/cli/main.d.ts +3 -10
  84. package/dist/cli/main.js +11 -137
  85. package/dist/cli/paint.d.ts +2 -0
  86. package/dist/cli/paint.js +4 -0
  87. package/dist/cli/record.d.ts +4 -0
  88. package/dist/cli/record.js +93 -0
  89. package/dist/cli/usage.d.ts +1 -0
  90. package/dist/cli/usage.js +58 -0
  91. package/dist/cli/version.d.ts +2 -0
  92. package/dist/cli/version.js +7 -0
  93. package/dist/config/browsers.d.ts +11 -0
  94. package/dist/config/browsers.js +32 -0
  95. package/dist/config/config.js +8 -1
  96. package/dist/config/mask.d.ts +1 -1
  97. package/dist/config/mask.js +7 -2
  98. package/dist/config/run-settings.d.ts +1 -2
  99. package/dist/config/run-settings.js +1 -6
  100. package/dist/config/timeouts.d.ts +2 -0
  101. package/dist/config/timeouts.js +13 -0
  102. package/dist/config/workers.d.ts +14 -0
  103. package/dist/config/workers.js +29 -0
  104. package/dist/flows/run/branch-context.d.ts +14 -0
  105. package/dist/flows/run/branch-context.js +35 -0
  106. package/dist/flows/run/handlers/condition.d.ts +1 -1
  107. package/dist/flows/run/handlers/end.d.ts +1 -1
  108. package/dist/flows/run/handlers/group.d.ts +1 -1
  109. package/dist/flows/run/handlers/index.d.ts +2 -2
  110. package/dist/flows/run/handlers/parallel.d.ts +1 -1
  111. package/dist/flows/run/handlers/start.d.ts +1 -1
  112. package/dist/flows/run/handlers/support.d.ts +3 -24
  113. package/dist/flows/run/handlers/support.js +1 -1
  114. package/dist/flows/run/handlers/test.d.ts +1 -1
  115. package/dist/flows/run/handlers/types.d.ts +27 -0
  116. package/dist/flows/run/handlers/types.js +1 -0
  117. package/dist/flows/run/index.d.ts +1 -1
  118. package/dist/flows/run/prepare-flow.d.ts +14 -0
  119. package/dist/flows/run/prepare-flow.js +44 -0
  120. package/dist/flows/run/project.d.ts +33 -2
  121. package/dist/flows/run/project.js +139 -49
  122. package/dist/flows/run/run.d.ts +8 -4
  123. package/dist/flows/run/run.js +30 -194
  124. package/dist/flows/run/walker.d.ts +56 -0
  125. package/dist/flows/run/walker.js +225 -0
  126. package/dist/flows/steps/catalog.d.ts +1 -1
  127. package/dist/flows/steps/handler.d.ts +1 -1
  128. package/dist/flows/steps/set.d.ts +1 -1
  129. package/dist/index.js +1 -1
  130. package/dist/locator/actionability.d.ts +33 -0
  131. package/dist/locator/actionability.js +104 -0
  132. package/dist/locator/chain-resolver.d.ts +20 -0
  133. package/dist/locator/chain-resolver.js +102 -0
  134. package/dist/locator/document-swap.d.ts +1 -0
  135. package/dist/locator/document-swap.js +11 -0
  136. package/dist/locator/element-state.d.ts +3 -1
  137. package/dist/locator/element-state.js +11 -3
  138. package/dist/locator/file-actions.d.ts +35 -0
  139. package/dist/locator/file-actions.js +55 -0
  140. package/dist/{script/helpers.js → locator/helper-realm.js} +2 -2
  141. package/dist/locator/input-actions.d.ts +18 -0
  142. package/dist/locator/input-actions.js +80 -0
  143. package/dist/locator/label-locator.d.ts +1 -1
  144. package/dist/locator/label-locator.js +5 -12
  145. package/dist/locator/locator.d.ts +14 -37
  146. package/dist/locator/locator.js +68 -424
  147. package/dist/locator/page-scripts.d.ts +16 -0
  148. package/dist/locator/page-scripts.js +54 -0
  149. package/dist/locator/page-search.d.ts +10 -0
  150. package/dist/locator/page-search.js +19 -0
  151. package/dist/locator/selector-errors.d.ts +0 -4
  152. package/dist/locator/selector-errors.js +0 -7
  153. package/dist/locator/selector.d.ts +14 -13
  154. package/dist/locator/selector.js +10 -16
  155. package/dist/locator/text-locator.d.ts +1 -1
  156. package/dist/locator/text-locator.js +5 -9
  157. package/dist/logger/index.d.ts +6 -0
  158. package/dist/logger/index.js +14 -7
  159. package/dist/network/bidi-wire.d.ts +10 -0
  160. package/dist/network/bidi-wire.js +38 -0
  161. package/dist/network/intercept.d.ts +30 -0
  162. package/dist/network/intercept.js +130 -0
  163. package/dist/network/network-tracker.d.ts +10 -47
  164. package/dist/network/network-tracker.js +34 -68
  165. package/dist/network/network-types.d.ts +33 -0
  166. package/dist/network/network-types.js +1 -0
  167. package/dist/network/network-wait.d.ts +7 -2
  168. package/dist/network/network-wait.js +14 -4
  169. package/dist/network/response.d.ts +1 -1
  170. package/dist/network/response.js +1 -1
  171. package/dist/network/route.d.ts +92 -0
  172. package/dist/network/route.js +142 -0
  173. package/dist/network/router.d.ts +6 -91
  174. package/dist/network/router.js +25 -258
  175. package/dist/recorder/expectation.d.ts +5 -0
  176. package/dist/recorder/expectation.js +20 -0
  177. package/dist/recorder/files-recorder.d.ts +30 -0
  178. package/dist/recorder/files-recorder.js +88 -0
  179. package/dist/recorder/normalise.d.ts +17 -6
  180. package/dist/recorder/normalise.js +96 -91
  181. package/dist/recorder/options.d.ts +56 -0
  182. package/dist/recorder/options.js +1 -0
  183. package/dist/recorder/page-messages.d.ts +35 -0
  184. package/dist/recorder/page-messages.js +26 -0
  185. package/dist/recorder/ranking.js +1 -0
  186. package/dist/recorder/realms.d.ts +6 -0
  187. package/dist/recorder/realms.js +13 -0
  188. package/dist/recorder/recorder.d.ts +10 -74
  189. package/dist/recorder/recorder.js +39 -199
  190. package/dist/recorder/session-browser.d.ts +22 -0
  191. package/dist/recorder/session-browser.js +21 -0
  192. package/dist/recorder/session-secrets.d.ts +8 -0
  193. package/dist/recorder/session-secrets.js +45 -0
  194. package/dist/recorder/session.d.ts +7 -13
  195. package/dist/recorder/session.js +22 -117
  196. package/dist/recorder/spec-source.d.ts +39 -0
  197. package/dist/recorder/spec-source.js +84 -0
  198. package/dist/recorder/toolbar/action-guard.d.ts +21 -0
  199. package/dist/recorder/toolbar/action-guard.js +43 -0
  200. package/dist/recorder/toolbar/actions/assert.d.ts +4 -0
  201. package/dist/recorder/toolbar/actions/assert.js +52 -0
  202. package/dist/recorder/toolbar/actions/insert.d.ts +6 -0
  203. package/dist/recorder/toolbar/actions/insert.js +93 -0
  204. package/dist/recorder/toolbar/actions/pick.d.ts +8 -0
  205. package/dist/recorder/toolbar/actions/pick.js +26 -0
  206. package/dist/recorder/toolbar/actions/reply.d.ts +7 -0
  207. package/dist/recorder/toolbar/actions/reply.js +10 -0
  208. package/dist/recorder/toolbar/controller-fixture.d.ts +47 -0
  209. package/dist/recorder/toolbar/controller-fixture.js +129 -0
  210. package/dist/recorder/toolbar/controller.d.ts +12 -78
  211. package/dist/recorder/toolbar/controller.js +35 -247
  212. package/dist/recorder/toolbar/inspect.d.ts +1 -3
  213. package/dist/recorder/toolbar/inspect.js +2 -2
  214. package/dist/recorder/toolbar/page-scope.d.ts +19 -0
  215. package/dist/recorder/toolbar/page-scope.js +43 -0
  216. package/dist/recorder/toolbar/protocol.d.ts +2 -1
  217. package/dist/recorder/toolbar/source/attach.d.ts +2 -0
  218. package/dist/recorder/toolbar/source/attach.js +41 -0
  219. package/dist/recorder/toolbar/source/dom.d.ts +2 -0
  220. package/dist/recorder/toolbar/source/dom.js +47 -0
  221. package/dist/recorder/toolbar/source/drag.d.ts +2 -0
  222. package/dist/recorder/toolbar/source/drag.js +32 -0
  223. package/dist/recorder/toolbar/source/events-page.d.ts +2 -0
  224. package/dist/recorder/toolbar/source/events-page.js +67 -0
  225. package/dist/recorder/toolbar/source/events-toolbar.d.ts +2 -0
  226. package/dist/recorder/toolbar/source/events-toolbar.js +35 -0
  227. package/dist/recorder/toolbar/source/fields.d.ts +2 -0
  228. package/dist/recorder/toolbar/source/fields.js +44 -0
  229. package/dist/recorder/toolbar/source/handlers.d.ts +2 -0
  230. package/dist/recorder/toolbar/source/handlers.js +134 -0
  231. package/dist/recorder/toolbar/source/names.d.ts +2 -0
  232. package/dist/recorder/toolbar/source/names.js +12 -0
  233. package/dist/recorder/toolbar/source/picking.d.ts +2 -0
  234. package/dist/recorder/toolbar/source/picking.js +72 -0
  235. package/dist/recorder/toolbar/source/placement.d.ts +2 -0
  236. package/dist/recorder/toolbar/source/placement.js +45 -0
  237. package/dist/recorder/toolbar/source/recorder-side.d.ts +2 -0
  238. package/dist/recorder/toolbar/source/recorder-side.js +54 -0
  239. package/dist/recorder/toolbar/source/setup.d.ts +2 -0
  240. package/dist/recorder/toolbar/source/setup.js +50 -0
  241. package/dist/recorder/toolbar/source/views-panels.d.ts +2 -0
  242. package/dist/recorder/toolbar/source/views-panels.js +150 -0
  243. package/dist/recorder/toolbar/source/views-rail.d.ts +2 -0
  244. package/dist/recorder/toolbar/source/views-rail.js +40 -0
  245. package/dist/recorder/toolbar/source/views-render.d.ts +2 -0
  246. package/dist/recorder/toolbar/source/views-render.js +48 -0
  247. package/dist/recorder/toolbar/source.js +30 -856
  248. package/dist/recorder/toolbar/types.d.ts +70 -0
  249. package/dist/recorder/toolbar/types.js +1 -0
  250. package/dist/recorder/toolbar-bridge.d.ts +43 -0
  251. package/dist/recorder/toolbar-bridge.js +106 -0
  252. package/dist/runner/browsers.d.ts +10 -0
  253. package/dist/runner/browsers.js +12 -0
  254. package/dist/runner/groups.d.ts +5 -1
  255. package/dist/runner/groups.js +9 -2
  256. package/dist/runner/options.d.ts +31 -0
  257. package/dist/runner/options.js +1 -0
  258. package/dist/runner/pooled-run.d.ts +43 -0
  259. package/dist/runner/pooled-run.js +75 -0
  260. package/dist/runner/ports.d.ts +2 -0
  261. package/dist/runner/ports.js +2 -0
  262. package/dist/runner/registry.d.ts +1 -1
  263. package/dist/runner/registry.js +1 -1
  264. package/dist/runner/reporter.d.ts +40 -11
  265. package/dist/runner/reporter.js +69 -16
  266. package/dist/runner/run-test.d.ts +16 -0
  267. package/dist/runner/run-test.js +178 -0
  268. package/dist/runner/run.d.ts +5 -2
  269. package/dist/runner/run.js +28 -28
  270. package/dist/runner/select.d.ts +24 -0
  271. package/dist/runner/select.js +77 -0
  272. package/dist/runner/test-dir.d.ts +13 -0
  273. package/dist/runner/test-dir.js +27 -0
  274. package/dist/runner/test-runner.d.ts +27 -50
  275. package/dist/runner/test-runner.js +102 -264
  276. package/dist/runner/worker-pool.d.ts +67 -0
  277. package/dist/runner/worker-pool.js +275 -0
  278. package/dist/runner/worker-process.d.ts +6 -0
  279. package/dist/runner/worker-process.js +54 -0
  280. package/dist/runner/worker-protocol.d.ts +67 -0
  281. package/dist/runner/worker-protocol.js +1 -0
  282. package/dist/runner/worker-session.d.ts +7 -0
  283. package/dist/runner/worker-session.js +60 -0
  284. package/dist/runner/worker.d.ts +26 -0
  285. package/dist/runner/worker.js +121 -0
  286. package/dist/runner/workers-option.d.ts +15 -0
  287. package/dist/runner/workers-option.js +22 -0
  288. package/dist/script/call-function.d.ts +1 -9
  289. package/dist/script/call-function.js +2 -19
  290. package/dist/script/element-handle.d.ts +1 -2
  291. package/dist/script/element-handle.js +1 -2
  292. package/dist/script/serialize.d.ts +3 -12
  293. package/dist/script/serialize.js +53 -62
  294. package/dist/steps/parse/call.d.ts +3 -0
  295. package/dist/steps/parse/call.js +81 -0
  296. package/dist/steps/parse/expectation.d.ts +5 -0
  297. package/dist/steps/parse/expectation.js +71 -0
  298. package/dist/steps/parse/file-entry.d.ts +4 -0
  299. package/dist/steps/parse/file-entry.js +74 -0
  300. package/dist/steps/parse/literals.d.ts +4 -0
  301. package/dist/steps/parse/literals.js +28 -0
  302. package/dist/steps/parse/step.d.ts +4 -0
  303. package/dist/steps/parse/step.js +81 -0
  304. package/dist/steps/parse.js +2 -323
  305. package/dist/transport/bidi-connection.d.ts +4 -2
  306. package/dist/transport/bidi-connection.js +9 -43
  307. package/dist/transport/log-redaction.d.ts +13 -0
  308. package/dist/transport/log-redaction.js +51 -0
  309. package/dist/transport/subscriptions.js +18 -13
  310. package/dist/transport/unsupported.d.ts +7 -0
  311. package/dist/transport/unsupported.js +13 -0
  312. package/dist/types/bidi-modules/browser.d.ts +1 -12
  313. package/dist/types/bidi-modules/browsing-context.d.ts +8 -18
  314. package/dist/types/bidi-modules/emulation.d.ts +29 -21
  315. package/dist/types/bidi-modules/input.d.ts +1 -9
  316. package/dist/types/bidi-modules/network.d.ts +29 -24
  317. package/dist/types/bidi-modules/script.d.ts +0 -9
  318. package/dist/types/bidi-modules/session.d.ts +0 -8
  319. package/dist/types/bidi-modules/storage.d.ts +0 -5
  320. package/dist/types/bidi.d.ts +7 -37
  321. package/dist/types/config.d.ts +17 -3
  322. package/dist/types/test.d.ts +15 -2
  323. package/dist/wait/wait-until.d.ts +1 -5
  324. package/dist/wait/wait-until.js +7 -16
  325. package/package.json +3 -2
  326. package/dist/config/default.d.ts +0 -2
  327. package/dist/config/default.js +0 -3
  328. package/dist/types/bidi-modules/web-extensions.d.ts +0 -9
  329. package/dist/types/bidi-protocols/command.d.ts +0 -7
  330. package/dist/types/bidi-protocols/event.d.ts +0 -17
  331. /package/dist/{script/helpers.d.ts → locator/helper-realm.d.ts} +0 -0
@@ -1,103 +1,14 @@
1
1
  import { BiDiError } from "../transport/bidi-error.js";
2
2
  import { callFunction, ScriptError } from "../script/call-function.js";
3
- import { CALL_PROBE, HELPER_SANDBOX, HELPERS_MISSING, } from "../script/helpers.js";
4
3
  import { ElementHandle } from "../script/element-handle.js";
5
4
  import { takeScreenshot, } from "../browser/screenshot.js";
6
- import { isGeneratedFile, resolveFileInputs, } from "../browser/generated-files.js";
7
- import { resolveTimeout, waitUntil, WaitTimeoutError, } from "../wait/wait-until.js";
8
- import { ActionTimeoutError } from "./action-timeout-error.js";
9
- import { allPass, DETACHED_STATE, evaluateChecks, parseElementState, PROBE_ELEMENT, } from "./element-state.js";
10
- import { InvalidSelectorError, UnsupportedOperationError, } from "./selector-errors.js";
11
- import { LABEL_LOCATE } from "./label-locator.js";
12
- import { TEXT_LOCATE } from "./text-locator.js";
13
- import { cssSelector, describeChain, describeSelector, labelSelector, roleSelector, testIdSelector, textSelector, toBiDiLocator, xpathSelector, } from "./selector.js";
14
- export { InvalidSelectorError, UnsupportedOperationError, } from "./selector-errors.js";
15
- /** Locator types a connection's browser rejected, so they are not tried again on every poll */
16
- const unsupportedByConnector = new WeakMap();
17
- function unsupportedTypes(connector) {
18
- let types = unsupportedByConnector.get(connector);
19
- if (!types)
20
- unsupportedByConnector.set(connector, (types = new Set()));
21
- return types;
22
- }
23
- /** What `setInputFiles` needs to know about the element before it sends files */
24
- const FILE_INPUT_INFO = `(el) => ({
25
- tag: el.tagName.toLowerCase(),
26
- type: (el.getAttribute("type") || "").toLowerCase(),
27
- multiple: Boolean(el.multiple),
28
- })`;
29
- const FILE_INPUT_CHECKS = ["attached", "enabled"];
30
- const DROP_CHECKS = ["attached", "visible"];
31
- /** The sandbox `dropFiles` builds its files in */
32
- const DROP_SANDBOX = "samurai-drop";
33
- const DROP_KEY = `globalThis[Symbol.for("samurai.drop")]`;
34
- const DROP_INPUT = `() => {
35
- const input = document.createElement("input");
36
- input.type = "file";
37
- input.multiple = true;
38
- ${DROP_KEY} = input;
39
- return input;
40
- }`;
41
- /** Fires dragenter, dragover and drop at the element's centre with the input's files (retyped where asked) */
42
- const DROP_EVENTS = `(el, types) => {
43
- const input = ${DROP_KEY};
44
- delete ${DROP_KEY};
45
- const data = new DataTransfer();
46
- Array.from(input.files).forEach((file, i) => {
47
- data.items.add(types[i] ? new File([file], file.name, { type: types[i], lastModified: file.lastModified }) : file);
48
- });
49
- const box = el.getBoundingClientRect();
50
- const at = { clientX: box.left + box.width / 2, clientY: box.top + box.height / 2 };
51
- for (const type of ["dragenter", "dragover", "drop"]) {
52
- el.dispatchEvent(new DragEvent(type, Object.assign({ bubbles: true, cancelable: true, composed: true, dataTransfer: data }, at)));
53
- }
54
- }`;
55
- const SCREENSHOT_CHECKS = ["attached", "visible"];
56
- const CLICK_CHECKS = [
57
- "attached",
58
- "visible",
59
- "stable",
60
- "enabled",
61
- "hit target",
62
- ];
63
- const FILL_CHECKS = [
64
- "attached",
65
- "visible",
66
- "enabled",
67
- "editable",
68
- "hit target",
69
- ];
70
- const PRESS_CHECKS = ["attached", "visible", "enabled"];
71
- const ATTACHED_ONLY = ["attached"];
72
- /** WebDriver code points of the named keys `press()` accepts; any other single character is typed as is */
73
- const NAMED_KEYS = {
74
- Backspace: "\uE003",
75
- Tab: "\uE004",
76
- Enter: "\uE007",
77
- Escape: "\uE00C",
78
- Space: " ",
79
- ArrowLeft: "\uE012",
80
- ArrowUp: "\uE013",
81
- ArrowRight: "\uE014",
82
- ArrowDown: "\uE015",
83
- Delete: "\uE017",
84
- Home: "\uE011",
85
- End: "\uE010",
86
- PageUp: "\uE00E",
87
- PageDown: "\uE00F",
88
- };
89
- /** Unicode code point WebDriver uses for the Backspace key */
90
- const BACKSPACE = "";
91
- /**
92
- * Chrome answers a command sent while the page swaps documents with an unknown error that says the context
93
- * is gone for the moment; the same call a moment later works.
94
- */
95
- const DOCUMENT_SWAP = /Cannot find context with specified id|execution contexts? (was |were )?(cleared|destroyed)/i;
96
- function isDocumentSwap(err) {
97
- return (err instanceof BiDiError &&
98
- err.code === "unknown error" &&
99
- DOCUMENT_SWAP.test(err.message));
100
- }
5
+ import { probeState, waitForActionable, waitForState, } from "./actionability.js";
6
+ import { ChainResolver } from "./chain-resolver.js";
7
+ import { dropFiles, setInputFiles, } from "./file-actions.js";
8
+ import { describeType, } from "./element-state.js";
9
+ import { clickRect, DEFAULT_PAUSE_MS, NAMED_KEYS, pause, pressKey, typeText, } from "./input-actions.js";
10
+ import { CLICK_CHECKS, FILL_CHECKS, PRESS_CHECKS, SCREENSHOT_CHECKS, ATTACHED_ONLY, } from "./page-scripts.js";
11
+ import { cssSelector, describeChain, describeSelector, labelSelector, roleSelector, testIdSelector, textSelector, xpathSelector, } from "./selector.js";
101
12
  export default class Locator {
102
13
  /**
103
14
  * `selector` is an xpath, or a chain of selector steps that each search inside the previous step's matches.
@@ -112,6 +23,27 @@ export default class Locator {
112
23
  this.contextId = contextId;
113
24
  this.helpers = helpers;
114
25
  this.alternatives = alternatives;
26
+ const locator = this;
27
+ this.actionability = {
28
+ resolveOne: () => this.resolveOne(),
29
+ call: (fn, args, sandbox) => this.call(fn, args, sandbox),
30
+ get selector() {
31
+ return locator.selector;
32
+ },
33
+ helpers,
34
+ };
35
+ this.elementContext = {
36
+ connector: biDiConnector,
37
+ contextId,
38
+ get selector() {
39
+ return locator.selector;
40
+ },
41
+ call: (fn, args, sandbox) => this.call(fn, args, sandbox),
42
+ waitForActionable: (action, checks, probe, options) => this.waitForActionable(action, checks, probe, options),
43
+ requireElement: () => this.requireElement(),
44
+ noElementError: () => this.noElementError(),
45
+ };
46
+ this.resolver = new ChainResolver(biDiConnector, contextId, (fn, args, sandbox) => this.call(fn, args, sandbox));
115
47
  }
116
48
  /**
117
49
  * The description of this locator used in error messages, e.g. `//form >> role=button[name="Save"]`;
@@ -190,7 +122,7 @@ export default class Locator {
190
122
  */
191
123
  async resolve(max) {
192
124
  this.matched = undefined;
193
- const own = await this.resolveChain(max);
125
+ const own = await this.resolver.resolveChain(this.chain, max);
194
126
  if (own.length > 0) {
195
127
  this.matched = { index: 0, selector: describeChain(this.chain) };
196
128
  return own;
@@ -206,7 +138,7 @@ export default class Locator {
206
138
  }
207
139
  /** The primary or the first fallback that currently matches, without its own fallbacks */
208
140
  async firstMatching() {
209
- if ((await this.resolveChain(1)).length > 0)
141
+ if ((await this.resolver.resolveChain(this.chain, 1)).length > 0)
210
142
  return this.withoutFallbacks();
211
143
  for (const alternative of this.alternatives) {
212
144
  const found = await alternative.firstMatching();
@@ -218,90 +150,9 @@ export default class Locator {
218
150
  withoutFallbacks() {
219
151
  return new Locator(this.chain, this.biDiConnector, this.contextId, this.helpers);
220
152
  }
221
- async resolveChain(max) {
222
- let nodes;
223
- for (const [index, selector] of this.chain.entries()) {
224
- if (selector.kind === "nth") {
225
- const picked = nodes?.[selector.index];
226
- nodes = picked ? [picked] : [];
227
- }
228
- else {
229
- try {
230
- nodes = await this.locateStep(selector, index > 0, nodes, index === this.chain.length - 1 ? max : undefined);
231
- }
232
- catch (err) {
233
- // The page is swapping documents: nothing matches right now, and the waits that poll try again
234
- if (isDocumentSwap(err))
235
- return [];
236
- throw err;
237
- }
238
- }
239
- if (nodes.length === 0)
240
- return [];
241
- }
242
- return nodes ?? [];
243
- }
244
153
  async resolveOne() {
245
154
  return (await this.resolve(1))[0] ?? null;
246
155
  }
247
- async locateStep(selector, scoped, startNodes, max) {
248
- if (selector.kind === "label")
249
- return this.locateInPage(LABEL_LOCATE, selector, startNodes, max);
250
- if (selector.kind === "text" &&
251
- unsupportedTypes(this.biDiConnector).has("innerText")) {
252
- return this.locateByText(selector, startNodes, max);
253
- }
254
- try {
255
- return await this.locateNatively(selector, scoped, startNodes, max);
256
- }
257
- catch (err) {
258
- if (err instanceof BiDiError && err.code === "invalid selector") {
259
- throw new InvalidSelectorError(describeSelector(selector, scoped), err.message);
260
- }
261
- if (err instanceof BiDiError && err.code === "unsupported operation") {
262
- if (selector.kind === "text") {
263
- // The browser has no innerText locator (Firefox): remember that and search in the page instead
264
- unsupportedTypes(this.biDiConnector).add("innerText");
265
- return this.locateByText(selector, startNodes, max);
266
- }
267
- throw new UnsupportedOperationError(`${describeSelector(selector, scoped)}: this kind of locator is not supported by the browser (${err.message})`);
268
- }
269
- throw err;
270
- }
271
- }
272
- async locateNatively(selector, scoped, startNodes, max) {
273
- const { nodes } = await this.biDiConnector.send("browsingContext.locateNodes", {
274
- context: this.contextId,
275
- locator: toBiDiLocator(selector, scoped),
276
- ...(max !== undefined && { maxNodeCount: max }),
277
- // Only the references are needed; skip serializing the matched subtrees
278
- serializationOptions: { maxDomDepth: 0 },
279
- ...(startNodes && {
280
- startNodes: startNodes.map(({ sharedId }) => ({ sharedId })),
281
- }),
282
- });
283
- const found = new Map();
284
- for (const node of nodes) {
285
- if (node.sharedId !== undefined && !found.has(node.sharedId)) {
286
- found.set(node.sharedId, new ElementHandle(node.sharedId, node.handle));
287
- }
288
- }
289
- return [...found.values()];
290
- }
291
- /** Text search done in the page, for browsers without BiDi's innerText locator */
292
- locateByText(selector, startNodes, max) {
293
- return this.locateInPage(TEXT_LOCATE, selector, startNodes, max);
294
- }
295
- /** Runs a page-side search `(starts, value, match, ignoreCase) => elements` */
296
- async locateInPage(fn, selector, startNodes, max) {
297
- const found = await this.call(fn, [
298
- startNodes ?? [],
299
- selector.value,
300
- selector.match,
301
- selector.ignoreCase,
302
- ]);
303
- return max === undefined ? found : found.slice(0, max);
304
- }
305
156
  /** Calls `fn` in the page; a throwing function becomes a "Failed to locate element" error */
306
157
  async call(fn, args, sandbox) {
307
158
  try {
@@ -338,120 +189,32 @@ export default class Locator {
338
189
  async callOnExistingElement(body) {
339
190
  const missing = Symbol("missing");
340
191
  const result = await this.callOnElement(missing, body);
341
- if (result === missing) {
342
- throw new Error(`Failed to locate element ${this.selector}. Details: no element matches`);
343
- }
192
+ if (result === missing)
193
+ throw this.noElementError();
344
194
  return result;
345
195
  }
346
- /** Reads the element's actionability state: one search, one probe */
347
- async probeState(options) {
196
+ /** The error for an operation that needs an element when none matches */
197
+ noElementError() {
198
+ return new Error(`Failed to locate element ${this.selector}. Details: no element matches`);
199
+ }
200
+ /** The element the locator matches now; throws when none does */
201
+ async requireElement() {
348
202
  const el = await this.resolveOne();
349
203
  if (!el)
350
- return DETACHED_STATE;
351
- try {
352
- return parseElementState(await this.callProbe(el, options));
353
- }
354
- catch (err) {
355
- // The document changed between the search and the probe
356
- if ((err instanceof BiDiError && err.code === "no such node") ||
357
- isDocumentSwap(err))
358
- return DETACHED_STATE;
359
- throw err;
360
- }
204
+ throw this.noElementError();
205
+ return el;
361
206
  }
362
- async callProbe(el, options) {
363
- const args = [el, { ...options }];
364
- if (!this.helpers)
365
- return this.call(PROBE_ELEMENT, args);
366
- await this.helpers.ensureInstalled();
367
- let result = await this.call(CALL_PROBE, args, HELPER_SANDBOX);
368
- if (result === HELPERS_MISSING) {
369
- // A document got past the registration (e.g. created while it was being set up): install again once
370
- await this.helpers.reinstall();
371
- result = await this.call(CALL_PROBE, args, HELPER_SANDBOX);
372
- if (result === HELPERS_MISSING) {
373
- throw new ScriptError("the samurai helpers are missing in the page after reinstalling", "probeElement");
374
- }
375
- }
376
- return result;
207
+ probeState(options) {
208
+ return probeState(this.actionability, options);
377
209
  }
378
- /**
379
- * Probes until every required check passes and returns that state.
380
- * Throws ActionTimeoutError describing the last probe on timeout.
381
- */
382
- async waitForActionable(action, checks, probe, options) {
383
- const timeout = await resolveTimeout(options?.timeout);
384
- // Stability compares two probes; with timeout 0 there is only one
385
- const required = options?.force
386
- ? ATTACHED_ONLY
387
- : timeout === 0
388
- ? checks.filter((check) => check !== "stable")
389
- : checks;
390
- let lastChecks;
391
- try {
392
- return await waitUntil(() => this.probeState(probe), (current, previous) => {
393
- lastChecks = evaluateChecks(required, current, previous);
394
- return allPass(lastChecks);
395
- }, { timeout });
396
- }
397
- catch (err) {
398
- if (!(err instanceof WaitTimeoutError))
399
- throw err;
400
- const last = err.last;
401
- throw new ActionTimeoutError({
402
- action,
403
- selector: this.selector,
404
- timeout,
405
- reason: !last
406
- ? "unreadable"
407
- : last.attached
408
- ? "not-actionable"
409
- : "not-attached",
410
- checks: lastChecks,
411
- coveredBy: lastChecks?.["hit target"] === "fail"
412
- ? (last?.hitTarget ?? undefined)
413
- : undefined,
414
- });
415
- }
210
+ waitForActionable(action, checks, probe, options) {
211
+ return waitForActionable(this.actionability, action, checks, probe, options);
416
212
  }
417
213
  /** Waits until the element is attached, visible, stable, enabled and not covered, then clicks its centre with real pointer input */
418
214
  async click(options) {
419
215
  const state = await this.waitForActionable("click", CLICK_CHECKS, { scroll: true, hitTest: true }, options);
420
216
  // "attached" is always required, so the box is present
421
- await this.clickRect(state.box);
422
- }
423
- /** Simulate a click event on the center off a page element.
424
- * This is mostly used internally to focus input elements when using the `fill()` method
425
- * @example
426
- * const container = page.locator("div[@id=['clickable-element']");
427
- * const rect = await container.getBoundingClientRect();
428
- * await container.clickRect(rect);
429
- */
430
- async clickRect(rect) {
431
- await this.biDiConnector.send("input.performActions", {
432
- context: this.contextId,
433
- actions: [
434
- {
435
- type: "pointer",
436
- id: "samurai-pointer",
437
- actions: [
438
- {
439
- type: "pointerMove",
440
- x: rect.x + rect.width / 2,
441
- y: rect.y + rect.height / 2,
442
- },
443
- {
444
- type: "pointerDown",
445
- button: 0,
446
- },
447
- {
448
- type: "pointerUp",
449
- button: 0,
450
- },
451
- ],
452
- },
453
- ],
454
- });
217
+ await clickRect(this.biDiConnector, this.contextId, state.box);
455
218
  }
456
219
  /**
457
220
  * Sets the files of an `<input type=file>`; `[]` clears it. Paths are relative to the project folder (absolute
@@ -462,35 +225,7 @@ export default class Locator {
462
225
  * await page.getByLabel("Upload").setInputFiles(generatedFile({ name: "huge.pdf", size: "60 MB" }));
463
226
  */
464
227
  async setInputFiles(files, options) {
465
- const paths = await resolveFileInputs(files, "setInputFiles");
466
- await this.waitForActionable("setInputFiles", FILE_INPUT_CHECKS, { scroll: false, hitTest: false }, options?.timeout === undefined ? undefined : { timeout: options.timeout });
467
- const missing = () => new Error(`Failed to locate element ${this.selector}. Details: no element matches`);
468
- const el = await this.resolveOne();
469
- if (!el)
470
- throw missing();
471
- let info;
472
- try {
473
- info = await this.call(FILE_INPUT_INFO, [el]);
474
- }
475
- catch (err) {
476
- if (err instanceof BiDiError && err.code === "no such node")
477
- throw missing();
478
- throw err;
479
- }
480
- if (info.tag !== "input" || info.type !== "file") {
481
- const found = info.tag === "input"
482
- ? `<input type="${info.type || "text"}">`
483
- : `<${info.tag}>`;
484
- throw new Error(`setInputFiles(): ${this.selector} is not an <input type=file> (found ${found})`);
485
- }
486
- if (paths.length > 1 && !info.multiple) {
487
- throw new Error(`setInputFiles(): ${this.selector} does not accept multiple files`);
488
- }
489
- await this.biDiConnector.send("input.setFiles", {
490
- context: this.contextId,
491
- element: { sharedId: el.sharedId },
492
- files: paths,
493
- });
228
+ await setInputFiles(this.elementContext, files, options);
494
229
  }
495
230
  /**
496
231
  * Drops files on the element, as dragging them from the desktop does: `dragenter`, `dragover` and `drop`
@@ -501,21 +236,7 @@ export default class Locator {
501
236
  * await page.getByTestId("dropzone").dropFiles(["files/a.png", "files/b.png"]);
502
237
  */
503
238
  async dropFiles(files, options) {
504
- const list = Array.isArray(files) ? files : [files];
505
- const paths = await resolveFileInputs(list, "dropFiles");
506
- const types = list.map((file) => isGeneratedFile(file) ? (file.type ?? "") : "");
507
- await this.waitForActionable("dropFiles", DROP_CHECKS, { scroll: true, hitTest: false }, options?.timeout === undefined ? undefined : { timeout: options.timeout });
508
- const el = await this.resolveOne();
509
- if (!el)
510
- throw new Error(`Failed to locate element ${this.selector}. Details: no element matches`);
511
- // A file input of our own, made in a sandbox and never attached: the page doesn't see it
512
- const input = await this.call(DROP_INPUT, [], DROP_SANDBOX);
513
- await this.biDiConnector.send("input.setFiles", {
514
- context: this.contextId,
515
- element: { sharedId: input.sharedId },
516
- files: paths,
517
- });
518
- await this.call(DROP_EVENTS, [el, types], DROP_SANDBOX);
239
+ await dropFiles(this.elementContext, files, options);
519
240
  }
520
241
  /**
521
242
  * Takes a screenshot of just this element, after scrolling it into view and waiting until it is attached and
@@ -526,10 +247,7 @@ export default class Locator {
526
247
  async screenshot(options = {}) {
527
248
  const { timeout, ...capture } = options;
528
249
  await this.waitForActionable("screenshot", SCREENSHOT_CHECKS, { scroll: true, hitTest: false }, timeout === undefined ? undefined : { timeout });
529
- const el = await this.resolveOne();
530
- if (!el) {
531
- throw new Error(`Failed to locate element ${this.selector}. Details: no element matches`);
532
- }
250
+ const el = await this.requireElement();
533
251
  return takeScreenshot(this.biDiConnector, this.contextId, capture, {
534
252
  sharedId: el.sharedId,
535
253
  });
@@ -540,30 +258,8 @@ export default class Locator {
540
258
  await this.callOnExistingElement(`el.focus();`);
541
259
  }
542
260
  /** Waits until the element reaches `state` (default "visible"); does not scroll */
543
- async waitFor({ state = "visible", timeout, } = {}) {
544
- const resolved = await resolveTimeout(timeout);
545
- const reached = {
546
- attached: (current) => current.attached,
547
- detached: (current) => !current.attached,
548
- visible: (current) => current.attached && current.visible,
549
- hidden: (current) => !current.attached || !current.visible,
550
- };
551
- try {
552
- await waitUntil(() => this.probeState({ scroll: false, hitTest: false }), reached[state], {
553
- timeout: resolved,
554
- });
555
- }
556
- catch (err) {
557
- if (!(err instanceof WaitTimeoutError))
558
- throw err;
559
- throw new ActionTimeoutError({
560
- action: "waitFor",
561
- selector: this.selector,
562
- timeout: resolved,
563
- reason: err.last === undefined ? "unreadable" : "wrong-state",
564
- state,
565
- });
566
- }
261
+ async waitFor(options = {}) {
262
+ await waitForState(this.actionability, options);
567
263
  }
568
264
  /** Returns the browser's getBoundingClientRect result for the given element */
569
265
  async getBoundingClientRect() {
@@ -576,34 +272,22 @@ export default class Locator {
576
272
  }
577
273
  return rect;
578
274
  }
579
- stringOrNull(value) {
580
- if (typeof value === "string")
581
- return value;
582
- if (value === null)
583
- return null;
584
- throw new Error(`Expected a string or null but received "${describeType(value)}"`);
585
- }
586
275
  /** Whether the element exists, has a non-empty box and is not hidden by CSS */
587
276
  async isVisible() {
588
- const result = await this.callOnElement(false, `
589
- const rect = el.getBoundingClientRect();
590
- const style = getComputedStyle(el);
591
- return rect.width > 0 && rect.height > 0 &&
592
- style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0";
593
- `);
594
- return result === true;
277
+ const state = await this.probeState({ scroll: false, hitTest: false });
278
+ return state.attached && state.visible;
595
279
  }
596
280
  /** Trimmed text content, or null when the element is missing */
597
281
  async textContent() {
598
- return this.stringOrNull(await this.callOnElement(null, `return el.textContent.trim();`));
282
+ return stringOrNull(await this.callOnElement(null, `return el.textContent.trim();`));
599
283
  }
600
284
  /** Value of an input/textarea/select, or null when missing */
601
285
  async inputValue() {
602
- return this.stringOrNull(await this.callOnElement(null, `return typeof el.value === "string" ? el.value : null;`));
286
+ return stringOrNull(await this.callOnElement(null, `return typeof el.value === "string" ? el.value : null;`));
603
287
  }
604
288
  /** Attribute value, or null when the element or attribute is missing */
605
289
  async getAttribute(name) {
606
- return this.stringOrNull(await this.callOnElement(null, `return el.getAttribute(name);`, ["name"], [name]));
290
+ return stringOrNull(await this.callOnElement(null, `return el.getAttribute(name);`, ["name"], [name]));
607
291
  }
608
292
  /** References to the elements currently matching, in document order. Internal: for tooling that identifies elements */
609
293
  async elements() {
@@ -624,22 +308,8 @@ export default class Locator {
624
308
  return state.attached && state.editable;
625
309
  }
626
310
  /** Wait for certain time (ms). Default: 300ms */
627
- async wait(duration = 300) {
628
- await this.biDiConnector.send("input.performActions", {
629
- context: this.contextId,
630
- actions: [
631
- {
632
- type: "none",
633
- id: "samurai-sleep",
634
- actions: [
635
- {
636
- type: "pause",
637
- duration,
638
- },
639
- ],
640
- },
641
- ],
642
- });
311
+ async wait(duration = DEFAULT_PAUSE_MS) {
312
+ await pause(this.biDiConnector, this.contextId, duration);
643
313
  }
644
314
  /**
645
315
  * Waits until the element is attached, visible and enabled, focuses it and presses `key` with real keyboard input.
@@ -655,50 +325,24 @@ export default class Locator {
655
325
  }
656
326
  await this.waitForActionable("press", PRESS_CHECKS, { scroll: true, hitTest: false }, options);
657
327
  await this.callOnElement(undefined, `el.focus();`);
658
- await this.biDiConnector.send("input.performActions", {
659
- context: this.contextId,
660
- actions: [
661
- {
662
- type: "key",
663
- id: "samurai-keyboard",
664
- actions: [
665
- { type: "keyDown", value: code },
666
- { type: "keyUp", value: code },
667
- ],
668
- },
669
- ],
670
- });
328
+ await pressKey(this.biDiConnector, this.contextId, code);
671
329
  }
672
330
  /** Waits until the field is editable and not covered, then replaces its value by typing `value`; an empty string clears it */
673
331
  async fill(value, options) {
674
332
  const state = await this.waitForActionable("fill", FILL_CHECKS, { scroll: true, hitTest: true }, options);
675
333
  // Typing over the selected existing value replaces it; Backspace clears it for an empty value
676
- const keys = value === "" ? BACKSPACE : value;
677
- const actions = Array.from(keys).flatMap((char) => [
678
- {
679
- type: "keyDown",
680
- value: char,
681
- },
682
- {
683
- type: "keyUp",
684
- value: char,
685
- },
686
- ]);
687
- await this.clickRect(state.box);
334
+ const keys = value === "" ? NAMED_KEYS.Backspace : value;
335
+ await clickRect(this.biDiConnector, this.contextId, state.box);
336
+ // Lets the focus the click caused (and the page's focus handlers) settle before the text is selected and typed over
688
337
  await this.wait();
689
338
  await this.callOnElement(undefined, `if (typeof el.select === "function") el.select();`);
690
- await this.biDiConnector.send("input.performActions", {
691
- context: this.contextId,
692
- actions: [
693
- {
694
- actions,
695
- type: "key",
696
- id: "samurai-keyboard",
697
- },
698
- ],
699
- });
339
+ await typeText(this.biDiConnector, this.contextId, keys);
700
340
  }
701
341
  }
702
- function describeType(value) {
703
- return value === null ? "null" : typeof value;
342
+ function stringOrNull(value) {
343
+ if (typeof value === "string")
344
+ return value;
345
+ if (value === null)
346
+ return null;
347
+ throw new Error(`Expected a string or null but received "${describeType(value)}"`);
704
348
  }
@@ -0,0 +1,16 @@
1
+ import type { CheckName } from "./element-state.js";
2
+ /** Page-side source strings and the actionability checks each action waits for */
3
+ /** What `setInputFiles` needs to know about the element before it sends files */
4
+ export declare const FILE_INPUT_INFO = "(el) => ({\n tag: el.tagName.toLowerCase(),\n type: (el.getAttribute(\"type\") || \"\").toLowerCase(),\n multiple: Boolean(el.multiple),\n})";
5
+ export declare const FILE_INPUT_CHECKS: readonly CheckName[];
6
+ export declare const DROP_CHECKS: readonly CheckName[];
7
+ /** The sandbox `dropFiles` builds its files in */
8
+ export declare const DROP_SANDBOX = "samurai-drop";
9
+ export declare const DROP_INPUT = "() => {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.multiple = true;\n globalThis[Symbol.for(\"samurai.drop\")] = input;\n return input;\n}";
10
+ /** Fires dragenter, dragover and drop at the element's centre with the input's files (retyped where asked) */
11
+ export declare const DROP_EVENTS = "(el, types) => {\n const input = globalThis[Symbol.for(\"samurai.drop\")];\n delete globalThis[Symbol.for(\"samurai.drop\")];\n const data = new DataTransfer();\n Array.from(input.files).forEach((file, i) => {\n data.items.add(types[i] ? new File([file], file.name, { type: types[i], lastModified: file.lastModified }) : file);\n });\n const box = el.getBoundingClientRect();\n const at = { clientX: box.left + box.width / 2, clientY: box.top + box.height / 2 };\n for (const type of [\"dragenter\", \"dragover\", \"drop\"]) {\n el.dispatchEvent(new DragEvent(type, Object.assign({ bubbles: true, cancelable: true, composed: true, dataTransfer: data }, at)));\n }\n}";
12
+ export declare const SCREENSHOT_CHECKS: readonly CheckName[];
13
+ export declare const CLICK_CHECKS: readonly CheckName[];
14
+ export declare const FILL_CHECKS: readonly CheckName[];
15
+ export declare const PRESS_CHECKS: readonly CheckName[];
16
+ export declare const ATTACHED_ONLY: readonly CheckName[];