@noego/wood 0.4.9 → 0.5.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 (493) hide show
  1. package/README.md +118 -42
  2. package/bin/axe.js +313 -98
  3. package/dist/{loader/__fixtures__/layouts/app.load.cjs → automation/actions.cjs} +3 -13
  4. package/dist/automation/actions.cjs.map +1 -0
  5. package/dist/automation/actions.d.cts +57 -0
  6. package/dist/automation/actions.d.ts +57 -0
  7. package/dist/automation/actions.js +1 -0
  8. package/dist/automation/actions.js.map +1 -0
  9. package/dist/automation/actions_executor.cjs +101 -0
  10. package/dist/automation/actions_executor.cjs.map +1 -0
  11. package/dist/automation/actions_executor.d.cts +16 -0
  12. package/dist/automation/actions_executor.d.ts +16 -0
  13. package/dist/automation/actions_executor.js +76 -0
  14. package/dist/automation/actions_executor.js.map +1 -0
  15. package/dist/automation/connection.cjs +86 -0
  16. package/dist/automation/connection.cjs.map +1 -0
  17. package/dist/automation/connection.d.cts +18 -0
  18. package/dist/automation/connection.d.ts +18 -0
  19. package/dist/automation/connection.js +51 -0
  20. package/dist/automation/connection.js.map +1 -0
  21. package/dist/{middleware/__fixtures__/middleware/sequence.cjs → automation/errors.cjs} +25 -22
  22. package/dist/automation/errors.cjs.map +1 -0
  23. package/dist/automation/errors.d.cts +31 -0
  24. package/dist/automation/errors.d.ts +31 -0
  25. package/dist/automation/errors.js +24 -0
  26. package/dist/automation/errors.js.map +1 -0
  27. package/dist/automation/index.cjs +49 -0
  28. package/dist/automation/index.cjs.map +1 -0
  29. package/dist/automation/index.d.cts +16 -0
  30. package/dist/automation/index.d.ts +16 -0
  31. package/dist/automation/index.js +15 -0
  32. package/dist/automation/index.js.map +1 -0
  33. package/dist/automation/introspection_reader.cjs +75 -0
  34. package/dist/automation/introspection_reader.cjs.map +1 -0
  35. package/dist/automation/introspection_reader.d.cts +20 -0
  36. package/dist/automation/introspection_reader.d.ts +20 -0
  37. package/dist/automation/introspection_reader.js +48 -0
  38. package/dist/automation/introspection_reader.js.map +1 -0
  39. package/dist/automation/locator.cjs +102 -0
  40. package/dist/automation/locator.cjs.map +1 -0
  41. package/dist/automation/locator.d.cts +51 -0
  42. package/dist/automation/locator.d.ts +51 -0
  43. package/dist/automation/locator.js +75 -0
  44. package/dist/automation/locator.js.map +1 -0
  45. package/dist/{loader/__fixtures__/views/test/page.load.cjs → automation/observation.cjs} +3 -13
  46. package/dist/automation/observation.cjs.map +1 -0
  47. package/dist/automation/observation.d.cts +44 -0
  48. package/dist/automation/observation.d.ts +44 -0
  49. package/dist/automation/observation.js +1 -0
  50. package/dist/automation/observation.js.map +1 -0
  51. package/dist/{controller/__fixtures__/controllers/test.cjs → automation/receipts.cjs} +3 -15
  52. package/dist/automation/receipts.cjs.map +1 -0
  53. package/dist/automation/receipts.d.cts +27 -0
  54. package/dist/automation/receipts.d.ts +27 -0
  55. package/dist/automation/receipts.js +1 -0
  56. package/dist/automation/receipts.js.map +1 -0
  57. package/dist/automation/scenario.cjs +696 -0
  58. package/dist/automation/scenario.cjs.map +1 -0
  59. package/dist/automation/scenario.d.cts +89 -0
  60. package/dist/automation/scenario.d.ts +89 -0
  61. package/dist/automation/scenario.js +660 -0
  62. package/dist/automation/scenario.js.map +1 -0
  63. package/dist/automation/scrolling.cjs +17 -0
  64. package/dist/automation/scrolling.cjs.map +1 -0
  65. package/dist/automation/scrolling.d.cts +51 -0
  66. package/dist/automation/scrolling.d.ts +51 -0
  67. package/dist/automation/scrolling.js +1 -0
  68. package/dist/automation/scrolling.js.map +1 -0
  69. package/dist/automation/scrolling_executor.cjs +109 -0
  70. package/dist/automation/scrolling_executor.cjs.map +1 -0
  71. package/dist/automation/scrolling_executor.d.cts +13 -0
  72. package/dist/automation/scrolling_executor.d.ts +13 -0
  73. package/dist/automation/scrolling_executor.js +84 -0
  74. package/dist/automation/scrolling_executor.js.map +1 -0
  75. package/dist/automation/target_identity.cjs +17 -0
  76. package/dist/automation/target_identity.cjs.map +1 -0
  77. package/dist/automation/target_identity.d.cts +28 -0
  78. package/dist/automation/target_identity.d.ts +28 -0
  79. package/dist/automation/target_identity.js +1 -0
  80. package/dist/automation/target_identity.js.map +1 -0
  81. package/dist/automation/target_registry.cjs +148 -0
  82. package/dist/automation/target_registry.cjs.map +1 -0
  83. package/dist/automation/target_registry.d.cts +32 -0
  84. package/dist/automation/target_registry.d.ts +32 -0
  85. package/dist/automation/target_registry.js +122 -0
  86. package/dist/automation/target_registry.js.map +1 -0
  87. package/dist/automation/waits.cjs +17 -0
  88. package/dist/automation/waits.cjs.map +1 -0
  89. package/dist/automation/waits.d.cts +44 -0
  90. package/dist/automation/waits.d.ts +44 -0
  91. package/dist/automation/waits.js +1 -0
  92. package/dist/automation/waits.js.map +1 -0
  93. package/dist/automation/waits_executor.cjs +104 -0
  94. package/dist/automation/waits_executor.cjs.map +1 -0
  95. package/dist/automation/waits_executor.d.cts +14 -0
  96. package/dist/automation/waits_executor.d.ts +14 -0
  97. package/dist/automation/waits_executor.js +79 -0
  98. package/dist/automation/waits_executor.js.map +1 -0
  99. package/dist/bridge/backend_bridge.cjs.map +1 -1
  100. package/dist/bridge/backend_bridge.js.map +1 -1
  101. package/dist/client/index.cjs +78 -21
  102. package/dist/client/index.cjs.map +1 -1
  103. package/dist/client/index.d.cts +19 -3
  104. package/dist/client/index.d.ts +19 -3
  105. package/dist/client/index.js +80 -22
  106. package/dist/client/index.js.map +1 -1
  107. package/dist/client/renderer_log_transport.cjs +151 -0
  108. package/dist/client/renderer_log_transport.cjs.map +1 -0
  109. package/dist/client/renderer_log_transport.d.cts +54 -0
  110. package/dist/client/renderer_log_transport.d.ts +54 -0
  111. package/dist/client/renderer_log_transport.js +123 -0
  112. package/dist/client/renderer_log_transport.js.map +1 -0
  113. package/dist/codegen/controller_registration_generator.cjs +13 -2
  114. package/dist/codegen/controller_registration_generator.cjs.map +1 -1
  115. package/dist/codegen/controller_registration_generator.d.cts +12 -1
  116. package/dist/codegen/controller_registration_generator.d.ts +12 -1
  117. package/dist/codegen/controller_registration_generator.js +10 -1
  118. package/dist/codegen/controller_registration_generator.js.map +1 -1
  119. package/dist/codegen/index.d.cts +1 -0
  120. package/dist/codegen/index.d.ts +1 -0
  121. package/dist/codegen/preload_generator.cjs +13 -6
  122. package/dist/codegen/preload_generator.cjs.map +1 -1
  123. package/dist/codegen/preload_generator.d.cts +11 -2
  124. package/dist/codegen/preload_generator.d.ts +11 -2
  125. package/dist/codegen/preload_generator.js +13 -6
  126. package/dist/codegen/preload_generator.js.map +1 -1
  127. package/dist/codegen/renderer_app_generator.cjs +95 -44
  128. package/dist/codegen/renderer_app_generator.cjs.map +1 -1
  129. package/dist/codegen/renderer_app_generator.js +95 -44
  130. package/dist/codegen/renderer_app_generator.js.map +1 -1
  131. package/dist/codegen/type_generator.cjs +1 -0
  132. package/dist/codegen/type_generator.cjs.map +1 -1
  133. package/dist/codegen/type_generator.js +1 -0
  134. package/dist/codegen/type_generator.js.map +1 -1
  135. package/dist/config/config_parser.cjs +95 -4
  136. package/dist/config/config_parser.cjs.map +1 -1
  137. package/dist/config/config_parser.d.cts +10 -2
  138. package/dist/config/config_parser.d.ts +10 -2
  139. package/dist/config/config_parser.js +92 -3
  140. package/dist/config/config_parser.js.map +1 -1
  141. package/dist/config/index.cjs +6 -2
  142. package/dist/config/index.cjs.map +1 -1
  143. package/dist/config/index.d.cts +2 -2
  144. package/dist/config/index.d.ts +2 -2
  145. package/dist/config/index.js +8 -2
  146. package/dist/config/index.js.map +1 -1
  147. package/dist/controller/controller_resolver.cjs +51 -3
  148. package/dist/controller/controller_resolver.cjs.map +1 -1
  149. package/dist/controller/controller_resolver.d.cts +27 -4
  150. package/dist/controller/controller_resolver.d.ts +27 -4
  151. package/dist/controller/controller_resolver.js +48 -2
  152. package/dist/controller/controller_resolver.js.map +1 -1
  153. package/dist/controller/index.cjs +6 -2
  154. package/dist/controller/index.cjs.map +1 -1
  155. package/dist/controller/index.d.cts +1 -1
  156. package/dist/controller/index.d.ts +1 -1
  157. package/dist/controller/index.js +4 -2
  158. package/dist/controller/index.js.map +1 -1
  159. package/dist/dev/wood_dev_server.cjs +4 -1
  160. package/dist/dev/wood_dev_server.cjs.map +1 -1
  161. package/dist/dev/wood_dev_server.js +5 -2
  162. package/dist/dev/wood_dev_server.js.map +1 -1
  163. package/dist/dev/yaml_watcher.cjs +1 -1
  164. package/dist/dev/yaml_watcher.cjs.map +1 -1
  165. package/dist/dev/yaml_watcher.d.cts +4 -0
  166. package/dist/dev/yaml_watcher.d.ts +4 -0
  167. package/dist/dev/yaml_watcher.js +1 -1
  168. package/dist/dev/yaml_watcher.js.map +1 -1
  169. package/dist/frontend/frontend_lifecycle.cjs +74 -0
  170. package/dist/frontend/frontend_lifecycle.cjs.map +1 -0
  171. package/dist/frontend/frontend_lifecycle.d.cts +50 -0
  172. package/dist/frontend/frontend_lifecycle.d.ts +50 -0
  173. package/dist/frontend/frontend_lifecycle.js +50 -0
  174. package/dist/frontend/frontend_lifecycle.js.map +1 -0
  175. package/dist/frontend/frontend_page.cjs +122 -0
  176. package/dist/frontend/frontend_page.cjs.map +1 -0
  177. package/dist/frontend/frontend_page.d.cts +62 -0
  178. package/dist/frontend/frontend_page.d.ts +62 -0
  179. package/dist/frontend/frontend_page.js +98 -0
  180. package/dist/frontend/frontend_page.js.map +1 -0
  181. package/dist/frontend/frontend_surface.cjs +249 -0
  182. package/dist/frontend/frontend_surface.cjs.map +1 -0
  183. package/dist/frontend/frontend_surface.d.cts +64 -0
  184. package/dist/frontend/frontend_surface.d.ts +64 -0
  185. package/dist/frontend/frontend_surface.js +224 -0
  186. package/dist/frontend/frontend_surface.js.map +1 -0
  187. package/dist/frontend/index.cjs +52 -0
  188. package/dist/frontend/index.cjs.map +1 -0
  189. package/dist/frontend/index.d.cts +10 -0
  190. package/dist/frontend/index.d.ts +10 -0
  191. package/dist/frontend/index.js +19 -0
  192. package/dist/frontend/index.js.map +1 -0
  193. package/dist/frontend/page_catalog.cjs +135 -0
  194. package/dist/frontend/page_catalog.cjs.map +1 -0
  195. package/dist/frontend/page_catalog.d.cts +56 -0
  196. package/dist/frontend/page_catalog.d.ts +56 -0
  197. package/dist/frontend/page_catalog.js +108 -0
  198. package/dist/frontend/page_catalog.js.map +1 -0
  199. package/dist/frontend/tracked_transport.cjs +55 -0
  200. package/dist/frontend/tracked_transport.cjs.map +1 -0
  201. package/dist/frontend/tracked_transport.d.cts +36 -0
  202. package/dist/frontend/tracked_transport.d.ts +36 -0
  203. package/dist/frontend/tracked_transport.js +31 -0
  204. package/dist/frontend/tracked_transport.js.map +1 -0
  205. package/dist/frontend/work_registry.cjs +153 -0
  206. package/dist/frontend/work_registry.cjs.map +1 -0
  207. package/dist/frontend/work_registry.d.cts +70 -0
  208. package/dist/frontend/work_registry.d.ts +70 -0
  209. package/dist/frontend/work_registry.js +128 -0
  210. package/dist/frontend/work_registry.js.map +1 -0
  211. package/dist/index.cjs +24 -0
  212. package/dist/index.cjs.map +1 -1
  213. package/dist/index.d.cts +11 -7
  214. package/dist/index.d.ts +11 -7
  215. package/dist/index.js +27 -4
  216. package/dist/index.js.map +1 -1
  217. package/dist/main/index.cjs +10 -0
  218. package/dist/main/index.cjs.map +1 -1
  219. package/dist/main/index.d.cts +14 -2
  220. package/dist/main/index.d.ts +14 -2
  221. package/dist/main/index.js +16 -0
  222. package/dist/main/index.js.map +1 -1
  223. package/dist/middleware/middleware_resolver.cjs +22 -1
  224. package/dist/middleware/middleware_resolver.cjs.map +1 -1
  225. package/dist/middleware/middleware_resolver.d.cts +13 -1
  226. package/dist/middleware/middleware_resolver.d.ts +13 -1
  227. package/dist/middleware/middleware_resolver.js +22 -1
  228. package/dist/middleware/middleware_resolver.js.map +1 -1
  229. package/dist/navigation/automation_introspection.cjs +110 -0
  230. package/dist/navigation/automation_introspection.cjs.map +1 -0
  231. package/dist/navigation/automation_introspection.d.cts +60 -0
  232. package/dist/navigation/automation_introspection.d.ts +60 -0
  233. package/dist/navigation/automation_introspection.js +85 -0
  234. package/dist/navigation/automation_introspection.js.map +1 -0
  235. package/dist/navigation/index.cjs +10 -2
  236. package/dist/navigation/index.cjs.map +1 -1
  237. package/dist/navigation/index.d.cts +27 -1
  238. package/dist/navigation/index.d.ts +27 -1
  239. package/dist/navigation/index.js +6 -1
  240. package/dist/navigation/index.js.map +1 -1
  241. package/dist/{middleware/__fixtures__/middleware/auth.cjs → navigation/layout_preservation.cjs} +18 -20
  242. package/dist/navigation/layout_preservation.cjs.map +1 -0
  243. package/dist/navigation/layout_preservation.d.cts +2 -0
  244. package/dist/navigation/layout_preservation.d.ts +2 -0
  245. package/dist/navigation/layout_preservation.js +18 -0
  246. package/dist/navigation/layout_preservation.js.map +1 -0
  247. package/dist/parser/index.cjs +2 -0
  248. package/dist/parser/index.cjs.map +1 -1
  249. package/dist/parser/index.d.cts +1 -1
  250. package/dist/parser/index.d.ts +1 -1
  251. package/dist/parser/index.js +2 -1
  252. package/dist/parser/index.js.map +1 -1
  253. package/dist/parser/operations_parser.cjs +6 -0
  254. package/dist/parser/operations_parser.cjs.map +1 -1
  255. package/dist/parser/operations_parser.d.cts +9 -2
  256. package/dist/parser/operations_parser.d.ts +9 -2
  257. package/dist/parser/operations_parser.js +5 -0
  258. package/dist/parser/operations_parser.js.map +1 -1
  259. package/dist/parser/views_parser.cjs.map +1 -1
  260. package/dist/parser/views_parser.js.map +1 -1
  261. package/dist/router/index.d.cts +1 -0
  262. package/dist/router/index.d.ts +1 -0
  263. package/dist/router/wood_router.cjs +35 -3
  264. package/dist/router/wood_router.cjs.map +1 -1
  265. package/dist/router/wood_router.d.cts +15 -0
  266. package/dist/router/wood_router.d.ts +15 -0
  267. package/dist/router/wood_router.js +36 -4
  268. package/dist/router/wood_router.js.map +1 -1
  269. package/dist/runtime/get_container.cjs +9 -34
  270. package/dist/runtime/get_container.cjs.map +1 -1
  271. package/dist/runtime/get_container.d.cts +24 -4
  272. package/dist/runtime/get_container.d.ts +24 -4
  273. package/dist/runtime/get_container.js +8 -23
  274. package/dist/runtime/get_container.js.map +1 -1
  275. package/dist/runtime/index.cjs +9 -0
  276. package/dist/runtime/index.cjs.map +1 -1
  277. package/dist/runtime/index.d.cts +5 -2
  278. package/dist/runtime/index.d.ts +5 -2
  279. package/dist/runtime/index.js +10 -1
  280. package/dist/runtime/index.js.map +1 -1
  281. package/dist/runtime/renderer_config_extension.cjs +50 -0
  282. package/dist/runtime/renderer_config_extension.cjs.map +1 -0
  283. package/dist/runtime/renderer_config_extension.d.cts +19 -0
  284. package/dist/runtime/renderer_config_extension.d.ts +19 -0
  285. package/dist/runtime/renderer_config_extension.js +24 -0
  286. package/dist/runtime/renderer_config_extension.js.map +1 -0
  287. package/dist/runtime/renderer_log_batch_receiver.cjs +73 -0
  288. package/dist/runtime/renderer_log_batch_receiver.cjs.map +1 -0
  289. package/dist/runtime/renderer_log_batch_receiver.d.cts +29 -0
  290. package/dist/runtime/renderer_log_batch_receiver.d.ts +29 -0
  291. package/dist/runtime/renderer_log_batch_receiver.js +48 -0
  292. package/dist/runtime/renderer_log_batch_receiver.js.map +1 -0
  293. package/dist/runtime/renderer_trace_batch_receiver_registry.d.cts +1 -1
  294. package/dist/runtime/renderer_trace_batch_receiver_registry.d.ts +1 -1
  295. package/dist/runtime/runtime.cjs +14 -0
  296. package/dist/runtime/runtime.cjs.map +1 -1
  297. package/dist/runtime/runtime.d.cts +2 -1
  298. package/dist/runtime/runtime.d.ts +2 -1
  299. package/dist/runtime/runtime.js +14 -0
  300. package/dist/runtime/runtime.js.map +1 -1
  301. package/dist/stick/index.cjs.map +1 -1
  302. package/dist/stick/index.js.map +1 -1
  303. package/dist/testing/automation_assertions.cjs +417 -0
  304. package/dist/testing/automation_assertions.cjs.map +1 -0
  305. package/dist/testing/automation_assertions.d.cts +44 -0
  306. package/dist/testing/automation_assertions.d.ts +44 -0
  307. package/dist/testing/automation_assertions.js +385 -0
  308. package/dist/testing/automation_assertions.js.map +1 -0
  309. package/dist/testing/browser.cjs +130 -57
  310. package/dist/testing/browser.cjs.map +1 -1
  311. package/dist/testing/browser.d.cts +10 -4
  312. package/dist/testing/browser.d.ts +10 -4
  313. package/dist/testing/browser.js +132 -53
  314. package/dist/testing/browser.js.map +1 -1
  315. package/dist/testing/create_controller_harness.cjs +28 -8
  316. package/dist/testing/create_controller_harness.cjs.map +1 -1
  317. package/dist/testing/create_controller_harness.d.cts +18 -2
  318. package/dist/testing/create_controller_harness.d.ts +18 -2
  319. package/dist/testing/create_controller_harness.js +28 -8
  320. package/dist/testing/create_controller_harness.js.map +1 -1
  321. package/dist/testing/create_router_bridge.d.cts +1 -0
  322. package/dist/testing/create_router_bridge.d.ts +1 -0
  323. package/dist/testing/create_test_router.d.cts +1 -0
  324. package/dist/testing/create_test_router.d.ts +1 -0
  325. package/dist/testing/geometry.cjs +109 -0
  326. package/dist/testing/geometry.cjs.map +1 -0
  327. package/dist/testing/geometry.d.cts +45 -0
  328. package/dist/testing/geometry.d.ts +45 -0
  329. package/dist/testing/geometry.js +79 -0
  330. package/dist/testing/geometry.js.map +1 -0
  331. package/dist/testing/index.cjs +62 -2
  332. package/dist/testing/index.cjs.map +1 -1
  333. package/dist/testing/index.d.cts +23 -4
  334. package/dist/testing/index.d.ts +23 -4
  335. package/dist/testing/index.js +50 -2
  336. package/dist/testing/index.js.map +1 -1
  337. package/dist/{controller/__fixtures__/controllers/not_a_class.cjs → testing/test_wood.cjs} +15 -7
  338. package/dist/testing/test_wood.cjs.map +1 -0
  339. package/dist/testing/test_wood.d.cts +16 -0
  340. package/dist/testing/test_wood.d.ts +16 -0
  341. package/dist/testing/test_wood.js +12 -0
  342. package/dist/testing/test_wood.js.map +1 -0
  343. package/dist/testing/test_wood_config.cjs +272 -0
  344. package/dist/testing/test_wood_config.cjs.map +1 -0
  345. package/dist/testing/test_wood_config.d.cts +111 -0
  346. package/dist/testing/test_wood_config.d.ts +111 -0
  347. package/dist/testing/test_wood_config.js +247 -0
  348. package/dist/testing/test_wood_config.js.map +1 -0
  349. package/dist/testing/wood_config_source.cjs +146 -0
  350. package/dist/testing/wood_config_source.cjs.map +1 -0
  351. package/dist/testing/wood_config_source.d.cts +36 -0
  352. package/dist/testing/wood_config_source.d.ts +36 -0
  353. package/dist/testing/wood_config_source.js +112 -0
  354. package/dist/testing/wood_config_source.js.map +1 -0
  355. package/dist/testing/wood_env_renderer.cjs +210 -0
  356. package/dist/testing/wood_env_renderer.cjs.map +1 -0
  357. package/dist/testing/wood_env_renderer.d.cts +74 -0
  358. package/dist/testing/wood_env_renderer.d.ts +74 -0
  359. package/dist/testing/wood_env_renderer.js +188 -0
  360. package/dist/testing/wood_env_renderer.js.map +1 -0
  361. package/dist/testing/wood_test_selection.cjs +94 -0
  362. package/dist/testing/wood_test_selection.cjs.map +1 -0
  363. package/dist/testing/wood_test_selection.d.cts +39 -0
  364. package/dist/testing/wood_test_selection.d.ts +39 -0
  365. package/dist/testing/wood_test_selection.js +68 -0
  366. package/dist/testing/wood_test_selection.js.map +1 -0
  367. package/dist/trace-testing/index.d.cts +1 -2
  368. package/dist/trace-testing/index.d.ts +1 -2
  369. package/dist/trace-testing/trace_recorder.cjs +1 -1
  370. package/dist/trace-testing/trace_recorder.cjs.map +1 -1
  371. package/dist/trace-testing/trace_recorder.d.cts +1 -2
  372. package/dist/trace-testing/trace_recorder.d.ts +1 -2
  373. package/dist/trace-testing/trace_recorder.js +1 -1
  374. package/dist/trace-testing/trace_recorder.js.map +1 -1
  375. package/dist/trace-transport/index.d.cts +1 -1
  376. package/dist/trace-transport/index.d.ts +1 -1
  377. package/dist/{trace_hub-Cob54qRx.d.cts → trace_hub-Cpo_nVze.d.cts} +21 -1
  378. package/dist/{trace_hub-Cob54qRx.d.ts → trace_hub-Cpo_nVze.d.ts} +21 -1
  379. package/dist/tracing/index.cjs +9 -2
  380. package/dist/tracing/index.cjs.map +1 -1
  381. package/dist/tracing/index.d.cts +3 -2
  382. package/dist/tracing/index.d.ts +3 -2
  383. package/dist/tracing/index.js +7 -1
  384. package/dist/tracing/index.js.map +1 -1
  385. package/dist/tracing/renderer_trace_batch_host.d.cts +1 -1
  386. package/dist/tracing/renderer_trace_batch_host.d.ts +1 -1
  387. package/dist/tracing/renderer_trace_batch_transport.cjs +48 -6
  388. package/dist/tracing/renderer_trace_batch_transport.cjs.map +1 -1
  389. package/dist/tracing/renderer_trace_batch_transport.d.cts +17 -1
  390. package/dist/tracing/renderer_trace_batch_transport.d.ts +17 -1
  391. package/dist/tracing/renderer_trace_batch_transport.js +48 -6
  392. package/dist/tracing/renderer_trace_batch_transport.js.map +1 -1
  393. package/dist/tracing/trace_batch_adapter.cjs +110 -0
  394. package/dist/tracing/trace_batch_adapter.cjs.map +1 -0
  395. package/dist/tracing/trace_batch_adapter.d.cts +36 -0
  396. package/dist/tracing/trace_batch_adapter.d.ts +36 -0
  397. package/dist/tracing/trace_batch_adapter.js +86 -0
  398. package/dist/tracing/trace_batch_adapter.js.map +1 -0
  399. package/dist/tracing/trace_commit_writer.d.cts +1 -1
  400. package/dist/tracing/trace_commit_writer.d.ts +1 -1
  401. package/dist/tracing/trace_hub.cjs +87 -20
  402. package/dist/tracing/trace_hub.cjs.map +1 -1
  403. package/dist/tracing/trace_hub.d.cts +1 -1
  404. package/dist/tracing/trace_hub.d.ts +1 -1
  405. package/dist/tracing/trace_hub.js +85 -20
  406. package/dist/tracing/trace_hub.js.map +1 -1
  407. package/dist/tracing/trace_provider.cjs +21 -6
  408. package/dist/tracing/trace_provider.cjs.map +1 -1
  409. package/dist/tracing/trace_provider.d.cts +13 -4
  410. package/dist/tracing/trace_provider.d.ts +13 -4
  411. package/dist/tracing/trace_provider.js +22 -7
  412. package/dist/tracing/trace_provider.js.map +1 -1
  413. package/dist/tracing/types/wood_trace_batch.types.cjs.map +1 -1
  414. package/dist/tracing/types/wood_trace_batch.types.d.cts +15 -1
  415. package/dist/tracing/types/wood_trace_batch.types.d.ts +15 -1
  416. package/dist/tracing/types/wood_trace_sink.types.d.cts +1 -1
  417. package/dist/tracing/types/wood_trace_sink.types.d.ts +1 -1
  418. package/dist/tracing/wood_trace_batch_contract.cjs +2 -0
  419. package/dist/tracing/wood_trace_batch_contract.cjs.map +1 -1
  420. package/dist/tracing/wood_trace_batch_contract.d.cts +1 -1
  421. package/dist/tracing/wood_trace_batch_contract.d.ts +1 -1
  422. package/dist/tracing/wood_trace_batch_contract.js +2 -0
  423. package/dist/tracing/wood_trace_batch_contract.js.map +1 -1
  424. package/dist/transport/build_transport_bridge.cjs +4 -2
  425. package/dist/transport/build_transport_bridge.cjs.map +1 -1
  426. package/dist/transport/build_transport_bridge.d.cts +7 -1
  427. package/dist/transport/build_transport_bridge.d.ts +7 -1
  428. package/dist/transport/build_transport_bridge.js +2 -1
  429. package/dist/transport/build_transport_bridge.js.map +1 -1
  430. package/dist/transport/in_process_router_transport.d.cts +1 -0
  431. package/dist/transport/in_process_router_transport.d.ts +1 -0
  432. package/dist/transport/index.d.cts +1 -0
  433. package/dist/transport/index.d.ts +1 -0
  434. package/dist/types/config.cjs.map +1 -1
  435. package/dist/types/config.d.cts +47 -1
  436. package/dist/types/config.d.ts +47 -1
  437. package/dist/types/context.cjs +12 -0
  438. package/dist/types/context.cjs.map +1 -1
  439. package/dist/types/context.d.cts +27 -1
  440. package/dist/types/context.d.ts +27 -1
  441. package/dist/types/context.js +4 -0
  442. package/dist/types/context.js.map +1 -1
  443. package/dist/types/index.d.cts +2 -2
  444. package/dist/types/index.d.ts +2 -2
  445. package/dist/types/operations.cjs.map +1 -1
  446. package/dist/types/operations.d.cts +2 -0
  447. package/dist/types/operations.d.ts +2 -0
  448. package/docs/axe.md +706 -0
  449. package/package.json +19 -5
  450. package/src/components/NavigationShell.scopes.browser.test.ts +363 -0
  451. package/src/components/NavigationShell.svelte +126 -49
  452. package/dist/controller/__fixtures__/controllers/chat.cjs +0 -32
  453. package/dist/controller/__fixtures__/controllers/chat.cjs.map +0 -1
  454. package/dist/controller/__fixtures__/controllers/chat.d.cts +0 -11
  455. package/dist/controller/__fixtures__/controllers/chat.d.ts +0 -11
  456. package/dist/controller/__fixtures__/controllers/chat.js +0 -12
  457. package/dist/controller/__fixtures__/controllers/chat.js.map +0 -1
  458. package/dist/controller/__fixtures__/controllers/not_a_class.cjs.map +0 -1
  459. package/dist/controller/__fixtures__/controllers/not_a_class.d.cts +0 -3
  460. package/dist/controller/__fixtures__/controllers/not_a_class.d.ts +0 -3
  461. package/dist/controller/__fixtures__/controllers/not_a_class.js +0 -5
  462. package/dist/controller/__fixtures__/controllers/not_a_class.js.map +0 -1
  463. package/dist/controller/__fixtures__/controllers/settings.controller.cjs +0 -32
  464. package/dist/controller/__fixtures__/controllers/settings.controller.cjs.map +0 -1
  465. package/dist/controller/__fixtures__/controllers/settings.controller.d.cts +0 -12
  466. package/dist/controller/__fixtures__/controllers/settings.controller.d.ts +0 -12
  467. package/dist/controller/__fixtures__/controllers/settings.controller.js +0 -12
  468. package/dist/controller/__fixtures__/controllers/settings.controller.js.map +0 -1
  469. package/dist/controller/__fixtures__/controllers/test.cjs.map +0 -1
  470. package/dist/controller/__fixtures__/controllers/test.d.cts +0 -7
  471. package/dist/controller/__fixtures__/controllers/test.d.ts +0 -7
  472. package/dist/controller/__fixtures__/controllers/test.js +0 -9
  473. package/dist/controller/__fixtures__/controllers/test.js.map +0 -1
  474. package/dist/loader/__fixtures__/layouts/app.load.cjs.map +0 -1
  475. package/dist/loader/__fixtures__/layouts/app.load.d.cts +0 -5
  476. package/dist/loader/__fixtures__/layouts/app.load.d.ts +0 -5
  477. package/dist/loader/__fixtures__/layouts/app.load.js +0 -7
  478. package/dist/loader/__fixtures__/layouts/app.load.js.map +0 -1
  479. package/dist/loader/__fixtures__/views/test/page.load.cjs.map +0 -1
  480. package/dist/loader/__fixtures__/views/test/page.load.d.cts +0 -6
  481. package/dist/loader/__fixtures__/views/test/page.load.d.ts +0 -6
  482. package/dist/loader/__fixtures__/views/test/page.load.js +0 -7
  483. package/dist/loader/__fixtures__/views/test/page.load.js.map +0 -1
  484. package/dist/middleware/__fixtures__/middleware/auth.cjs.map +0 -1
  485. package/dist/middleware/__fixtures__/middleware/auth.d.cts +0 -6
  486. package/dist/middleware/__fixtures__/middleware/auth.d.ts +0 -6
  487. package/dist/middleware/__fixtures__/middleware/auth.js +0 -19
  488. package/dist/middleware/__fixtures__/middleware/auth.js.map +0 -1
  489. package/dist/middleware/__fixtures__/middleware/sequence.cjs.map +0 -1
  490. package/dist/middleware/__fixtures__/middleware/sequence.d.cts +0 -7
  491. package/dist/middleware/__fixtures__/middleware/sequence.d.ts +0 -7
  492. package/dist/middleware/__fixtures__/middleware/sequence.js +0 -21
  493. package/dist/middleware/__fixtures__/middleware/sequence.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/automation/scenario.ts"],"sourcesContent":["import { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Browser, ConsoleMessage, Page, Request } from 'playwright';\nimport type { WoodAutomationAction } from './actions.js';\nimport { executeAction } from './actions_executor.js';\nimport { automationError, automationOk, type WoodAutomationError, type WoodAutomationResult } from './errors.js';\nimport type { WoodConsoleEntry } from './observation.js';\nimport type { WoodActionReceipt } from './receipts.js';\nimport type { WoodScrollCommand, WoodScrollContainer } from './scrolling.js';\nimport { discoverTargets, selectTarget } from './target_registry.js';\nimport type { WoodWaitCondition } from './waits.js';\nimport { awaitCondition } from './waits_executor.js';\nimport type { WoodLocator } from './locator.js';\n\nconst EXPECT_TIMEOUT_MS = 2_000;\nconst ACTION_KINDS = [\n 'click',\n 'double_click',\n 'fill',\n 'type',\n 'press',\n 'select',\n 'toggle',\n 'scroll',\n 'back',\n 'forward',\n 'reload',\n 'wait',\n] as const;\nconst WAIT_KINDS = [\n 'route',\n 'url',\n 'target',\n 'visible',\n 'hidden',\n 'attached',\n 'detached',\n 'enabled',\n 'trace',\n 'scroll_edge',\n 'visual_stable',\n 'app_idle',\n] as const;\n\nexport interface WoodScenario {\n version: 1;\n target?: { windowId?: string };\n evidence?: {\n screenshot?: 'on-failure' | 'always' | 'off';\n console?: boolean;\n };\n steps: Array<{\n name?: string;\n action: WoodAutomationAction;\n wait?: WoodWaitCondition;\n expect?: WoodWaitCondition[];\n }>;\n}\n\nexport interface WoodScenarioStepReport {\n index: number;\n name?: string;\n startedAt: string;\n durationMs: number;\n receipt: WoodActionReceipt;\n evidence: string[];\n}\n\nexport interface WoodScenarioReport {\n startedAt: string;\n completedAt: string;\n durationMs: number;\n success: true;\n receipts: WoodActionReceipt[];\n steps: WoodScenarioStepReport[];\n evidence: string[];\n console: WoodConsoleEntry[];\n}\n\nexport type WoodScenarioEvent =\n | { kind: 'scenario_started'; startedAt: string; stepCount: number }\n | { kind: 'step_started'; stepIndex: number; stepName?: string; startedAt: string }\n | {\n kind: 'step_completed';\n stepIndex: number;\n stepName?: string;\n receipt: WoodActionReceipt;\n durationMs: number;\n evidence: string[];\n }\n | {\n kind: 'step_failed';\n stepIndex: number;\n stepName?: string;\n error: WoodAutomationError;\n durationMs: number;\n evidence: string[];\n }\n | {\n kind: 'scenario_completed';\n stepIndex?: number;\n stepName?: string;\n receipt?: WoodActionReceipt;\n error?: WoodAutomationError;\n startedAt: string;\n completedAt: string;\n durationMs: number;\n success: boolean;\n };\n\nexport interface WoodScenarioHooks {\n onEvent: (event: WoodScenarioEvent) => void;\n evidenceDir?: string;\n}\n\ntype Validation<T> = { ok: true; value: T } | { ok: false; message: string };\n\nfunction valid<T>(value: T): Validation<T> {\n return { ok: true, value };\n}\n\nfunction invalid<T = never>(message: string): Validation<T> {\n return { ok: false, message };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction requireRecord(value: unknown, at: string): Validation<Record<string, unknown>> {\n return isRecord(value) ? valid(value) : invalid(`${at} must be an object.`);\n}\n\nfunction requireString(value: unknown, at: string): Validation<string> {\n return typeof value === 'string' && value.length > 0\n ? valid(value)\n : invalid(`${at} must be a non-empty string.`);\n}\n\nfunction optionalBoolean(value: unknown, at: string): Validation<boolean | undefined> {\n return value === undefined || typeof value === 'boolean'\n ? valid(value)\n : invalid(`${at} must be a boolean when provided.`);\n}\n\nfunction optionalNumber(value: unknown, at: string): Validation<number | undefined> {\n return value === undefined || (typeof value === 'number' && Number.isFinite(value))\n ? valid(value)\n : invalid(`${at} must be a finite number when provided.`);\n}\n\nfunction stringRecord(value: unknown, at: string): Validation<Record<string, string> | undefined> {\n if (value === undefined) return valid(undefined);\n if (!isRecord(value)) return invalid(`${at} must be an object of string values.`);\n const result: Record<string, string> = {};\n for (const [key, item] of Object.entries(value)) {\n if (typeof item !== 'string') return invalid(`${at}.${key} must be a string.`);\n result[key] = item;\n }\n return valid(result);\n}\n\nfunction parseLocator(value: unknown, at: string): Validation<WoodLocator> {\n const object = requireRecord(value, at);\n if (!object.ok) return object;\n const kind = object.value.kind;\n if (kind === 'role') {\n const role = requireString(object.value.role, `${at}.role`);\n if (!role.ok) return role;\n if (object.value.name !== undefined && typeof object.value.name !== 'string') {\n return invalid(`${at}.name must be a string when provided.`);\n }\n const exact = optionalBoolean(object.value.exact, `${at}.exact`);\n if (!exact.ok) return exact;\n return valid({\n kind,\n role: role.value,\n ...(object.value.name !== undefined ? { name: object.value.name as string } : {}),\n ...(exact.value !== undefined ? { exact: exact.value } : {}),\n });\n }\n if (!['test_id', 'label', 'placeholder', 'text', 'css'].includes(String(kind))) {\n return invalid(`${at}.kind must be one of test_id, role, label, placeholder, text, css.`);\n }\n const text = requireString(object.value.value, `${at}.value`);\n if (!text.ok) return text;\n if (kind === 'css' || kind === 'test_id') return valid({ kind, value: text.value } as WoodLocator);\n const exact = optionalBoolean(object.value.exact, `${at}.exact`);\n if (!exact.ok) return exact;\n return valid({\n kind: kind as 'label' | 'placeholder' | 'text',\n value: text.value,\n ...(exact.value !== undefined ? { exact: exact.value } : {}),\n });\n}\n\nfunction parseContainer(value: unknown, at: string): Validation<WoodScrollContainer> {\n const object = requireRecord(value, at);\n if (!object.ok) return object;\n if (object.value.kind === 'viewport') return valid({ kind: 'viewport' });\n if (object.value.kind !== 'locator') {\n return invalid(`${at}.kind must be viewport or locator.`);\n }\n const target = parseLocator(object.value.target, `${at}.target`);\n return target.ok ? valid({ kind: 'locator', target: target.value }) : target;\n}\n\nfunction parseScroll(value: unknown, at: string): Validation<WoodScrollCommand> {\n const object = requireRecord(value, at);\n if (!object.ok) return object;\n const mode = object.value.mode;\n if (mode === 'into_view') {\n const target = parseLocator(object.value.target, `${at}.target`);\n if (!target.ok) return target;\n const block = object.value.block;\n if (block !== undefined && !['start', 'center', 'end', 'nearest'].includes(String(block))) {\n return invalid(`${at}.block must be start, center, end, or nearest.`);\n }\n return valid({\n mode,\n target: target.value,\n ...(block !== undefined ? { block: block as 'start' | 'center' | 'end' | 'nearest' } : {}),\n });\n }\n if (!['wheel', 'position', 'until'].includes(String(mode))) {\n return invalid(`${at}.mode must be wheel, position, into_view, or until.`);\n }\n const container = parseContainer(object.value.container, `${at}.container`);\n if (!container.ok) return container;\n if (mode === 'wheel') {\n const deltaX = optionalNumber(object.value.deltaX, `${at}.deltaX`);\n if (!deltaX.ok) return deltaX;\n const deltaY = optionalNumber(object.value.deltaY, `${at}.deltaY`);\n if (!deltaY.ok) return deltaY;\n return valid({\n mode,\n container: container.value,\n ...(deltaX.value !== undefined ? { deltaX: deltaX.value } : {}),\n ...(deltaY.value !== undefined ? { deltaY: deltaY.value } : {}),\n });\n }\n if (mode === 'position') {\n const x = optionalNumber(object.value.x, `${at}.x`);\n if (!x.ok) return x;\n const y = optionalNumber(object.value.y, `${at}.y`);\n if (!y.ok) return y;\n const edge = object.value.edge;\n if (edge !== undefined && !['top', 'bottom', 'left', 'right'].includes(String(edge))) {\n return invalid(`${at}.edge must be top, bottom, left, or right.`);\n }\n return valid({\n mode,\n container: container.value,\n ...(x.value !== undefined ? { x: x.value } : {}),\n ...(y.value !== undefined ? { y: y.value } : {}),\n ...(edge !== undefined ? { edge: edge as 'top' | 'bottom' | 'left' | 'right' } : {}),\n });\n }\n const target = parseLocator(object.value.target, `${at}.target`);\n if (!target.ok) return target;\n const direction = object.value.direction;\n if (!['up', 'down', 'left', 'right'].includes(String(direction))) {\n return invalid(`${at}.direction must be up, down, left, or right.`);\n }\n const stepPx = object.value.stepPx;\n if (typeof stepPx !== 'number' || !Number.isFinite(stepPx) || stepPx <= 0) {\n return invalid(`${at}.stepPx must be a positive number.`);\n }\n const maxSteps = object.value.maxSteps;\n if (!Number.isInteger(maxSteps) || (maxSteps as number) <= 0) {\n return invalid(`${at}.maxSteps must be a positive integer.`);\n }\n return valid({\n mode: 'until',\n container: container.value,\n target: target.value,\n direction: direction as 'up' | 'down' | 'left' | 'right',\n stepPx,\n maxSteps: maxSteps as number,\n });\n}\n\nfunction parseWait(value: unknown, at: string): Validation<WoodWaitCondition> {\n const object = requireRecord(value, at);\n if (!object.ok) return object;\n const kind = object.value.kind;\n if (!WAIT_KINDS.includes(kind as (typeof WAIT_KINDS)[number])) {\n return invalid(`${at}.kind must be one of ${WAIT_KINDS.join(', ')}.`);\n }\n if (kind === 'route') {\n const page = requireString(object.value.page, `${at}.page`);\n if (!page.ok) return page;\n const params = stringRecord(object.value.params, `${at}.params`);\n if (!params.ok) return params;\n const query = stringRecord(object.value.query, `${at}.query`);\n if (!query.ok) return query;\n return valid({\n kind,\n page: page.value,\n ...(params.value ? { params: params.value } : {}),\n ...(query.value ? { query: query.value } : {}),\n });\n }\n if (kind === 'url') {\n const text = requireString(object.value.value, `${at}.value`);\n if (!text.ok) return text;\n const match = object.value.match;\n if (match !== undefined && !['exact', 'glob', 'regex'].includes(String(match))) {\n return invalid(`${at}.match must be exact, glob, or regex.`);\n }\n return valid({\n kind,\n value: text.value,\n ...(match !== undefined ? { match: match as 'exact' | 'glob' | 'regex' } : {}),\n });\n }\n if (kind === 'target') {\n const windowId = requireString(object.value.windowId, `${at}.windowId`);\n if (!windowId.ok) return windowId;\n const state = object.value.state;\n if (!['present', 'active', 'closed'].includes(String(state))) {\n return invalid(`${at}.state must be present, active, or closed.`);\n }\n return valid({ kind, windowId: windowId.value, state: state as 'present' | 'active' | 'closed' });\n }\n if (['visible', 'hidden', 'attached', 'detached', 'enabled'].includes(String(kind))) {\n const target = parseLocator(object.value.target, `${at}.target`);\n return target.ok\n ? valid({ kind: kind as 'visible' | 'hidden' | 'attached' | 'detached' | 'enabled', target: target.value })\n : target;\n }\n if (kind === 'trace') {\n const type = requireString(object.value.type, `${at}.type`);\n if (!type.ok) return type;\n if (object.value.source !== undefined && typeof object.value.source !== 'string') {\n return invalid(`${at}.source must be a string when provided.`);\n }\n if (object.value.count !== undefined && (!Number.isInteger(object.value.count) || (object.value.count as number) < 1)) {\n return invalid(`${at}.count must be a positive integer when provided.`);\n }\n return valid({\n kind,\n type: type.value,\n ...(object.value.source !== undefined ? { source: object.value.source as string } : {}),\n ...(object.value.count !== undefined ? { count: object.value.count as number } : {}),\n });\n }\n if (kind === 'scroll_edge') {\n const container = parseContainer(object.value.container, `${at}.container`);\n if (!container.ok) return container;\n const edge = object.value.edge;\n if (!['top', 'bottom', 'left', 'right'].includes(String(edge))) {\n return invalid(`${at}.edge must be top, bottom, left, or right.`);\n }\n return valid({ kind, container: container.value, edge: edge as 'top' | 'bottom' | 'left' | 'right' });\n }\n if (kind === 'visual_stable') {\n const target = object.value.target === undefined\n ? valid<WoodLocator | undefined>(undefined)\n : parseLocator(object.value.target, `${at}.target`);\n if (!target.ok) return target;\n if (object.value.frames !== undefined && (!Number.isInteger(object.value.frames) || (object.value.frames as number) < 1)) {\n return invalid(`${at}.frames must be a positive integer when provided.`);\n }\n return valid({\n kind,\n ...(target.value ? { target: target.value } : {}),\n ...(object.value.frames !== undefined ? { frames: object.value.frames as number } : {}),\n });\n }\n return valid({ kind: 'app_idle' });\n}\n\nfunction parseAction(value: unknown, at: string): Validation<WoodAutomationAction> {\n const object = requireRecord(value, at);\n if (!object.ok) return object;\n const kind = object.value.kind;\n if (!ACTION_KINDS.includes(kind as (typeof ACTION_KINDS)[number])) {\n return invalid(`${at}.kind must be one of ${ACTION_KINDS.join(', ')}.`);\n }\n if (kind === 'back' || kind === 'forward' || kind === 'reload') return valid({ kind });\n if (kind === 'scroll') {\n const command = parseScroll(object.value.command, `${at}.command`);\n return command.ok ? valid({ kind, command: command.value }) : command;\n }\n if (kind === 'wait') {\n const condition = parseWait(object.value.condition, `${at}.condition`);\n return condition.ok ? valid({ kind, condition: condition.value }) : condition;\n }\n if (kind === 'press') {\n let target: Validation<WoodLocator | undefined> = valid(undefined);\n if (object.value.target !== undefined) target = parseLocator(object.value.target, `${at}.target`);\n if (!target.ok) return target;\n if (!Array.isArray(object.value.keys) || object.value.keys.length === 0) {\n return invalid(`${at}.keys must be a non-empty array of strings.`);\n }\n for (let index = 0; index < object.value.keys.length; index += 1) {\n if (typeof object.value.keys[index] !== 'string' || object.value.keys[index].length === 0) {\n return invalid(`${at}.keys[${index}] must be a non-empty string.`);\n }\n }\n return valid({\n kind,\n ...(target.value ? { target: target.value } : {}),\n keys: object.value.keys as string[],\n });\n }\n const target = parseLocator(object.value.target, `${at}.target`);\n if (!target.ok) return target;\n if (kind === 'click') {\n const button = object.value.button;\n if (button !== undefined && button !== 'left' && button !== 'middle') {\n return invalid(`${at}.button must be left or middle when provided.`);\n }\n return valid({ kind, target: target.value, ...(button ? { button } : {}) });\n }\n if (kind === 'double_click') return valid({ kind, target: target.value });\n if (kind === 'fill' || kind === 'type') {\n if (typeof object.value.value !== 'string') return invalid(`${at}.value must be a string.`);\n if (kind === 'type') {\n const delayMs = optionalNumber(object.value.delayMs, `${at}.delayMs`);\n if (!delayMs.ok) return delayMs;\n return valid({\n kind,\n target: target.value,\n value: object.value.value,\n ...(delayMs.value !== undefined ? { delayMs: delayMs.value } : {}),\n });\n }\n return valid({ kind, target: target.value, value: object.value.value });\n }\n if (kind === 'select') {\n if (typeof object.value.option !== 'string') return invalid(`${at}.option must be a string.`);\n return valid({ kind, target: target.value, option: object.value.option });\n }\n if (typeof object.value.checked !== 'boolean') return invalid(`${at}.checked must be a boolean.`);\n return valid({ kind: 'toggle', target: target.value, checked: object.value.checked });\n}\n\nexport function parseScenario(json: unknown): WoodAutomationResult<WoodScenario> {\n const root = requireRecord(json, '$');\n if (!root.ok) return automationError('ACTION_FAILED', root.message);\n if (root.value.version !== 1) {\n return automationError('UNSUPPORTED', '$.version must equal 1.');\n }\n if (!Array.isArray(root.value.steps)) {\n return automationError('ACTION_FAILED', '$.steps must be an array.');\n }\n if (root.value.steps.length === 0) {\n return automationError('ACTION_FAILED', '$.steps must contain at least one step.');\n }\n\n let target: WoodScenario['target'];\n if (root.value.target !== undefined) {\n const object = requireRecord(root.value.target, '$.target');\n if (!object.ok) return automationError('ACTION_FAILED', object.message);\n if (object.value.windowId !== undefined && (typeof object.value.windowId !== 'string' || object.value.windowId.length === 0)) {\n return automationError('ACTION_FAILED', '$.target.windowId must be a non-empty string when provided.');\n }\n target = object.value.windowId === undefined ? {} : { windowId: object.value.windowId as string };\n }\n\n let evidence: WoodScenario['evidence'];\n if (root.value.evidence !== undefined) {\n const object = requireRecord(root.value.evidence, '$.evidence');\n if (!object.ok) return automationError('ACTION_FAILED', object.message);\n const screenshot = object.value.screenshot;\n if (screenshot !== undefined && !['on-failure', 'always', 'off'].includes(String(screenshot))) {\n return automationError('ACTION_FAILED', '$.evidence.screenshot must be on-failure, always, or off.');\n }\n const consoleCapture = optionalBoolean(object.value.console, '$.evidence.console');\n if (!consoleCapture.ok) return automationError('ACTION_FAILED', consoleCapture.message);\n evidence = {\n ...(screenshot !== undefined ? { screenshot: screenshot as 'on-failure' | 'always' | 'off' } : {}),\n ...(consoleCapture.value !== undefined ? { console: consoleCapture.value } : {}),\n };\n }\n\n const steps: WoodScenario['steps'] = [];\n for (let index = 0; index < root.value.steps.length; index += 1) {\n const at = `$.steps[${index}]`;\n const step = requireRecord(root.value.steps[index], at);\n if (!step.ok) return automationError('ACTION_FAILED', step.message);\n if (step.value.name !== undefined && (typeof step.value.name !== 'string' || step.value.name.length === 0)) {\n return automationError('ACTION_FAILED', `${at}.name must be a non-empty string when provided.`);\n }\n const action = parseAction(step.value.action, `${at}.action`);\n if (!action.ok) return automationError('ACTION_FAILED', action.message);\n const wait = step.value.wait === undefined\n ? valid<WoodWaitCondition | undefined>(undefined)\n : parseWait(step.value.wait, `${at}.wait`);\n if (!wait.ok) return automationError('ACTION_FAILED', wait.message);\n if (step.value.expect !== undefined && !Array.isArray(step.value.expect)) {\n return automationError('ACTION_FAILED', `${at}.expect must be an array when provided.`);\n }\n const expect: WoodWaitCondition[] = [];\n for (let expectIndex = 0; expectIndex < (step.value.expect as unknown[] | undefined)?.length!; expectIndex += 1) {\n const condition = parseWait(\n (step.value.expect as unknown[])[expectIndex],\n `${at}.expect[${expectIndex}]`,\n );\n if (!condition.ok) return automationError('ACTION_FAILED', condition.message);\n expect.push(condition.value);\n }\n steps.push({\n ...(step.value.name !== undefined ? { name: step.value.name as string } : {}),\n action: action.value,\n ...(wait.value ? { wait: wait.value } : {}),\n ...(step.value.expect !== undefined ? { expect } : {}),\n });\n }\n\n return automationOk({\n version: 1,\n ...(target ? { target } : {}),\n ...(evidence ? { evidence } : {}),\n steps,\n });\n}\n\nfunction safeEvidenceName(stepIndex: number, stepName: string | undefined, suffix: string): string {\n const name = (stepName ?? 'step').replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^-+|-+$/g, '') || 'step';\n return `${String(stepIndex + 1).padStart(3, '0')}-${name}-${suffix}.png`;\n}\n\nasync function captureScreenshot(\n page: Page,\n hooks: WoodScenarioHooks,\n stepIndex: number,\n stepName: string | undefined,\n suffix: string,\n): Promise<string | undefined> {\n if (!hooks.evidenceDir) return undefined;\n await mkdir(hooks.evidenceDir, { recursive: true });\n const outputPath = path.join(hooks.evidenceDir, safeEvidenceName(stepIndex, stepName, suffix));\n await page.screenshot({ path: outputPath });\n return outputPath;\n}\n\nfunction attachConsoleCapture(page: Page, entries: WoodConsoleEntry[]): () => void {\n const add = (type: WoodConsoleEntry['type'], message: string) => {\n entries.push({ type, message, occurredAt: new Date().toISOString() });\n };\n const onConsole = (message: ConsoleMessage) => {\n if (message.type() === 'error') add('console_error', message.text());\n };\n const onPageError = (error: Error) => add('page_error', error.message);\n const onRequestFailed = (request: Request) => {\n add('request_failed', `${request.method()} ${request.url()}: ${request.failure()?.errorText ?? 'request failed'}`);\n };\n page.on('console', onConsole);\n page.on('pageerror', onPageError);\n page.on('requestfailed', onRequestFailed);\n return () => {\n page.off('console', onConsole);\n page.off('pageerror', onPageError);\n page.off('requestfailed', onRequestFailed);\n };\n}\n\nfunction emit(hooks: WoodScenarioHooks, event: WoodScenarioEvent): void {\n hooks.onEvent(event);\n}\n\nfunction classifyThrown(error: unknown, message: string): WoodAutomationError {\n return {\n code: 'ACTION_FAILED',\n message,\n details: { cause: error instanceof Error ? error.message : String(error) },\n };\n}\n\nexport async function runScenarioOnPage(\n page: Page,\n scenario: WoodScenario,\n hooks: WoodScenarioHooks,\n): Promise<WoodAutomationResult<WoodScenarioReport>> {\n const started = new Date();\n const receipts: WoodActionReceipt[] = [];\n const steps: WoodScenarioStepReport[] = [];\n const evidence: string[] = [];\n const consoleEntries: WoodConsoleEntry[] = [];\n const detach = scenario.evidence?.console === false ? () => undefined : attachConsoleCapture(page, consoleEntries);\n emit(hooks, { kind: 'scenario_started', startedAt: started.toISOString(), stepCount: scenario.steps.length });\n\n try {\n for (let index = 0; index < scenario.steps.length; index += 1) {\n const step = scenario.steps[index];\n const stepStarted = new Date();\n const stepEvidence: string[] = [];\n let receipt: WoodActionReceipt | undefined;\n emit(hooks, {\n kind: 'step_started',\n stepIndex: index,\n ...(step.name ? { stepName: step.name } : {}),\n startedAt: stepStarted.toISOString(),\n });\n\n let failure: WoodAutomationError | undefined;\n const action = await executeAction(page, step.action, { wait: step.wait });\n if (!action.ok) {\n failure = action.error;\n } else {\n receipt = action.value;\n for (let expectIndex = 0; expectIndex < (step.expect?.length ?? 0); expectIndex += 1) {\n const condition = step.expect![expectIndex];\n const result = await awaitCondition(page, condition, { timeoutMs: EXPECT_TIMEOUT_MS });\n if (!result.ok) {\n failure = {\n ...result.error,\n message: `Step expectation ${expectIndex + 1} (${condition.kind}) failed: ${result.error.message}`,\n details: {\n ...result.error.details,\n condition,\n expectIndex,\n },\n };\n break;\n }\n }\n }\n\n if (failure) {\n if (scenario.evidence?.screenshot !== 'off') {\n try {\n const screenshot = await captureScreenshot(page, hooks, index, step.name, 'failure');\n if (screenshot) {\n stepEvidence.push(screenshot);\n evidence.push(screenshot);\n }\n } catch (error) {\n failure = {\n ...failure,\n details: {\n ...failure.details,\n screenshotError: error instanceof Error ? error.message : String(error),\n },\n };\n }\n }\n const durationMs = Date.now() - stepStarted.getTime();\n emit(hooks, {\n kind: 'step_failed',\n stepIndex: index,\n ...(step.name ? { stepName: step.name } : {}),\n error: failure,\n durationMs,\n evidence: stepEvidence,\n });\n const completed = new Date();\n emit(hooks, {\n kind: 'scenario_completed',\n stepIndex: index,\n ...(step.name ? { stepName: step.name } : {}),\n ...(receipt ? { receipt } : {}),\n error: failure,\n startedAt: started.toISOString(),\n completedAt: completed.toISOString(),\n durationMs: completed.getTime() - started.getTime(),\n success: false,\n });\n return automationError(failure.code, failure.message, {\n requiredAction: failure.requiredAction,\n details: {\n ...failure.details,\n stepIndex: index,\n ...(step.name ? { stepName: step.name } : {}),\n receipts,\n steps,\n evidence,\n console: consoleEntries,\n },\n });\n }\n\n if (scenario.evidence?.screenshot === 'always') {\n try {\n const screenshot = await captureScreenshot(page, hooks, index, step.name, 'completed');\n if (screenshot) {\n stepEvidence.push(screenshot);\n evidence.push(screenshot);\n }\n } catch (error) {\n const screenshotFailure = classifyThrown(error, 'Scenario evidence screenshot failed.');\n emit(hooks, {\n kind: 'step_failed',\n stepIndex: index,\n ...(step.name ? { stepName: step.name } : {}),\n error: screenshotFailure,\n durationMs: Date.now() - stepStarted.getTime(),\n evidence: stepEvidence,\n });\n const completed = new Date();\n emit(hooks, {\n kind: 'scenario_completed',\n stepIndex: index,\n ...(step.name ? { stepName: step.name } : {}),\n receipt,\n error: screenshotFailure,\n startedAt: started.toISOString(),\n completedAt: completed.toISOString(),\n durationMs: completed.getTime() - started.getTime(),\n success: false,\n });\n return automationError(screenshotFailure.code, screenshotFailure.message, {\n details: {\n ...screenshotFailure.details,\n stepIndex: index,\n receipts,\n steps,\n evidence,\n console: consoleEntries,\n },\n });\n }\n }\n\n const durationMs = Date.now() - stepStarted.getTime();\n receipts.push(receipt!);\n const stepReport: WoodScenarioStepReport = {\n index,\n ...(step.name ? { name: step.name } : {}),\n startedAt: stepStarted.toISOString(),\n durationMs,\n receipt: receipt!,\n evidence: stepEvidence,\n };\n steps.push(stepReport);\n emit(hooks, {\n kind: 'step_completed',\n stepIndex: index,\n ...(step.name ? { stepName: step.name } : {}),\n receipt: receipt!,\n durationMs,\n evidence: stepEvidence,\n });\n }\n\n const completed = new Date();\n const report: WoodScenarioReport = {\n startedAt: started.toISOString(),\n completedAt: completed.toISOString(),\n durationMs: completed.getTime() - started.getTime(),\n success: true,\n receipts,\n steps,\n evidence,\n console: consoleEntries,\n };\n const lastStep = scenario.steps.at(-1);\n emit(hooks, {\n kind: 'scenario_completed',\n ...(lastStep\n ? {\n stepIndex: scenario.steps.length - 1,\n ...(lastStep.name ? { stepName: lastStep.name } : {}),\n receipt: receipts.at(-1),\n }\n : {}),\n startedAt: report.startedAt,\n completedAt: report.completedAt,\n durationMs: report.durationMs,\n success: true,\n });\n return automationOk(report);\n } catch (error) {\n const failure = classifyThrown(error, 'Scenario runner failed unexpectedly.');\n const completed = new Date();\n emit(hooks, {\n kind: 'scenario_completed',\n error: failure,\n startedAt: started.toISOString(),\n completedAt: completed.toISOString(),\n durationMs: completed.getTime() - started.getTime(),\n success: false,\n });\n return automationError(failure.code, failure.message, {\n details: { ...failure.details, receipts, steps, evidence, console: consoleEntries },\n });\n } finally {\n detach();\n }\n}\n\nexport async function runScenario(\n connection: { browser: Browser },\n scenario: WoodScenario,\n hooks: WoodScenarioHooks,\n): Promise<WoodAutomationResult<WoodScenarioReport>> {\n const entries = await discoverTargets(connection.browser);\n const selected = selectTarget(entries, scenario.target?.windowId);\n if (!selected.ok) return selected;\n return runScenarioOnPage(selected.value.page, scenario, hooks);\n}\n"],"mappings":"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","names":["exact","target","durationMs","completed"]}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var scrolling_exports = {};
16
+ module.exports = __toCommonJS(scrolling_exports);
17
+ //# sourceMappingURL=scrolling.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/automation/scrolling.ts"],"sourcesContent":["/**\n * Scrolling contract (frozen — Axe.md \"Scrolling contract\").\n * Type surface only in WP-00/01; execution lands in AXE-WP-03.\n */\n\nimport type { WoodLocator } from './locator.cjs';\n\nexport type WoodScrollContainer =\n | { kind: 'viewport' }\n | { kind: 'locator'; target: WoodLocator };\n\nexport type WoodScrollCommand =\n | {\n mode: 'wheel';\n container: WoodScrollContainer;\n deltaX?: number;\n deltaY?: number;\n }\n | {\n mode: 'position';\n container: WoodScrollContainer;\n x?: number;\n y?: number;\n edge?: 'top' | 'bottom' | 'left' | 'right';\n }\n | {\n mode: 'into_view';\n target: WoodLocator;\n block?: 'start' | 'center' | 'end' | 'nearest';\n }\n | {\n mode: 'until';\n container: WoodScrollContainer;\n target: WoodLocator;\n direction: 'up' | 'down' | 'left' | 'right';\n stepPx: number;\n maxSteps: number;\n };\n\n/** Per-step scroll metrics recorded in receipts. */\nexport interface WoodScrollMetrics {\n scrollTop: number;\n scrollLeft: number;\n scrollHeight: number;\n scrollWidth: number;\n clientHeight: number;\n clientWidth: number;\n atEdge: Array<'top' | 'bottom' | 'left' | 'right'>;\n moved: boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1,51 @@
1
+ import { WoodLocator } from './locator.cjs';
2
+ import 'playwright';
3
+ import './errors.cjs';
4
+
5
+ /**
6
+ * Scrolling contract (frozen — Axe.md "Scrolling contract").
7
+ * Type surface only in WP-00/01; execution lands in AXE-WP-03.
8
+ */
9
+
10
+ type WoodScrollContainer = {
11
+ kind: 'viewport';
12
+ } | {
13
+ kind: 'locator';
14
+ target: WoodLocator;
15
+ };
16
+ type WoodScrollCommand = {
17
+ mode: 'wheel';
18
+ container: WoodScrollContainer;
19
+ deltaX?: number;
20
+ deltaY?: number;
21
+ } | {
22
+ mode: 'position';
23
+ container: WoodScrollContainer;
24
+ x?: number;
25
+ y?: number;
26
+ edge?: 'top' | 'bottom' | 'left' | 'right';
27
+ } | {
28
+ mode: 'into_view';
29
+ target: WoodLocator;
30
+ block?: 'start' | 'center' | 'end' | 'nearest';
31
+ } | {
32
+ mode: 'until';
33
+ container: WoodScrollContainer;
34
+ target: WoodLocator;
35
+ direction: 'up' | 'down' | 'left' | 'right';
36
+ stepPx: number;
37
+ maxSteps: number;
38
+ };
39
+ /** Per-step scroll metrics recorded in receipts. */
40
+ interface WoodScrollMetrics {
41
+ scrollTop: number;
42
+ scrollLeft: number;
43
+ scrollHeight: number;
44
+ scrollWidth: number;
45
+ clientHeight: number;
46
+ clientWidth: number;
47
+ atEdge: Array<'top' | 'bottom' | 'left' | 'right'>;
48
+ moved: boolean;
49
+ }
50
+
51
+ export type { WoodScrollCommand, WoodScrollContainer, WoodScrollMetrics };
@@ -0,0 +1,51 @@
1
+ import { WoodLocator } from './locator.js';
2
+ import 'playwright';
3
+ import './errors.js';
4
+
5
+ /**
6
+ * Scrolling contract (frozen — Axe.md "Scrolling contract").
7
+ * Type surface only in WP-00/01; execution lands in AXE-WP-03.
8
+ */
9
+
10
+ type WoodScrollContainer = {
11
+ kind: 'viewport';
12
+ } | {
13
+ kind: 'locator';
14
+ target: WoodLocator;
15
+ };
16
+ type WoodScrollCommand = {
17
+ mode: 'wheel';
18
+ container: WoodScrollContainer;
19
+ deltaX?: number;
20
+ deltaY?: number;
21
+ } | {
22
+ mode: 'position';
23
+ container: WoodScrollContainer;
24
+ x?: number;
25
+ y?: number;
26
+ edge?: 'top' | 'bottom' | 'left' | 'right';
27
+ } | {
28
+ mode: 'into_view';
29
+ target: WoodLocator;
30
+ block?: 'start' | 'center' | 'end' | 'nearest';
31
+ } | {
32
+ mode: 'until';
33
+ container: WoodScrollContainer;
34
+ target: WoodLocator;
35
+ direction: 'up' | 'down' | 'left' | 'right';
36
+ stepPx: number;
37
+ maxSteps: number;
38
+ };
39
+ /** Per-step scroll metrics recorded in receipts. */
40
+ interface WoodScrollMetrics {
41
+ scrollTop: number;
42
+ scrollLeft: number;
43
+ scrollHeight: number;
44
+ scrollWidth: number;
45
+ clientHeight: number;
46
+ clientWidth: number;
47
+ atEdge: Array<'top' | 'bottom' | 'left' | 'right'>;
48
+ moved: boolean;
49
+ }
50
+
51
+ export type { WoodScrollCommand, WoodScrollContainer, WoodScrollMetrics };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=scrolling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var scrolling_executor_exports = {};
20
+ __export(scrolling_executor_exports, {
21
+ executeScroll: () => executeScroll,
22
+ hasNoProgress: () => hasNoProgress
23
+ });
24
+ module.exports = __toCommonJS(scrolling_executor_exports);
25
+ var import_errors = require("./errors.cjs");
26
+ var import_locator = require("./locator.cjs");
27
+ async function metrics(page, container, before) {
28
+ const element = container.kind === "locator" ? await (0, import_locator.toPlaywrightLocator)(page, container.target).elementHandle() : null;
29
+ return page.evaluate(({ element: element2, prior }) => {
30
+ const node = element2 ?? document.scrollingElement ?? document.documentElement;
31
+ const atEdge = [];
32
+ if (node.scrollTop <= 0) atEdge.push("top");
33
+ if (node.scrollTop + node.clientHeight >= node.scrollHeight - 1) atEdge.push("bottom");
34
+ if (node.scrollLeft <= 0) atEdge.push("left");
35
+ if (node.scrollLeft + node.clientWidth >= node.scrollWidth - 1) atEdge.push("right");
36
+ return { scrollTop: node.scrollTop, scrollLeft: node.scrollLeft, scrollHeight: node.scrollHeight, scrollWidth: node.scrollWidth, clientHeight: node.clientHeight, clientWidth: node.clientWidth, atEdge, moved: !!prior && (prior.scrollTop !== node.scrollTop || prior.scrollLeft !== node.scrollLeft) };
37
+ }, { element, prior: before });
38
+ }
39
+ function hasNoProgress(recent) {
40
+ return recent.length >= 3 && recent.slice(-3).every((value, index, all) => index === 0 || value.scrollTop === all[0].scrollTop && value.scrollLeft === all[0].scrollLeft);
41
+ }
42
+ async function isTargetReached(page, container, target) {
43
+ const locator = (0, import_locator.toPlaywrightLocator)(page, target);
44
+ if (!await locator.isVisible()) return false;
45
+ const targetElement = await locator.elementHandle();
46
+ const containerElement = container.kind === "locator" ? await (0, import_locator.toPlaywrightLocator)(page, container.target).elementHandle() : null;
47
+ return page.evaluate(({ targetElement: targetElement2, containerElement: containerElement2 }) => {
48
+ const targetRect = targetElement2.getBoundingClientRect();
49
+ const containerRect = containerElement2 ? containerElement2.getBoundingClientRect() : { top: 0, right: innerWidth, bottom: innerHeight, left: 0 };
50
+ return targetRect.bottom > containerRect.top && targetRect.top < containerRect.bottom && targetRect.right > containerRect.left && targetRect.left < containerRect.right;
51
+ }, { targetElement, containerElement });
52
+ }
53
+ async function executeScroll(page, command) {
54
+ const container = command.mode === "into_view" ? { kind: "viewport" } : command.container;
55
+ try {
56
+ const before = await metrics(page, container);
57
+ let steps = 1;
58
+ if (command.mode === "wheel") {
59
+ if (command.container.kind === "locator") {
60
+ const box = await (0, import_locator.toPlaywrightLocator)(page, command.container.target).boundingBox();
61
+ if (!box) throw new Error("Scroll container is not visible.");
62
+ await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
63
+ } else {
64
+ const viewport = page.viewportSize();
65
+ if (viewport) await page.mouse.move(viewport.width / 2, viewport.height / 2);
66
+ }
67
+ await page.mouse.wheel(command.deltaX ?? 0, command.deltaY ?? 0);
68
+ } else if (command.mode === "position") {
69
+ const element = command.container.kind === "locator" ? await (0, import_locator.toPlaywrightLocator)(page, command.container.target).elementHandle() : null;
70
+ await page.evaluate(({ element: element2, command: command2 }) => {
71
+ const node = element2 ?? document.scrollingElement ?? document.documentElement;
72
+ let x = command2.x ?? node.scrollLeft, y = command2.y ?? node.scrollTop;
73
+ if (command2.edge === "top") y = 0;
74
+ else if (command2.edge === "bottom") y = node.scrollHeight;
75
+ else if (command2.edge === "left") x = 0;
76
+ else if (command2.edge === "right") x = node.scrollWidth;
77
+ node.scrollTo(x, y);
78
+ }, { element, command });
79
+ } else if (command.mode === "into_view") {
80
+ const locator = (0, import_locator.toPlaywrightLocator)(page, command.target);
81
+ if (!command.block) await locator.scrollIntoViewIfNeeded();
82
+ else await locator.evaluate((node, block) => node.scrollIntoView({ block, inline: "nearest" }), command.block);
83
+ } else {
84
+ const history = [before];
85
+ steps = 0;
86
+ while (steps < command.maxSteps && !await isTargetReached(page, command.container, command.target)) {
87
+ const element = command.container.kind === "locator" ? await (0, import_locator.toPlaywrightLocator)(page, command.container.target).elementHandle() : null;
88
+ await page.evaluate(({ element: element2, direction, amount }) => {
89
+ const node = element2 ?? document.scrollingElement ?? document.documentElement;
90
+ node.scrollBy(direction === "left" ? -amount : direction === "right" ? amount : 0, direction === "up" ? -amount : direction === "down" ? amount : 0);
91
+ }, { element, direction: command.direction, amount: command.stepPx });
92
+ steps++;
93
+ history.push(await metrics(page, command.container, history.at(-1)));
94
+ if (hasNoProgress(history)) return (0, import_errors.automationError)("ACTION_FAILED", "Scroll made no progress for two consecutive steps.", { details: { metrics: history, steps } });
95
+ }
96
+ if (!await isTargetReached(page, command.container, command.target)) return (0, import_errors.automationError)("ACTION_FAILED", "Scroll target was not visible within maxSteps.", { details: { metrics: history, steps, maxSteps: command.maxSteps } });
97
+ }
98
+ await page.evaluate(() => new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))));
99
+ return (0, import_errors.automationOk)({ before, after: await metrics(page, container, before), steps });
100
+ } catch (error) {
101
+ return (0, import_errors.automationError)("ACTION_FAILED", "Scroll failed.", { details: { cause: error instanceof Error ? error.message : String(error) } });
102
+ }
103
+ }
104
+ // Annotate the CommonJS export names for ESM import in node:
105
+ 0 && (module.exports = {
106
+ executeScroll,
107
+ hasNoProgress
108
+ });
109
+ //# sourceMappingURL=scrolling_executor.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/automation/scrolling_executor.ts"],"sourcesContent":["import type { Page } from 'playwright';\nimport { automationError, automationOk, type WoodAutomationResult } from './errors.cjs';\nimport { toPlaywrightLocator } from './locator.cjs';\nimport type { WoodScrollCommand, WoodScrollContainer, WoodScrollMetrics } from './scrolling.cjs';\n\nasync function metrics(page: Page, container: WoodScrollContainer, before?: WoodScrollMetrics): Promise<WoodScrollMetrics> {\n const element = container.kind === 'locator' ? await toPlaywrightLocator(page, container.target).elementHandle() : null;\n return page.evaluate(({ element, prior }) => {\n const node = (element as HTMLElement | null) ?? document.scrollingElement ?? document.documentElement;\n const atEdge: WoodScrollMetrics['atEdge'] = [];\n if (node.scrollTop <= 0) atEdge.push('top');\n if (node.scrollTop + node.clientHeight >= node.scrollHeight - 1) atEdge.push('bottom');\n if (node.scrollLeft <= 0) atEdge.push('left');\n if (node.scrollLeft + node.clientWidth >= node.scrollWidth - 1) atEdge.push('right');\n return { scrollTop: node.scrollTop, scrollLeft: node.scrollLeft, scrollHeight: node.scrollHeight, scrollWidth: node.scrollWidth, clientHeight: node.clientHeight, clientWidth: node.clientWidth, atEdge, moved: !!prior && (prior.scrollTop !== node.scrollTop || prior.scrollLeft !== node.scrollLeft) };\n }, { element, prior: before });\n}\nexport function hasNoProgress(recent: WoodScrollMetrics[]): boolean {\n return recent.length >= 3 && recent.slice(-3).every((value, index, all) => index === 0 || (value.scrollTop === all[0].scrollTop && value.scrollLeft === all[0].scrollLeft));\n}\nasync function isTargetReached(page: Page, container: WoodScrollContainer, target: Parameters<typeof toPlaywrightLocator>[1]): Promise<boolean> {\n const locator = toPlaywrightLocator(page, target);\n if (!(await locator.isVisible())) return false;\n const targetElement = await locator.elementHandle();\n const containerElement = container.kind === 'locator' ? await toPlaywrightLocator(page, container.target).elementHandle() : null;\n return page.evaluate(({ targetElement, containerElement }) => {\n const targetRect = (targetElement as Element).getBoundingClientRect();\n const containerRect = containerElement\n ? (containerElement as Element).getBoundingClientRect()\n : { top: 0, right: innerWidth, bottom: innerHeight, left: 0 };\n return targetRect.bottom > containerRect.top\n && targetRect.top < containerRect.bottom\n && targetRect.right > containerRect.left\n && targetRect.left < containerRect.right;\n }, { targetElement, containerElement });\n}\n\nexport async function executeScroll(page: Page, command: WoodScrollCommand): Promise<WoodAutomationResult<{ before: WoodScrollMetrics; after: WoodScrollMetrics; steps: number }>> {\n const container = command.mode === 'into_view' ? { kind: 'viewport' } as const : command.container;\n try {\n const before = await metrics(page, container);\n let steps = 1;\n if (command.mode === 'wheel') {\n if (command.container.kind === 'locator') {\n const box = await toPlaywrightLocator(page, command.container.target).boundingBox();\n if (!box) throw new Error('Scroll container is not visible.');\n await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);\n } else {\n const viewport = page.viewportSize();\n if (viewport) await page.mouse.move(viewport.width / 2, viewport.height / 2);\n }\n await page.mouse.wheel(command.deltaX ?? 0, command.deltaY ?? 0);\n } else if (command.mode === 'position') {\n const element = command.container.kind === 'locator' ? await toPlaywrightLocator(page, command.container.target).elementHandle() : null;\n await page.evaluate(({ element, command }) => {\n const node = (element as HTMLElement | null) ?? document.scrollingElement ?? document.documentElement;\n let x = command.x ?? node.scrollLeft, y = command.y ?? node.scrollTop;\n if (command.edge === 'top') y = 0; else if (command.edge === 'bottom') y = node.scrollHeight;\n else if (command.edge === 'left') x = 0; else if (command.edge === 'right') x = node.scrollWidth;\n node.scrollTo(x, y);\n }, { element, command });\n } else if (command.mode === 'into_view') {\n const locator = toPlaywrightLocator(page, command.target);\n if (!command.block) await locator.scrollIntoViewIfNeeded();\n else await locator.evaluate((node, block) => node.scrollIntoView({ block, inline: 'nearest' }), command.block);\n } else {\n const history: WoodScrollMetrics[] = [before];\n steps = 0;\n while (steps < command.maxSteps && !(await isTargetReached(page, command.container, command.target))) {\n const element = command.container.kind === 'locator' ? await toPlaywrightLocator(page, command.container.target).elementHandle() : null;\n await page.evaluate(({ element, direction, amount }) => {\n const node = (element as HTMLElement | null) ?? document.scrollingElement ?? document.documentElement;\n node.scrollBy(direction === 'left' ? -amount : direction === 'right' ? amount : 0, direction === 'up' ? -amount : direction === 'down' ? amount : 0);\n }, { element, direction: command.direction, amount: command.stepPx });\n steps++;\n history.push(await metrics(page, command.container, history.at(-1)));\n if (hasNoProgress(history)) return automationError('ACTION_FAILED', 'Scroll made no progress for two consecutive steps.', { details: { metrics: history, steps } });\n }\n if (!(await isTargetReached(page, command.container, command.target))) return automationError('ACTION_FAILED', 'Scroll target was not visible within maxSteps.', { details: { metrics: history, steps, maxSteps: command.maxSteps } });\n }\n await page.evaluate(() => new Promise<void>((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))));\n return automationOk({ before, after: await metrics(page, container, before), steps });\n } catch (error) {\n return automationError('ACTION_FAILED', 'Scroll failed.', { details: { cause: error instanceof Error ? error.message : String(error) } });\n }\n}\n"],"mappings":"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","names":["element","targetElement","containerElement","command"]}
@@ -0,0 +1,13 @@
1
+ import { Page } from 'playwright';
2
+ import { WoodAutomationResult } from './errors.cjs';
3
+ import { WoodScrollCommand, WoodScrollMetrics } from './scrolling.cjs';
4
+ import './locator.cjs';
5
+
6
+ declare function hasNoProgress(recent: WoodScrollMetrics[]): boolean;
7
+ declare function executeScroll(page: Page, command: WoodScrollCommand): Promise<WoodAutomationResult<{
8
+ before: WoodScrollMetrics;
9
+ after: WoodScrollMetrics;
10
+ steps: number;
11
+ }>>;
12
+
13
+ export { executeScroll, hasNoProgress };
@@ -0,0 +1,13 @@
1
+ import { Page } from 'playwright';
2
+ import { WoodAutomationResult } from './errors.js';
3
+ import { WoodScrollCommand, WoodScrollMetrics } from './scrolling.js';
4
+ import './locator.js';
5
+
6
+ declare function hasNoProgress(recent: WoodScrollMetrics[]): boolean;
7
+ declare function executeScroll(page: Page, command: WoodScrollCommand): Promise<WoodAutomationResult<{
8
+ before: WoodScrollMetrics;
9
+ after: WoodScrollMetrics;
10
+ steps: number;
11
+ }>>;
12
+
13
+ export { executeScroll, hasNoProgress };
@@ -0,0 +1,84 @@
1
+ import { automationError, automationOk } from "./errors.js";
2
+ import { toPlaywrightLocator } from "./locator.js";
3
+ async function metrics(page, container, before) {
4
+ const element = container.kind === "locator" ? await toPlaywrightLocator(page, container.target).elementHandle() : null;
5
+ return page.evaluate(({ element: element2, prior }) => {
6
+ const node = element2 ?? document.scrollingElement ?? document.documentElement;
7
+ const atEdge = [];
8
+ if (node.scrollTop <= 0) atEdge.push("top");
9
+ if (node.scrollTop + node.clientHeight >= node.scrollHeight - 1) atEdge.push("bottom");
10
+ if (node.scrollLeft <= 0) atEdge.push("left");
11
+ if (node.scrollLeft + node.clientWidth >= node.scrollWidth - 1) atEdge.push("right");
12
+ return { scrollTop: node.scrollTop, scrollLeft: node.scrollLeft, scrollHeight: node.scrollHeight, scrollWidth: node.scrollWidth, clientHeight: node.clientHeight, clientWidth: node.clientWidth, atEdge, moved: !!prior && (prior.scrollTop !== node.scrollTop || prior.scrollLeft !== node.scrollLeft) };
13
+ }, { element, prior: before });
14
+ }
15
+ function hasNoProgress(recent) {
16
+ return recent.length >= 3 && recent.slice(-3).every((value, index, all) => index === 0 || value.scrollTop === all[0].scrollTop && value.scrollLeft === all[0].scrollLeft);
17
+ }
18
+ async function isTargetReached(page, container, target) {
19
+ const locator = toPlaywrightLocator(page, target);
20
+ if (!await locator.isVisible()) return false;
21
+ const targetElement = await locator.elementHandle();
22
+ const containerElement = container.kind === "locator" ? await toPlaywrightLocator(page, container.target).elementHandle() : null;
23
+ return page.evaluate(({ targetElement: targetElement2, containerElement: containerElement2 }) => {
24
+ const targetRect = targetElement2.getBoundingClientRect();
25
+ const containerRect = containerElement2 ? containerElement2.getBoundingClientRect() : { top: 0, right: innerWidth, bottom: innerHeight, left: 0 };
26
+ return targetRect.bottom > containerRect.top && targetRect.top < containerRect.bottom && targetRect.right > containerRect.left && targetRect.left < containerRect.right;
27
+ }, { targetElement, containerElement });
28
+ }
29
+ async function executeScroll(page, command) {
30
+ const container = command.mode === "into_view" ? { kind: "viewport" } : command.container;
31
+ try {
32
+ const before = await metrics(page, container);
33
+ let steps = 1;
34
+ if (command.mode === "wheel") {
35
+ if (command.container.kind === "locator") {
36
+ const box = await toPlaywrightLocator(page, command.container.target).boundingBox();
37
+ if (!box) throw new Error("Scroll container is not visible.");
38
+ await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
39
+ } else {
40
+ const viewport = page.viewportSize();
41
+ if (viewport) await page.mouse.move(viewport.width / 2, viewport.height / 2);
42
+ }
43
+ await page.mouse.wheel(command.deltaX ?? 0, command.deltaY ?? 0);
44
+ } else if (command.mode === "position") {
45
+ const element = command.container.kind === "locator" ? await toPlaywrightLocator(page, command.container.target).elementHandle() : null;
46
+ await page.evaluate(({ element: element2, command: command2 }) => {
47
+ const node = element2 ?? document.scrollingElement ?? document.documentElement;
48
+ let x = command2.x ?? node.scrollLeft, y = command2.y ?? node.scrollTop;
49
+ if (command2.edge === "top") y = 0;
50
+ else if (command2.edge === "bottom") y = node.scrollHeight;
51
+ else if (command2.edge === "left") x = 0;
52
+ else if (command2.edge === "right") x = node.scrollWidth;
53
+ node.scrollTo(x, y);
54
+ }, { element, command });
55
+ } else if (command.mode === "into_view") {
56
+ const locator = toPlaywrightLocator(page, command.target);
57
+ if (!command.block) await locator.scrollIntoViewIfNeeded();
58
+ else await locator.evaluate((node, block) => node.scrollIntoView({ block, inline: "nearest" }), command.block);
59
+ } else {
60
+ const history = [before];
61
+ steps = 0;
62
+ while (steps < command.maxSteps && !await isTargetReached(page, command.container, command.target)) {
63
+ const element = command.container.kind === "locator" ? await toPlaywrightLocator(page, command.container.target).elementHandle() : null;
64
+ await page.evaluate(({ element: element2, direction, amount }) => {
65
+ const node = element2 ?? document.scrollingElement ?? document.documentElement;
66
+ node.scrollBy(direction === "left" ? -amount : direction === "right" ? amount : 0, direction === "up" ? -amount : direction === "down" ? amount : 0);
67
+ }, { element, direction: command.direction, amount: command.stepPx });
68
+ steps++;
69
+ history.push(await metrics(page, command.container, history.at(-1)));
70
+ if (hasNoProgress(history)) return automationError("ACTION_FAILED", "Scroll made no progress for two consecutive steps.", { details: { metrics: history, steps } });
71
+ }
72
+ if (!await isTargetReached(page, command.container, command.target)) return automationError("ACTION_FAILED", "Scroll target was not visible within maxSteps.", { details: { metrics: history, steps, maxSteps: command.maxSteps } });
73
+ }
74
+ await page.evaluate(() => new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))));
75
+ return automationOk({ before, after: await metrics(page, container, before), steps });
76
+ } catch (error) {
77
+ return automationError("ACTION_FAILED", "Scroll failed.", { details: { cause: error instanceof Error ? error.message : String(error) } });
78
+ }
79
+ }
80
+ export {
81
+ executeScroll,
82
+ hasNoProgress
83
+ };
84
+ //# sourceMappingURL=scrolling_executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/automation/scrolling_executor.ts"],"sourcesContent":["import type { Page } from 'playwright';\nimport { automationError, automationOk, type WoodAutomationResult } from './errors.js';\nimport { toPlaywrightLocator } from './locator.js';\nimport type { WoodScrollCommand, WoodScrollContainer, WoodScrollMetrics } from './scrolling.js';\n\nasync function metrics(page: Page, container: WoodScrollContainer, before?: WoodScrollMetrics): Promise<WoodScrollMetrics> {\n const element = container.kind === 'locator' ? await toPlaywrightLocator(page, container.target).elementHandle() : null;\n return page.evaluate(({ element, prior }) => {\n const node = (element as HTMLElement | null) ?? document.scrollingElement ?? document.documentElement;\n const atEdge: WoodScrollMetrics['atEdge'] = [];\n if (node.scrollTop <= 0) atEdge.push('top');\n if (node.scrollTop + node.clientHeight >= node.scrollHeight - 1) atEdge.push('bottom');\n if (node.scrollLeft <= 0) atEdge.push('left');\n if (node.scrollLeft + node.clientWidth >= node.scrollWidth - 1) atEdge.push('right');\n return { scrollTop: node.scrollTop, scrollLeft: node.scrollLeft, scrollHeight: node.scrollHeight, scrollWidth: node.scrollWidth, clientHeight: node.clientHeight, clientWidth: node.clientWidth, atEdge, moved: !!prior && (prior.scrollTop !== node.scrollTop || prior.scrollLeft !== node.scrollLeft) };\n }, { element, prior: before });\n}\nexport function hasNoProgress(recent: WoodScrollMetrics[]): boolean {\n return recent.length >= 3 && recent.slice(-3).every((value, index, all) => index === 0 || (value.scrollTop === all[0].scrollTop && value.scrollLeft === all[0].scrollLeft));\n}\nasync function isTargetReached(page: Page, container: WoodScrollContainer, target: Parameters<typeof toPlaywrightLocator>[1]): Promise<boolean> {\n const locator = toPlaywrightLocator(page, target);\n if (!(await locator.isVisible())) return false;\n const targetElement = await locator.elementHandle();\n const containerElement = container.kind === 'locator' ? await toPlaywrightLocator(page, container.target).elementHandle() : null;\n return page.evaluate(({ targetElement, containerElement }) => {\n const targetRect = (targetElement as Element).getBoundingClientRect();\n const containerRect = containerElement\n ? (containerElement as Element).getBoundingClientRect()\n : { top: 0, right: innerWidth, bottom: innerHeight, left: 0 };\n return targetRect.bottom > containerRect.top\n && targetRect.top < containerRect.bottom\n && targetRect.right > containerRect.left\n && targetRect.left < containerRect.right;\n }, { targetElement, containerElement });\n}\n\nexport async function executeScroll(page: Page, command: WoodScrollCommand): Promise<WoodAutomationResult<{ before: WoodScrollMetrics; after: WoodScrollMetrics; steps: number }>> {\n const container = command.mode === 'into_view' ? { kind: 'viewport' } as const : command.container;\n try {\n const before = await metrics(page, container);\n let steps = 1;\n if (command.mode === 'wheel') {\n if (command.container.kind === 'locator') {\n const box = await toPlaywrightLocator(page, command.container.target).boundingBox();\n if (!box) throw new Error('Scroll container is not visible.');\n await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);\n } else {\n const viewport = page.viewportSize();\n if (viewport) await page.mouse.move(viewport.width / 2, viewport.height / 2);\n }\n await page.mouse.wheel(command.deltaX ?? 0, command.deltaY ?? 0);\n } else if (command.mode === 'position') {\n const element = command.container.kind === 'locator' ? await toPlaywrightLocator(page, command.container.target).elementHandle() : null;\n await page.evaluate(({ element, command }) => {\n const node = (element as HTMLElement | null) ?? document.scrollingElement ?? document.documentElement;\n let x = command.x ?? node.scrollLeft, y = command.y ?? node.scrollTop;\n if (command.edge === 'top') y = 0; else if (command.edge === 'bottom') y = node.scrollHeight;\n else if (command.edge === 'left') x = 0; else if (command.edge === 'right') x = node.scrollWidth;\n node.scrollTo(x, y);\n }, { element, command });\n } else if (command.mode === 'into_view') {\n const locator = toPlaywrightLocator(page, command.target);\n if (!command.block) await locator.scrollIntoViewIfNeeded();\n else await locator.evaluate((node, block) => node.scrollIntoView({ block, inline: 'nearest' }), command.block);\n } else {\n const history: WoodScrollMetrics[] = [before];\n steps = 0;\n while (steps < command.maxSteps && !(await isTargetReached(page, command.container, command.target))) {\n const element = command.container.kind === 'locator' ? await toPlaywrightLocator(page, command.container.target).elementHandle() : null;\n await page.evaluate(({ element, direction, amount }) => {\n const node = (element as HTMLElement | null) ?? document.scrollingElement ?? document.documentElement;\n node.scrollBy(direction === 'left' ? -amount : direction === 'right' ? amount : 0, direction === 'up' ? -amount : direction === 'down' ? amount : 0);\n }, { element, direction: command.direction, amount: command.stepPx });\n steps++;\n history.push(await metrics(page, command.container, history.at(-1)));\n if (hasNoProgress(history)) return automationError('ACTION_FAILED', 'Scroll made no progress for two consecutive steps.', { details: { metrics: history, steps } });\n }\n if (!(await isTargetReached(page, command.container, command.target))) return automationError('ACTION_FAILED', 'Scroll target was not visible within maxSteps.', { details: { metrics: history, steps, maxSteps: command.maxSteps } });\n }\n await page.evaluate(() => new Promise<void>((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))));\n return automationOk({ before, after: await metrics(page, container, before), steps });\n } catch (error) {\n return automationError('ACTION_FAILED', 'Scroll failed.', { details: { cause: error instanceof Error ? error.message : String(error) } });\n }\n}\n"],"mappings":"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","names":["element","targetElement","containerElement","command"]}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var target_identity_exports = {};
16
+ module.exports = __toCommonJS(target_identity_exports);
17
+ //# sourceMappingURL=target_identity.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/automation/target_identity.ts"],"sourcesContent":["/**\n * Typed target model (frozen contract — Axe.md \"Typed target model\").\n *\n * Identity comes from CDP target identity plus Wood window identity, never\n * from page enumeration order. A numeric index may be displayed for\n * diagnostics but is not durable identity.\n */\n\nexport interface WoodLiveTarget {\n /** CDP-derived target identity (stable for the page's lifetime). */\n targetId: string;\n /** Wood window identity from the renderer bridge; null when absent. */\n windowId: string | null;\n webContentsId?: number;\n browserContextId?: string;\n /** Incremented/replaced after reload or target replacement. */\n pageGeneration: number;\n url: string;\n title: string;\n /** Route currently displayed (dev/test introspection bridge; WP-02). */\n currentRoute?: string;\n /** Route the window was configured to open with — NOT the current route. */\n configuredDefaultRoute?: string;\n woodBridgePresent: boolean;\n /** Eligible for automation (Wood bridge present by default). */\n eligible: boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Typed target model (frozen contract — Axe.md "Typed target model").
3
+ *
4
+ * Identity comes from CDP target identity plus Wood window identity, never
5
+ * from page enumeration order. A numeric index may be displayed for
6
+ * diagnostics but is not durable identity.
7
+ */
8
+ interface WoodLiveTarget {
9
+ /** CDP-derived target identity (stable for the page's lifetime). */
10
+ targetId: string;
11
+ /** Wood window identity from the renderer bridge; null when absent. */
12
+ windowId: string | null;
13
+ webContentsId?: number;
14
+ browserContextId?: string;
15
+ /** Incremented/replaced after reload or target replacement. */
16
+ pageGeneration: number;
17
+ url: string;
18
+ title: string;
19
+ /** Route currently displayed (dev/test introspection bridge; WP-02). */
20
+ currentRoute?: string;
21
+ /** Route the window was configured to open with — NOT the current route. */
22
+ configuredDefaultRoute?: string;
23
+ woodBridgePresent: boolean;
24
+ /** Eligible for automation (Wood bridge present by default). */
25
+ eligible: boolean;
26
+ }
27
+
28
+ export type { WoodLiveTarget };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Typed target model (frozen contract — Axe.md "Typed target model").
3
+ *
4
+ * Identity comes from CDP target identity plus Wood window identity, never
5
+ * from page enumeration order. A numeric index may be displayed for
6
+ * diagnostics but is not durable identity.
7
+ */
8
+ interface WoodLiveTarget {
9
+ /** CDP-derived target identity (stable for the page's lifetime). */
10
+ targetId: string;
11
+ /** Wood window identity from the renderer bridge; null when absent. */
12
+ windowId: string | null;
13
+ webContentsId?: number;
14
+ browserContextId?: string;
15
+ /** Incremented/replaced after reload or target replacement. */
16
+ pageGeneration: number;
17
+ url: string;
18
+ title: string;
19
+ /** Route currently displayed (dev/test introspection bridge; WP-02). */
20
+ currentRoute?: string;
21
+ /** Route the window was configured to open with — NOT the current route. */
22
+ configuredDefaultRoute?: string;
23
+ woodBridgePresent: boolean;
24
+ /** Eligible for automation (Wood bridge present by default). */
25
+ eligible: boolean;
26
+ }
27
+
28
+ export type { WoodLiveTarget };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=target_identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}