@sun-asterisk/sungen 3.2.28 → 3.2.30

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 (486) hide show
  1. package/dist/capabilities/discover.d.ts +29 -0
  2. package/dist/capabilities/discover.d.ts.map +1 -1
  3. package/dist/capabilities/discover.js +144 -10
  4. package/dist/capabilities/discover.js.map +1 -1
  5. package/dist/capabilities/registry.d.ts +18 -0
  6. package/dist/capabilities/registry.d.ts.map +1 -1
  7. package/dist/capabilities/registry.js +25 -0
  8. package/dist/capabilities/registry.js.map +1 -1
  9. package/dist/cli/commands/audit.d.ts.map +1 -1
  10. package/dist/cli/commands/audit.js +9 -0
  11. package/dist/cli/commands/audit.js.map +1 -1
  12. package/dist/cli/commands/capability.js +1 -1
  13. package/dist/cli/commands/capability.js.map +1 -1
  14. package/dist/cli/commands/delivery.d.ts.map +1 -1
  15. package/dist/cli/commands/delivery.js +2 -1
  16. package/dist/cli/commands/delivery.js.map +1 -1
  17. package/dist/cli/commands/generate.d.ts.map +1 -1
  18. package/dist/cli/commands/generate.js +6 -2
  19. package/dist/cli/commands/generate.js.map +1 -1
  20. package/dist/cli/commands/inspect.js +1 -1
  21. package/dist/cli/commands/inspect.js.map +1 -1
  22. package/dist/cli/commands/results-merge.d.ts.map +1 -1
  23. package/dist/cli/commands/results-merge.js +9 -2
  24. package/dist/cli/commands/results-merge.js.map +1 -1
  25. package/dist/cli/commands/results-sanitize.d.ts +24 -0
  26. package/dist/cli/commands/results-sanitize.d.ts.map +1 -0
  27. package/dist/cli/commands/results-sanitize.js +126 -0
  28. package/dist/cli/commands/results-sanitize.js.map +1 -0
  29. package/dist/cli/commands/script-check.d.ts.map +1 -1
  30. package/dist/cli/commands/script-check.js +3 -1
  31. package/dist/cli/commands/script-check.js.map +1 -1
  32. package/dist/cli/commands/update.d.ts.map +1 -1
  33. package/dist/cli/commands/update.js +3 -0
  34. package/dist/cli/commands/update.js.map +1 -1
  35. package/dist/dashboard/templates/index.html +1 -1
  36. package/dist/exporters/api-testcase-formatter.d.ts +3 -6
  37. package/dist/exporters/api-testcase-formatter.d.ts.map +1 -1
  38. package/dist/exporters/api-testcase-formatter.js +7 -10
  39. package/dist/exporters/api-testcase-formatter.js.map +1 -1
  40. package/dist/exporters/feature-parser.d.ts +1 -1
  41. package/dist/exporters/feature-parser.js +1 -1
  42. package/dist/exporters/matrix/build.d.ts.map +1 -1
  43. package/dist/exporters/matrix/build.js +18 -3
  44. package/dist/exporters/matrix/build.js.map +1 -1
  45. package/dist/exporters/matrix/item-labels.d.ts +35 -0
  46. package/dist/exporters/matrix/item-labels.d.ts.map +1 -0
  47. package/dist/exporters/matrix/item-labels.js +90 -0
  48. package/dist/exporters/matrix/item-labels.js.map +1 -0
  49. package/dist/exporters/matrix/render-coverage-sheet.d.ts +14 -0
  50. package/dist/exporters/matrix/render-coverage-sheet.d.ts.map +1 -0
  51. package/dist/exporters/matrix/render-coverage-sheet.js +162 -0
  52. package/dist/exporters/matrix/render-coverage-sheet.js.map +1 -0
  53. package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
  54. package/dist/exporters/matrix/render-csv.js +3 -1
  55. package/dist/exporters/matrix/render-csv.js.map +1 -1
  56. package/dist/exporters/matrix/render-overview-sheet.d.ts +20 -0
  57. package/dist/exporters/matrix/render-overview-sheet.d.ts.map +1 -0
  58. package/dist/exporters/matrix/render-overview-sheet.js +32 -0
  59. package/dist/exporters/matrix/render-overview-sheet.js.map +1 -0
  60. package/dist/exporters/matrix/render-testcase-sheet.d.ts +30 -0
  61. package/dist/exporters/matrix/render-testcase-sheet.d.ts.map +1 -0
  62. package/dist/exporters/matrix/render-testcase-sheet.js +156 -0
  63. package/dist/exporters/matrix/render-testcase-sheet.js.map +1 -0
  64. package/dist/exporters/matrix/render-xlsx.d.ts +41 -31
  65. package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
  66. package/dist/exporters/matrix/render-xlsx.js +72 -425
  67. package/dist/exporters/matrix/render-xlsx.js.map +1 -1
  68. package/dist/exporters/matrix/result-totals.d.ts +23 -0
  69. package/dist/exporters/matrix/result-totals.d.ts.map +1 -0
  70. package/dist/exporters/matrix/result-totals.js +21 -0
  71. package/dist/exporters/matrix/result-totals.js.map +1 -0
  72. package/dist/exporters/matrix/testcase-summary-band.d.ts +30 -0
  73. package/dist/exporters/matrix/testcase-summary-band.d.ts.map +1 -0
  74. package/dist/exporters/matrix/testcase-summary-band.js +71 -0
  75. package/dist/exporters/matrix/testcase-summary-band.js.map +1 -0
  76. package/dist/exporters/matrix/wording.d.ts.map +1 -1
  77. package/dist/exporters/matrix/wording.js +13 -0
  78. package/dist/exporters/matrix/wording.js.map +1 -1
  79. package/dist/exporters/matrix/xlsx-cells.d.ts +38 -0
  80. package/dist/exporters/matrix/xlsx-cells.d.ts.map +1 -0
  81. package/dist/exporters/matrix/xlsx-cells.js +52 -0
  82. package/dist/exporters/matrix/xlsx-cells.js.map +1 -0
  83. package/dist/exporters/qa-env-secret-denylist.js +2 -2
  84. package/dist/exporters/qa-env-secret-denylist.js.map +1 -1
  85. package/dist/exporters/report-path-sanitizer.d.ts +38 -0
  86. package/dist/exporters/report-path-sanitizer.d.ts.map +1 -0
  87. package/dist/exporters/report-path-sanitizer.js +137 -0
  88. package/dist/exporters/report-path-sanitizer.js.map +1 -0
  89. package/dist/exporters/result-variants.d.ts.map +1 -1
  90. package/dist/exporters/result-variants.js +2 -1
  91. package/dist/exporters/result-variants.js.map +1 -1
  92. package/dist/exporters/sensitive-key.d.ts +31 -0
  93. package/dist/exporters/sensitive-key.d.ts.map +1 -0
  94. package/dist/exporters/sensitive-key.js +50 -0
  95. package/dist/exporters/sensitive-key.js.map +1 -0
  96. package/dist/exporters/test-data-resolver.d.ts +4 -1
  97. package/dist/exporters/test-data-resolver.d.ts.map +1 -1
  98. package/dist/exporters/test-data-resolver.js +12 -2
  99. package/dist/exporters/test-data-resolver.js.map +1 -1
  100. package/dist/exporters/xlsx-report-builder.d.ts +12 -1
  101. package/dist/exporters/xlsx-report-builder.d.ts.map +1 -1
  102. package/dist/exporters/xlsx-report-builder.js +10 -2
  103. package/dist/exporters/xlsx-report-builder.js.map +1 -1
  104. package/dist/generators/gherkin-parser/index.d.ts +10 -0
  105. package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
  106. package/dist/generators/gherkin-parser/index.js +20 -12
  107. package/dist/generators/gherkin-parser/index.js.map +1 -1
  108. package/dist/generators/gherkin-parser/parent-scope-clause.d.ts +54 -0
  109. package/dist/generators/gherkin-parser/parent-scope-clause.d.ts.map +1 -0
  110. package/dist/generators/gherkin-parser/parent-scope-clause.js +109 -0
  111. package/dist/generators/gherkin-parser/parent-scope-clause.js.map +1 -0
  112. package/dist/generators/test-generator/adapters/adapter-interface.d.ts +23 -18
  113. package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
  114. package/dist/generators/test-generator/adapters/appium/appium-adapter.d.ts +4 -19
  115. package/dist/generators/test-generator/adapters/appium/appium-adapter.d.ts.map +1 -1
  116. package/dist/generators/test-generator/adapters/appium/appium-adapter.js.map +1 -1
  117. package/dist/generators/test-generator/adapters/appium/os-support.d.ts +53 -0
  118. package/dist/generators/test-generator/adapters/appium/os-support.d.ts.map +1 -0
  119. package/dist/generators/test-generator/adapters/appium/os-support.js +200 -0
  120. package/dist/generators/test-generator/adapters/appium/os-support.js.map +1 -0
  121. package/dist/generators/test-generator/adapters/appium/templates/after-all.hbs +18 -0
  122. package/dist/generators/test-generator/adapters/appium/templates/after-each.hbs +18 -0
  123. package/dist/generators/test-generator/adapters/appium/templates/before-all.hbs +18 -0
  124. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/alert-fill-action.hbs +9 -2
  125. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/capture-variable.hbs +24 -1
  126. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/click-at-position-action.hbs +1 -0
  127. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/click-element-with-text.hbs +1 -1
  128. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/double-click-action.hbs +7 -0
  129. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/frame-enter-action.hbs +3 -6
  130. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/hover-action.hbs +6 -2
  131. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/hover-element-with-text.hbs +4 -3
  132. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/table-paginate-action.hbs +3 -0
  133. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/unknown-element-action.hbs +9 -0
  134. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/have-value-assertion.hbs +34 -1
  135. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/label-value-assertion.hbs +14 -6
  136. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/visible-assertion.hbs +1 -1
  137. package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/go-back-action.hbs +21 -0
  138. package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/long-press-action.hbs +4 -0
  139. package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/pinch-zoom-action.hbs +4 -0
  140. package/dist/generators/test-generator/adapters/appium/templates/steps/gestures/set-geolocation-action.hbs +16 -0
  141. package/dist/generators/test-generator/adapters/appium/templates/steps/partials/locator.hbs +9 -1
  142. package/dist/generators/test-generator/adapters/appium/templates/test-file.hbs +62 -23
  143. package/dist/generators/test-generator/adapters/index.d.ts +1 -1
  144. package/dist/generators/test-generator/adapters/index.d.ts.map +1 -1
  145. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts +4 -19
  146. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.d.ts.map +1 -1
  147. package/dist/generators/test-generator/adapters/playwright/playwright-adapter.js.map +1 -1
  148. package/dist/generators/test-generator/adapters/playwright/templates/after-all.hbs +19 -1
  149. package/dist/generators/test-generator/adapters/playwright/templates/after-each.hbs +18 -0
  150. package/dist/generators/test-generator/adapters/playwright/templates/before-all.hbs +19 -1
  151. package/dist/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
  152. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/check-action.hbs +6 -1
  153. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/click-at-position-action.hbs +23 -0
  154. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/expand-action.hbs +8 -8
  155. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/fill-editor-action.hbs +7 -2
  156. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row-nth.hbs +7 -2
  157. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +7 -2
  158. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/table-paginate-action.hbs +5 -0
  159. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/uncheck-action.hbs +3 -1
  160. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/unknown-element-action.hbs +1 -1
  161. package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-page.hbs +18 -1
  162. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/all-contain-assertion.hbs +32 -4
  163. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/all-contain-element.hbs +5 -2
  164. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/checked-assertion.hbs +5 -1
  165. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/column-cell-assertion.hbs +13 -2
  166. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -1
  167. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +2 -2
  168. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +1 -1
  169. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/have-text-assertion.hbs +1 -1
  170. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +2 -2
  171. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +1 -1
  172. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/not-checked-assertion.hbs +2 -1
  173. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/selected-assertion.hbs +21 -3
  174. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/state-with-filter-assertion.hbs +20 -2
  175. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-empty.hbs +4 -1
  176. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +4 -1
  177. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-count.hbs +4 -1
  178. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +12 -4
  179. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +14 -2
  180. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +3 -3
  181. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
  182. package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -1
  183. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/checked-opts.hbs +8 -0
  184. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +8 -8
  185. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-nth.hbs +1 -1
  186. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/id.hbs +1 -1
  187. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/testid.hbs +1 -1
  188. package/dist/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +8 -8
  189. package/dist/generators/test-generator/adapters/playwright/templates/test-file.hbs +10 -8
  190. package/dist/generators/test-generator/code-generator.d.ts +37 -0
  191. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  192. package/dist/generators/test-generator/code-generator.js +165 -40
  193. package/dist/generators/test-generator/code-generator.js.map +1 -1
  194. package/dist/generators/test-generator/diagnostics.d.ts +116 -6
  195. package/dist/generators/test-generator/diagnostics.d.ts.map +1 -1
  196. package/dist/generators/test-generator/diagnostics.js +115 -5
  197. package/dist/generators/test-generator/diagnostics.js.map +1 -1
  198. package/dist/generators/test-generator/patterns/index.d.ts +57 -11
  199. package/dist/generators/test-generator/patterns/index.d.ts.map +1 -1
  200. package/dist/generators/test-generator/patterns/index.js +163 -21
  201. package/dist/generators/test-generator/patterns/index.js.map +1 -1
  202. package/dist/generators/test-generator/patterns/types.d.ts +8 -0
  203. package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
  204. package/dist/generators/test-generator/patterns/with-parent-scope.d.ts +18 -0
  205. package/dist/generators/test-generator/patterns/with-parent-scope.d.ts.map +1 -0
  206. package/dist/generators/test-generator/patterns/with-parent-scope.js +40 -0
  207. package/dist/generators/test-generator/patterns/with-parent-scope.js.map +1 -0
  208. package/dist/generators/test-generator/step-mapper.d.ts +103 -10
  209. package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
  210. package/dist/generators/test-generator/step-mapper.js +266 -45
  211. package/dist/generators/test-generator/step-mapper.js.map +1 -1
  212. package/dist/generators/test-generator/template-engine.d.ts +4 -19
  213. package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
  214. package/dist/generators/test-generator/template-engine.js +17 -12
  215. package/dist/generators/test-generator/template-engine.js.map +1 -1
  216. package/dist/generators/test-generator/utils/data-resolver.d.ts +7 -0
  217. package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
  218. package/dist/generators/test-generator/utils/data-resolver.js +19 -2
  219. package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
  220. package/dist/generators/test-generator/utils/dialog-scope-identity.d.ts +41 -0
  221. package/dist/generators/test-generator/utils/dialog-scope-identity.d.ts.map +1 -0
  222. package/dist/generators/test-generator/utils/dialog-scope-identity.js +61 -0
  223. package/dist/generators/test-generator/utils/dialog-scope-identity.js.map +1 -0
  224. package/dist/generators/test-generator/utils/escape-js-string.d.ts +17 -0
  225. package/dist/generators/test-generator/utils/escape-js-string.d.ts.map +1 -0
  226. package/dist/generators/test-generator/utils/escape-js-string.js +29 -0
  227. package/dist/generators/test-generator/utils/escape-js-string.js.map +1 -0
  228. package/dist/generators/test-generator/utils/nearest-match.d.ts +24 -0
  229. package/dist/generators/test-generator/utils/nearest-match.d.ts.map +1 -0
  230. package/dist/generators/test-generator/utils/nearest-match.js +56 -0
  231. package/dist/generators/test-generator/utils/nearest-match.js.map +1 -0
  232. package/dist/generators/test-generator/utils/selector-entry-fields.d.ts +58 -0
  233. package/dist/generators/test-generator/utils/selector-entry-fields.d.ts.map +1 -0
  234. package/dist/generators/test-generator/utils/selector-entry-fields.js +119 -0
  235. package/dist/generators/test-generator/utils/selector-entry-fields.js.map +1 -0
  236. package/dist/generators/test-generator/utils/selector-entry-walk.d.ts +25 -0
  237. package/dist/generators/test-generator/utils/selector-entry-walk.d.ts.map +1 -0
  238. package/dist/generators/test-generator/utils/selector-entry-walk.js +54 -0
  239. package/dist/generators/test-generator/utils/selector-entry-walk.js.map +1 -0
  240. package/dist/generators/test-generator/utils/selector-nth-validation.d.ts +59 -0
  241. package/dist/generators/test-generator/utils/selector-nth-validation.d.ts.map +1 -0
  242. package/dist/generators/test-generator/utils/selector-nth-validation.js +91 -0
  243. package/dist/generators/test-generator/utils/selector-nth-validation.js.map +1 -0
  244. package/dist/generators/test-generator/utils/selector-resolver.d.ts +53 -2
  245. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  246. package/dist/generators/test-generator/utils/selector-resolver.js +273 -27
  247. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  248. package/dist/generators/test-generator/utils/selector-type-validation.d.ts +51 -0
  249. package/dist/generators/test-generator/utils/selector-type-validation.d.ts.map +1 -0
  250. package/dist/generators/test-generator/utils/selector-type-validation.js +77 -0
  251. package/dist/generators/test-generator/utils/selector-type-validation.js.map +1 -0
  252. package/dist/harness/audit.d.ts +3 -1
  253. package/dist/harness/audit.d.ts.map +1 -1
  254. package/dist/harness/audit.js +51 -28
  255. package/dist/harness/audit.js.map +1 -1
  256. package/dist/harness/capability-plan.d.ts +4 -0
  257. package/dist/harness/capability-plan.d.ts.map +1 -1
  258. package/dist/harness/capability-plan.js +32 -2
  259. package/dist/harness/capability-plan.js.map +1 -1
  260. package/dist/harness/catalog/drivers.yaml +1 -1
  261. package/dist/harness/catalog/universal-viewpoints.yaml +145 -0
  262. package/dist/harness/data-driven-lint.d.ts.map +1 -1
  263. package/dist/harness/data-driven-lint.js +217 -33
  264. package/dist/harness/data-driven-lint.js.map +1 -1
  265. package/dist/harness/parse.d.ts +6 -0
  266. package/dist/harness/parse.d.ts.map +1 -1
  267. package/dist/harness/parse.js +1 -1
  268. package/dist/harness/parse.js.map +1 -1
  269. package/dist/harness/repair.d.ts.map +1 -1
  270. package/dist/harness/repair.js +8 -1
  271. package/dist/harness/repair.js.map +1 -1
  272. package/dist/harness/script-check.d.ts +2 -2
  273. package/dist/harness/script-check.d.ts.map +1 -1
  274. package/dist/harness/script-check.js +186 -25
  275. package/dist/harness/script-check.js.map +1 -1
  276. package/dist/harness/sensors.d.ts +48 -0
  277. package/dist/harness/sensors.d.ts.map +1 -1
  278. package/dist/harness/sensors.js +26 -1
  279. package/dist/harness/sensors.js.map +1 -1
  280. package/dist/harness/viewpoint-ledger.d.ts +10 -0
  281. package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
  282. package/dist/harness/viewpoint-ledger.js +23 -2
  283. package/dist/harness/viewpoint-ledger.js.map +1 -1
  284. package/dist/index.d.ts +2 -0
  285. package/dist/index.d.ts.map +1 -1
  286. package/dist/index.js +10 -1
  287. package/dist/index.js.map +1 -1
  288. package/dist/orchestrator/project-initializer.d.ts +6 -0
  289. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  290. package/dist/orchestrator/project-initializer.js +16 -0
  291. package/dist/orchestrator/project-initializer.js.map +1 -1
  292. package/dist/orchestrator/report-sanitize-reporter-install.d.ts +24 -0
  293. package/dist/orchestrator/report-sanitize-reporter-install.d.ts.map +1 -0
  294. package/dist/orchestrator/report-sanitize-reporter-install.js +161 -0
  295. package/dist/orchestrator/report-sanitize-reporter-install.js.map +1 -0
  296. package/dist/orchestrator/templates/ai-src/commands/delivery.md +4 -3
  297. package/dist/orchestrator/templates/ai-src/commands/run-test.md +9 -1
  298. package/dist/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +10 -0
  299. package/dist/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +14 -5
  300. package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +62 -3
  301. package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +126 -11
  302. package/dist/orchestrator/templates/ai-src/skills/sungen-mobile-gestures/SKILL.md +16 -1
  303. package/dist/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +12 -0
  304. package/dist/orchestrator/templates/ai-src/skills/sungen-selector-keys/SKILL.md +19 -5
  305. package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +88 -2
  306. package/dist/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +62 -5
  307. package/dist/orchestrator/templates/ai-src/skills/sungen-test-design-techniques/SKILL.md +13 -0
  308. package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md +59 -10
  309. package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-f-mobile-native.md +419 -0
  310. package/dist/orchestrator/templates/playwright.config.ts +7 -0
  311. package/dist/orchestrator/templates/readme.md +1 -1
  312. package/dist/orchestrator/templates/specs-checked-state.d.ts +83 -0
  313. package/dist/orchestrator/templates/specs-checked-state.d.ts.map +1 -0
  314. package/dist/orchestrator/templates/specs-checked-state.js +261 -0
  315. package/dist/orchestrator/templates/specs-checked-state.js.map +1 -0
  316. package/dist/orchestrator/templates/specs-checked-state.ts +324 -0
  317. package/dist/orchestrator/templates/specs-pw-shape-reporter.ts +0 -0
  318. package/dist/orchestrator/templates/specs-report-path-sanitize-reporter.d.ts +36 -0
  319. package/dist/orchestrator/templates/specs-report-path-sanitize-reporter.d.ts.map +1 -0
  320. package/dist/orchestrator/templates/specs-report-path-sanitize-reporter.js +155 -0
  321. package/dist/orchestrator/templates/specs-report-path-sanitize-reporter.js.map +1 -0
  322. package/dist/orchestrator/templates/specs-report-path-sanitize-reporter.ts +142 -0
  323. package/dist/orchestrator/templates/specs-url-assert.d.ts +50 -25
  324. package/dist/orchestrator/templates/specs-url-assert.d.ts.map +1 -1
  325. package/dist/orchestrator/templates/specs-url-assert.js +65 -24
  326. package/dist/orchestrator/templates/specs-url-assert.js.map +1 -1
  327. package/dist/orchestrator/templates/specs-url-assert.ts +101 -28
  328. package/dist/orchestrator/templates/wdio.conf.ts +105 -1
  329. package/dist/utils/selector-types.d.ts +43 -1
  330. package/dist/utils/selector-types.d.ts.map +1 -1
  331. package/dist/utils/selector-types.js +51 -7
  332. package/dist/utils/selector-types.js.map +1 -1
  333. package/package.json +3 -3
  334. package/src/capabilities/discover.ts +146 -10
  335. package/src/capabilities/registry.ts +30 -0
  336. package/src/cli/commands/audit.ts +9 -0
  337. package/src/cli/commands/capability.ts +1 -1
  338. package/src/cli/commands/delivery.ts +2 -1
  339. package/src/cli/commands/generate.ts +5 -2
  340. package/src/cli/commands/inspect.ts +1 -1
  341. package/src/cli/commands/results-merge.ts +9 -2
  342. package/src/cli/commands/results-sanitize.ts +98 -0
  343. package/src/cli/commands/script-check.ts +3 -1
  344. package/src/cli/commands/update.ts +3 -0
  345. package/src/dashboard/templates/index.html +1 -1
  346. package/src/exporters/api-testcase-formatter.ts +5 -7
  347. package/src/exporters/feature-parser.ts +1 -1
  348. package/src/exporters/matrix/build.ts +17 -3
  349. package/src/exporters/matrix/item-labels.ts +78 -0
  350. package/src/exporters/matrix/render-coverage-sheet.ts +170 -0
  351. package/src/exporters/matrix/render-csv.ts +3 -1
  352. package/src/exporters/matrix/render-overview-sheet.ts +51 -0
  353. package/src/exporters/matrix/render-testcase-sheet.ts +178 -0
  354. package/src/exporters/matrix/render-xlsx.ts +67 -448
  355. package/src/exporters/matrix/result-totals.ts +37 -0
  356. package/src/exporters/matrix/testcase-summary-band.ts +74 -0
  357. package/src/exporters/matrix/wording.ts +13 -0
  358. package/src/exporters/matrix/xlsx-cells.ts +56 -0
  359. package/src/exporters/qa-env-secret-denylist.ts +1 -1
  360. package/src/exporters/report-path-sanitizer.ts +144 -0
  361. package/src/exporters/result-variants.ts +2 -1
  362. package/src/exporters/sensitive-key.ts +48 -0
  363. package/src/exporters/test-data-resolver.ts +12 -2
  364. package/src/exporters/xlsx-report-builder.ts +16 -2
  365. package/src/generators/gherkin-parser/index.ts +22 -11
  366. package/src/generators/gherkin-parser/parent-scope-clause.ts +130 -0
  367. package/src/generators/test-generator/adapters/adapter-interface.ts +25 -3
  368. package/src/generators/test-generator/adapters/appium/appium-adapter.ts +4 -4
  369. package/src/generators/test-generator/adapters/appium/os-support.ts +176 -0
  370. package/src/generators/test-generator/adapters/appium/templates/after-all.hbs +18 -0
  371. package/src/generators/test-generator/adapters/appium/templates/after-each.hbs +18 -0
  372. package/src/generators/test-generator/adapters/appium/templates/before-all.hbs +18 -0
  373. package/src/generators/test-generator/adapters/appium/templates/steps/actions/alert-fill-action.hbs +9 -2
  374. package/src/generators/test-generator/adapters/appium/templates/steps/actions/capture-variable.hbs +24 -1
  375. package/src/generators/test-generator/adapters/appium/templates/steps/actions/click-at-position-action.hbs +1 -0
  376. package/src/generators/test-generator/adapters/appium/templates/steps/actions/click-element-with-text.hbs +1 -1
  377. package/src/generators/test-generator/adapters/appium/templates/steps/actions/double-click-action.hbs +7 -0
  378. package/src/generators/test-generator/adapters/appium/templates/steps/actions/frame-enter-action.hbs +3 -6
  379. package/src/generators/test-generator/adapters/appium/templates/steps/actions/hover-action.hbs +6 -2
  380. package/src/generators/test-generator/adapters/appium/templates/steps/actions/hover-element-with-text.hbs +4 -3
  381. package/src/generators/test-generator/adapters/appium/templates/steps/actions/table-paginate-action.hbs +3 -0
  382. package/src/generators/test-generator/adapters/appium/templates/steps/actions/unknown-element-action.hbs +9 -0
  383. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/have-value-assertion.hbs +34 -1
  384. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/label-value-assertion.hbs +14 -6
  385. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/visible-assertion.hbs +1 -1
  386. package/src/generators/test-generator/adapters/appium/templates/steps/gestures/go-back-action.hbs +21 -0
  387. package/src/generators/test-generator/adapters/appium/templates/steps/gestures/long-press-action.hbs +4 -0
  388. package/src/generators/test-generator/adapters/appium/templates/steps/gestures/pinch-zoom-action.hbs +4 -0
  389. package/src/generators/test-generator/adapters/appium/templates/steps/gestures/set-geolocation-action.hbs +16 -0
  390. package/src/generators/test-generator/adapters/appium/templates/steps/partials/locator.hbs +9 -1
  391. package/src/generators/test-generator/adapters/appium/templates/test-file.hbs +62 -23
  392. package/src/generators/test-generator/adapters/index.ts +1 -1
  393. package/src/generators/test-generator/adapters/playwright/playwright-adapter.ts +4 -4
  394. package/src/generators/test-generator/adapters/playwright/templates/after-all.hbs +19 -1
  395. package/src/generators/test-generator/adapters/playwright/templates/after-each.hbs +18 -0
  396. package/src/generators/test-generator/adapters/playwright/templates/before-all.hbs +19 -1
  397. package/src/generators/test-generator/adapters/playwright/templates/imports.hbs +3 -0
  398. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/check-action.hbs +6 -1
  399. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/click-at-position-action.hbs +23 -0
  400. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/expand-action.hbs +8 -8
  401. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/fill-editor-action.hbs +7 -2
  402. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row-nth.hbs +7 -2
  403. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-action-in-row.hbs +7 -2
  404. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/table-paginate-action.hbs +5 -0
  405. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/uncheck-action.hbs +3 -1
  406. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/unknown-element-action.hbs +1 -1
  407. package/src/generators/test-generator/adapters/playwright/templates/steps/actions/wait-for-page.hbs +18 -1
  408. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/all-contain-assertion.hbs +32 -4
  409. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/all-contain-element.hbs +5 -2
  410. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/checked-assertion.hbs +5 -1
  411. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/column-cell-assertion.hbs +13 -2
  412. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -1
  413. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-role-variable-assertion.hbs +2 -2
  414. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/disabled-with-variable-assertion.hbs +1 -1
  415. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/have-text-assertion.hbs +1 -1
  416. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-role-variable-assertion.hbs +2 -2
  417. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/hidden-with-variable-assertion.hbs +1 -1
  418. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/not-checked-assertion.hbs +2 -1
  419. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/selected-assertion.hbs +21 -3
  420. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/state-with-filter-assertion.hbs +20 -2
  421. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-empty.hbs +4 -1
  422. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-match-data.hbs +4 -1
  423. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-count.hbs +4 -1
  424. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-exists.hbs +12 -4
  425. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/table-row-not-exists.hbs +14 -2
  426. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-role-variable-assertion.hbs +3 -3
  427. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-value-assertion.hbs +1 -1
  428. package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/visible-with-variable-assertion.hbs +1 -1
  429. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/checked-opts.hbs +8 -0
  430. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-base.hbs +8 -8
  431. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-nth.hbs +1 -1
  432. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/id.hbs +1 -1
  433. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator-strategies/testid.hbs +1 -1
  434. package/src/generators/test-generator/adapters/playwright/templates/steps/partials/locator.hbs +8 -8
  435. package/src/generators/test-generator/adapters/playwright/templates/test-file.hbs +10 -8
  436. package/src/generators/test-generator/code-generator.ts +181 -46
  437. package/src/generators/test-generator/diagnostics.ts +117 -6
  438. package/src/generators/test-generator/patterns/index.ts +175 -24
  439. package/src/generators/test-generator/patterns/types.ts +8 -0
  440. package/src/generators/test-generator/patterns/with-parent-scope.ts +41 -0
  441. package/src/generators/test-generator/step-mapper.ts +277 -43
  442. package/src/generators/test-generator/template-engine.ts +21 -21
  443. package/src/generators/test-generator/utils/data-resolver.ts +23 -2
  444. package/src/generators/test-generator/utils/dialog-scope-identity.ts +71 -0
  445. package/src/generators/test-generator/utils/escape-js-string.ts +24 -0
  446. package/src/generators/test-generator/utils/nearest-match.ts +55 -0
  447. package/src/generators/test-generator/utils/selector-entry-fields.ts +131 -0
  448. package/src/generators/test-generator/utils/selector-entry-walk.ts +58 -0
  449. package/src/generators/test-generator/utils/selector-nth-validation.ts +99 -0
  450. package/src/generators/test-generator/utils/selector-resolver.ts +333 -28
  451. package/src/generators/test-generator/utils/selector-type-validation.ts +87 -0
  452. package/src/harness/audit.ts +55 -30
  453. package/src/harness/capability-plan.ts +33 -1
  454. package/src/harness/catalog/drivers.yaml +1 -1
  455. package/src/harness/catalog/universal-viewpoints.yaml +145 -0
  456. package/src/harness/data-driven-lint.ts +192 -32
  457. package/src/harness/parse.ts +7 -1
  458. package/src/harness/repair.ts +8 -1
  459. package/src/harness/script-check.ts +186 -21
  460. package/src/harness/sensors.ts +75 -1
  461. package/src/harness/viewpoint-ledger.ts +26 -5
  462. package/src/index.ts +7 -0
  463. package/src/orchestrator/project-initializer.ts +17 -0
  464. package/src/orchestrator/report-sanitize-reporter-install.ts +109 -0
  465. package/src/orchestrator/templates/ai-src/commands/delivery.md +4 -3
  466. package/src/orchestrator/templates/ai-src/commands/run-test.md +9 -1
  467. package/src/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +10 -0
  468. package/src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +14 -5
  469. package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +62 -3
  470. package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +126 -11
  471. package/src/orchestrator/templates/ai-src/skills/sungen-mobile-gestures/SKILL.md +16 -1
  472. package/src/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md +12 -0
  473. package/src/orchestrator/templates/ai-src/skills/sungen-selector-keys/SKILL.md +19 -5
  474. package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +88 -2
  475. package/src/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md +62 -5
  476. package/src/orchestrator/templates/ai-src/skills/sungen-test-design-techniques/SKILL.md +13 -0
  477. package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md +59 -10
  478. package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-f-mobile-native.md +419 -0
  479. package/src/orchestrator/templates/playwright.config.ts +7 -0
  480. package/src/orchestrator/templates/readme.md +1 -1
  481. package/src/orchestrator/templates/specs-checked-state.ts +324 -0
  482. package/src/orchestrator/templates/specs-pw-shape-reporter.ts +0 -0
  483. package/src/orchestrator/templates/specs-report-path-sanitize-reporter.ts +142 -0
  484. package/src/orchestrator/templates/specs-url-assert.ts +101 -28
  485. package/src/orchestrator/templates/wdio.conf.ts +105 -1
  486. package/src/utils/selector-types.ts +54 -5
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.probeControl = probeControl;
4
+ exports.setCheckedState = setCheckedState;
5
+ exports.expectCheckedState = expectCheckedState;
6
+ /**
7
+ * Budget for EACH PHASE of a check/uncheck step — classification, the action, and the post-click
8
+ * verification each get their own (deliberately: see setCheckedState). So the worst case is a small
9
+ * multiple of this, not this. Raise it for a slow CI box with `SUNGEN_TOGGLE_TIMEOUT_MS`; without an
10
+ * escape hatch this would silently override a project that raised Playwright's own `actionTimeout`.
11
+ */
12
+ const ENV_TIMEOUT = Number(process.env.SUNGEN_TOGGLE_TIMEOUT_MS);
13
+ // Guard the parse: `=0` means "no timeout" to Playwright (hang forever) and a negative is nonsense —
14
+ // neither should be inherited from a typo'd env var.
15
+ const TOGGLE_TIMEOUT_MS = Number.isFinite(ENV_TIMEOUT) && ENV_TIMEOUT > 0 ? ENV_TIMEOUT : 8000;
16
+ const POLL_INTERVAL_MS = 100;
17
+ /**
18
+ * Runs IN THE PAGE, so it must stay self-contained: Playwright serialises it and the browser has
19
+ * none of this module's scope.
20
+ *
21
+ * It also must contain NO inner function of its own — not even an arrow helper. A bundler with
22
+ * keepNames (esbuild, which is what Playwright itself transpiles specs with) rewrites every named
23
+ * inner function to `__name(fn, "…")`, that wrapper travels inside the serialised source, and the
24
+ * page throws `ReferenceError: __name is not defined` on EVERY check step. Straight-line code with
25
+ * the normalise repeated inline is the price of being serialisable; `tests/runtime/
26
+ * checked-state.run.ts` pins it so the next edit cannot quietly reintroduce a helper.
27
+ *
28
+ * Structurally typed rather than via the DOM lib names because this file is also typechecked
29
+ * inside the compiler build, whose tsconfig carries no DOM lib.
30
+ */
31
+ function probeControl(node, declared) {
32
+ const el = node;
33
+ const tag = String(el.tagName ?? '').trim().toLowerCase(); // lowercase: XHTML serves it so
34
+ const type = String(el.type ?? '').trim().toLowerCase();
35
+ const role = String(el.getAttribute('role') ?? '').trim().toLowerCase();
36
+ const ariaCheckableRole = role === 'checkbox' || role === 'radio' || role === 'switch';
37
+ const buttonLike = tag === 'button' || role === 'button'
38
+ || (tag === 'input' && (type === 'button' || type === 'submit' || type === 'reset'));
39
+ // A DECLARED signal wins over every ARIA reading below (issue #730). The author reached for this
40
+ // escape hatch precisely because the component publishes no usable ARIA, so second-guessing them
41
+ // from a stray role would put the step back on the path that could not work. Self OR descendant:
42
+ // a card picker swaps the class on the control itself, while a custom checkbox often mounts a
43
+ // checkmark <svg class="is-checked"> inside instead — both are the same declaration to the author.
44
+ // `classList.contains` is exact-token by definition; `[class~="…"]` is its selector equivalent,
45
+ // so neither needs the class escaped and neither can half-match ("is-checked-disabled").
46
+ if (declared && declared.class) {
47
+ const onSelf = el.classList != null && el.classList.contains(declared.class);
48
+ const onChild = !onSelf && el.querySelector('[class~="' + declared.class + '"]') != null;
49
+ return { source: 'class', on: onSelf || onChild, buttonLike };
50
+ }
51
+ // The same declaration published as a boolean attribute instead of a class. Self ONLY, unlike the
52
+ // class above: a class swap can legitimately live on a checkmark child, but `data-checked` on a
53
+ // descendant is a different control's state, and reading it would assert the wrong element.
54
+ if (declared && declared.attribute) {
55
+ const raw = el.getAttribute(declared.attribute);
56
+ return { source: 'attribute', on: String(raw ?? '').trim().toLowerCase() === 'true', buttonLike };
57
+ }
58
+ // A native input needs no ARIA attribute — Playwright reads `.checked` directly.
59
+ if (tag === 'input' && (type === 'checkbox' || type === 'radio'))
60
+ return { source: 'native', on: false, buttonLike };
61
+ // An ARIA checkable publishes state through `aria-checked`, which is what Playwright reads. Only
62
+ // hand it over when that attribute is actually there: `<button role="switch" aria-pressed="…">`
63
+ // is a common authoring slip, and routing it to .check() makes Playwright click, re-read the
64
+ // aria-checked that does not exist, and die on "did not change its state".
65
+ if (ariaCheckableRole && el.hasAttribute('aria-checked'))
66
+ return { source: 'native', on: false, buttonLike };
67
+ if (el.hasAttribute('aria-pressed')) {
68
+ return { source: 'aria-pressed', on: String(el.getAttribute('aria-pressed') ?? '').trim().toLowerCase() === 'true', buttonLike };
69
+ }
70
+ if (el.hasAttribute('aria-checked')) {
71
+ return { source: 'aria-checked', on: String(el.getAttribute('aria-checked') ?? '').trim().toLowerCase() === 'true', buttonLike };
72
+ }
73
+ // Role claims checkable but nothing is published — let Playwright raise its own, precise error.
74
+ if (ariaCheckableRole)
75
+ return { source: 'native', on: false, buttonLike };
76
+ return { source: 'none', on: false, buttonLike };
77
+ }
78
+ /** The declaration both helpers forward into the page. Undefined when nothing was declared, so a
79
+ * control with real ARIA keeps being read exactly as it was before any of this existed. */
80
+ const declaredSignal = (options) => (options?.checkedClass ? { class: options.checkedClass }
81
+ : options?.checkedAttribute ? { attribute: options.checkedAttribute }
82
+ : undefined);
83
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
84
+ /**
85
+ * Time left on a budget, floored at 250ms. Never 0 — to Playwright that means "no timeout", i.e.
86
+ * hang forever. And never a sliver either: a 1ms floor makes the last poll fail with
87
+ * `Timeout 1ms exceeded`, which masks the real, explanatory error this helper is about to throw.
88
+ * The floor lets a budget overrun by at most 250ms; the loops below terminate on the deadline.
89
+ */
90
+ const left = (deadline) => Math.max(250, deadline - Date.now());
91
+ /** Read the live state. A REMOVED attribute means off: `aria-pressed={on || undefined}` is a common
92
+ * React/Vue idiom, so requiring a literal "false" would fail a control that is correctly off. */
93
+ async function readOn(target, attr, deadline) {
94
+ const raw = await target.getAttribute(attr, { timeout: left(deadline) });
95
+ return String(raw ?? '').trim().toLowerCase() === 'true';
96
+ }
97
+ /**
98
+ * Drive `target` to the requested on/off state, idempotently.
99
+ *
100
+ * @param target the control
101
+ * @param want `true` = checked/pressed, `false` = unchecked/unpressed
102
+ * @param label the `[Selector Ref]` from the feature file, used only in error messages
103
+ * @param options.checkedClass `checked:`/`selected:` from selectors.yaml — the class marking ON,
104
+ * for a control that publishes no ARIA at all (issue #730). Overrides every ARIA reading.
105
+ * @param options.checkedAttribute the same declaration published as a boolean attribute
106
+ * ('true'/'false') instead of a class. A selector declares one or the other, never both.
107
+ */
108
+ async function setCheckedState(target, want, label, options) {
109
+ const timeout = options?.timeout ?? TOGGLE_TIMEOUT_MS;
110
+ const declared = declaredSignal(options);
111
+ // TWO budgets, not one shared deadline: a control that hydrates late would otherwise spend the
112
+ // whole budget being classified and leave the post-click check a single sample — which then
113
+ // reports "the click landed on the label" when the real problem was the clock.
114
+ const classifyDeadline = Date.now() + timeout;
115
+ // `locator.evaluate` waits only for ATTACHED. Playwright's own .check() re-resolved the locator on
116
+ // every actionability retry, so a control that gains its role/aria-* on hydration still worked —
117
+ // classifying once at first attach would turn a slow mount into a hard failure.
118
+ let probe = await target.evaluate(probeControl, declared, { timeout: left(classifyDeadline) });
119
+ while (probe.source === 'none' && classifyDeadline - Date.now() > POLL_INTERVAL_MS) {
120
+ await sleep(POLL_INTERVAL_MS);
121
+ probe = await target.evaluate(probeControl, declared, { timeout: left(classifyDeadline) });
122
+ }
123
+ if (probe.source === 'native') {
124
+ if (want)
125
+ await target.check({ timeout });
126
+ else
127
+ await target.uncheck({ timeout });
128
+ return;
129
+ }
130
+ // A declared class: drive it the way the ARIA path below drives a toggle — click ONLY when the
131
+ // current state differs, then require the class to reach the requested state. Same idempotence,
132
+ // and the same refusal to report success on a blind click.
133
+ if (probe.source === 'class' || probe.source === 'attribute') {
134
+ if (probe.on === want)
135
+ return;
136
+ await target.click({ timeout });
137
+ const classStart = Date.now();
138
+ const classDeadline = classStart + timeout;
139
+ for (;;) {
140
+ const after = await target.evaluate(probeControl, declared, { timeout: left(classDeadline) });
141
+ if (after.on === want)
142
+ return;
143
+ if (classDeadline - Date.now() <= POLL_INTERVAL_MS) {
144
+ throw new Error(`[${label}] did not become ${want ? 'checked' : 'unchecked'} within ${Date.now() - classStart}ms of `
145
+ + `being clicked — the declared ${probe.source} "${declared?.class ?? declared?.attribute}" still reads `
146
+ + `${want ? 'off' : 'on'}${probe.source === 'class' ? ' on the element and on its descendants' : ''}. `
147
+ + `Either the click landed on the label rather than the control, or that is not the `
148
+ + `${probe.source} this component swaps for its on/off state.`);
149
+ }
150
+ await sleep(POLL_INTERVAL_MS);
151
+ }
152
+ }
153
+ if (probe.source === 'none') {
154
+ // Absence on a PRESSABLE control means off — a toggle written as `aria-pressed={on || undefined}`
155
+ // (React/Vue, and several component libraries a QA team does not own) drops the attribute
156
+ // entirely when unpressed. Treating that as an error made `uncheck` pass on the first run and
157
+ // fail on the second, which is precisely the rerun-dependent flake this helper exists to stop.
158
+ if (probe.buttonLike) {
159
+ if (!want) {
160
+ // Nothing to do — but say so, because the alternative is a green step that did nothing at
161
+ // all (a mis-resolved selector pointing at a plain button looks exactly like this).
162
+ console.warn(`[sungen] uncheck [${label}]: the control publishes no aria-pressed/aria-checked, so it was `
163
+ + `read as already unpressed and NOT clicked. If it should have been a toggle, expose `
164
+ + `aria-pressed in both states; if this is not a toggle at all, the step is a no-op.`);
165
+ return;
166
+ }
167
+ // Not a blind click: press once, then REQUIRE the control to publish the requested state.
168
+ // A plain button publishes nothing afterwards either, so it still fails — just one click later.
169
+ await target.click({ timeout });
170
+ const pressedStart = Date.now();
171
+ const pressedDeadline = pressedStart + timeout;
172
+ for (;;) {
173
+ const after = await target.evaluate(probeControl, undefined, { timeout: left(pressedDeadline) });
174
+ if (after.source !== 'none' && after.on === want)
175
+ return;
176
+ if (pressedDeadline - Date.now() <= POLL_INTERVAL_MS) {
177
+ throw new Error(`Cannot check [${label}] — it published no aria-pressed/aria-checked before the click and `
178
+ + `still none ${Date.now() - pressedStart}ms after it, so it is a plain button rather than a `
179
+ + `toggle. Give the control a real ARIA toggle state, or use "toggles [${label}]" if an `
180
+ + `unconditional flip is what you meant.`);
181
+ }
182
+ await sleep(POLL_INTERVAL_MS);
183
+ }
184
+ }
185
+ // Not pressable and publishes nothing — there is no reading of this that makes the step meaningful.
186
+ throw new Error(`Cannot ${want ? 'check' : 'uncheck'} [${label}] — it is not a checkbox/radio/switch, is not a `
187
+ + `button, and publishes no aria-pressed/aria-checked, so it has no on/off state to set. Point the `
188
+ + `selector at the control itself, or give it a real ARIA toggle role.`);
189
+ }
190
+ const attr = probe.source;
191
+ // Already in the requested state → nothing to do. This is the idempotence `check` promises.
192
+ if (probe.on === want)
193
+ return;
194
+ await target.click({ timeout });
195
+ // Fresh budget: this measures the CONTROL's reaction, not time already spent finding it.
196
+ const verifyStart = Date.now();
197
+ const verifyDeadline = verifyStart + timeout;
198
+ for (;;) {
199
+ if (await readOn(target, attr, verifyDeadline) === want)
200
+ return;
201
+ if (verifyDeadline - Date.now() <= POLL_INTERVAL_MS) {
202
+ throw new Error(`[${label}] did not become ${want ? 'pressed' : 'unpressed'} within ${Date.now() - verifyStart}ms of being `
203
+ + `clicked — ${attr} still reads ${want ? 'off' : 'on'}. Either the click landed on the label rather than `
204
+ + `the control, or the handler did not change the state.`);
205
+ }
206
+ await sleep(POLL_INTERVAL_MS);
207
+ }
208
+ }
209
+ /**
210
+ * Assert the on/off state of the same control family — the read side of #675.
211
+ *
212
+ * `expect(locator).toBeChecked()` throws the identical "Not a checkbox or radio button" on a
213
+ * `<button aria-pressed>`, so driving a toggle worked while asserting it did not. Polls like
214
+ * Playwright's own web-first assertions rather than sampling once, and reads state exactly the way
215
+ * setCheckedState does, so an action and the assertion after it can never disagree about what the
216
+ * control says. Uses `locator.isChecked()` (not `expect`) for the native family, which keeps this
217
+ * file free of any test-runner dependency.
218
+ */
219
+ async function expectCheckedState(target, expected, label, options) {
220
+ const timeout = options?.timeout ?? TOGGLE_TIMEOUT_MS;
221
+ // Same signal the action side drives (issue #730) — passing it here is what keeps the invariant
222
+ // above true for a class-only control too: `source: 'class'` falls into the generic `probe.on`
223
+ // branch below, so check-then-assert cannot disagree.
224
+ const declared = declaredSignal(options);
225
+ const start = Date.now();
226
+ const deadline = start + timeout;
227
+ for (;;) {
228
+ const probe = await target.evaluate(probeControl, declared, { timeout: left(deadline) });
229
+ let actual = null;
230
+ if (probe.source === 'native')
231
+ actual = await target.isChecked({ timeout: left(deadline) });
232
+ else if (probe.source !== 'none')
233
+ actual = probe.on;
234
+ else if (probe.buttonLike) {
235
+ // Absence on a pressable control reads as off, mirroring setCheckedState. But a plain button
236
+ // and a correctly-off toggle are indistinguishable HERE, and this is an ASSERTION: returning
237
+ // green having verified nothing is worse than the loud "Not a checkbox or radio button" it
238
+ // replaced. So say so, exactly as the action side does for the same reading.
239
+ if (!expected) {
240
+ console.warn(`[sungen] see [${label}] is unchecked: the control publishes no aria-pressed/aria-checked, `
241
+ + `so it was read as unpressed WITHOUT verifying anything. If it should be a toggle, expose `
242
+ + `aria-pressed in both states; if it is not a toggle, this assertion proves nothing.`);
243
+ }
244
+ actual = false;
245
+ }
246
+ if (actual === expected)
247
+ return;
248
+ if (deadline - Date.now() <= POLL_INTERVAL_MS) {
249
+ if (actual === null) {
250
+ throw new Error(`Cannot assert [${label}] is ${expected ? 'checked' : 'unchecked'} — it is not a `
251
+ + `checkbox/radio/switch, is not a button, and publishes no aria-pressed/aria-checked, so it `
252
+ + `reports no state to assert. Point the selector at the control itself, or give it a real `
253
+ + `ARIA toggle role.`);
254
+ }
255
+ throw new Error(`Expected [${label}] to be ${expected ? 'checked' : 'unchecked'}, but it is `
256
+ + `${actual ? 'checked' : 'unchecked'} after ${Date.now() - start}ms.`);
257
+ }
258
+ await sleep(POLL_INTERVAL_MS);
259
+ }
260
+ }
261
+ //# sourceMappingURL=specs-checked-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specs-checked-state.js","sourceRoot":"","sources":["../../../src/orchestrator/templates/specs-checked-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,324 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * Sungen checked-state helper — auto-generated into specs/checked-state.ts. DO NOT EDIT.
4
+ *
5
+ * Playwright's `.check()` / `.uncheck()` accept ONLY native checkbox/radio inputs and
6
+ * `role=checkbox|radio|switch`. Anything else throws "Not a checkbox or radio button" (#675).
7
+ * A toggle BUTTON — `<button aria-pressed>`, the correct ARIA pattern for a pressed/unpressed
8
+ * control — is none of those, so a bare `.check()` could never drive one.
9
+ *
10
+ * Rewriting the Gherkin to `click` is NOT an equivalent workaround, and that is the whole reason
11
+ * this helper exists: `click` flips UNCONDITIONALLY, so a scenario that re-runs, or starts from an
12
+ * unknown state, drives the toggle the WRONG way. Idempotence — end up in the requested state
13
+ * regardless of where you started — is the entire meaning of `check` / `uncheck`.
14
+ *
15
+ * The mechanism is chosen from the ELEMENT at run time, not from the selector's declared role,
16
+ * because the resolved selector is very often a testid/CSS locator carrying no role at all — so
17
+ * codegen cannot know what it will hit.
18
+ *
19
+ * Deliberately depends on NOTHING but the `Locator` TYPE: no `expect`, no test-runner context. That
20
+ * keeps the branching testable against a fake locator without a browser (tests/runtime/
21
+ * checked-state.run.ts) — this file runs inside every user's suite, so its logic is worth pinning.
22
+ */
23
+ import type { Locator } from '@playwright/test';
24
+
25
+ /**
26
+ * Budget for EACH PHASE of a check/uncheck step — classification, the action, and the post-click
27
+ * verification each get their own (deliberately: see setCheckedState). So the worst case is a small
28
+ * multiple of this, not this. Raise it for a slow CI box with `SUNGEN_TOGGLE_TIMEOUT_MS`; without an
29
+ * escape hatch this would silently override a project that raised Playwright's own `actionTimeout`.
30
+ */
31
+ const ENV_TIMEOUT = Number(process.env.SUNGEN_TOGGLE_TIMEOUT_MS);
32
+ // Guard the parse: `=0` means "no timeout" to Playwright (hang forever) and a negative is nonsense —
33
+ // neither should be inherited from a typo'd env var.
34
+ const TOGGLE_TIMEOUT_MS = Number.isFinite(ENV_TIMEOUT) && ENV_TIMEOUT > 0 ? ENV_TIMEOUT : 8_000;
35
+ const POLL_INTERVAL_MS = 100;
36
+
37
+ /** A signal DECLARED in selectors.yaml: the class token, or the boolean attribute, marking ON. */
38
+ export interface DeclaredSignal { class?: string; attribute?: string }
39
+
40
+ /** Where the control publishes its on/off state — decided in the page, from the real element. */
41
+ export type StateSource = 'native' | 'aria-pressed' | 'aria-checked' | 'class' | 'attribute' | 'none';
42
+ export interface ControlProbe {
43
+ source: StateSource;
44
+ /** Current state, already normalised. Meaningless when `source` is 'native' (Playwright reads it). */
45
+ on: boolean;
46
+ /** Button-like: a control a human would press. Decides how a MISSING state is read — see below. */
47
+ buttonLike: boolean;
48
+ }
49
+
50
+ /**
51
+ * Runs IN THE PAGE, so it must stay self-contained: Playwright serialises it and the browser has
52
+ * none of this module's scope.
53
+ *
54
+ * It also must contain NO inner function of its own — not even an arrow helper. A bundler with
55
+ * keepNames (esbuild, which is what Playwright itself transpiles specs with) rewrites every named
56
+ * inner function to `__name(fn, "…")`, that wrapper travels inside the serialised source, and the
57
+ * page throws `ReferenceError: __name is not defined` on EVERY check step. Straight-line code with
58
+ * the normalise repeated inline is the price of being serialisable; `tests/runtime/
59
+ * checked-state.run.ts` pins it so the next edit cannot quietly reintroduce a helper.
60
+ *
61
+ * Structurally typed rather than via the DOM lib names because this file is also typechecked
62
+ * inside the compiler build, whose tsconfig carries no DOM lib.
63
+ */
64
+ export function probeControl(node: unknown, declared?: DeclaredSignal): ControlProbe {
65
+ const el = node as {
66
+ tagName: string; type?: string;
67
+ getAttribute(n: string): string | null; hasAttribute(n: string): boolean;
68
+ classList: { contains(c: string): boolean };
69
+ querySelector(s: string): unknown;
70
+ };
71
+ const tag = String(el.tagName ?? '').trim().toLowerCase(); // lowercase: XHTML serves it so
72
+ const type = String(el.type ?? '').trim().toLowerCase();
73
+ const role = String(el.getAttribute('role') ?? '').trim().toLowerCase();
74
+ const ariaCheckableRole = role === 'checkbox' || role === 'radio' || role === 'switch';
75
+ const buttonLike = tag === 'button' || role === 'button'
76
+ || (tag === 'input' && (type === 'button' || type === 'submit' || type === 'reset'));
77
+
78
+ // A DECLARED signal wins over every ARIA reading below (issue #730). The author reached for this
79
+ // escape hatch precisely because the component publishes no usable ARIA, so second-guessing them
80
+ // from a stray role would put the step back on the path that could not work. Self OR descendant:
81
+ // a card picker swaps the class on the control itself, while a custom checkbox often mounts a
82
+ // checkmark <svg class="is-checked"> inside instead — both are the same declaration to the author.
83
+ // `classList.contains` is exact-token by definition; `[class~="…"]` is its selector equivalent,
84
+ // so neither needs the class escaped and neither can half-match ("is-checked-disabled").
85
+ if (declared && declared.class) {
86
+ const onSelf = el.classList != null && el.classList.contains(declared.class);
87
+ const onChild = !onSelf && el.querySelector('[class~="' + declared.class + '"]') != null;
88
+ return { source: 'class', on: onSelf || onChild, buttonLike };
89
+ }
90
+ // The same declaration published as a boolean attribute instead of a class. Self ONLY, unlike the
91
+ // class above: a class swap can legitimately live on a checkmark child, but `data-checked` on a
92
+ // descendant is a different control's state, and reading it would assert the wrong element.
93
+ if (declared && declared.attribute) {
94
+ const raw = el.getAttribute(declared.attribute);
95
+ return { source: 'attribute', on: String(raw ?? '').trim().toLowerCase() === 'true', buttonLike };
96
+ }
97
+
98
+ // A native input needs no ARIA attribute — Playwright reads `.checked` directly.
99
+ if (tag === 'input' && (type === 'checkbox' || type === 'radio')) return { source: 'native', on: false, buttonLike };
100
+ // An ARIA checkable publishes state through `aria-checked`, which is what Playwright reads. Only
101
+ // hand it over when that attribute is actually there: `<button role="switch" aria-pressed="…">`
102
+ // is a common authoring slip, and routing it to .check() makes Playwright click, re-read the
103
+ // aria-checked that does not exist, and die on "did not change its state".
104
+ if (ariaCheckableRole && el.hasAttribute('aria-checked')) return { source: 'native', on: false, buttonLike };
105
+ if (el.hasAttribute('aria-pressed')) {
106
+ return { source: 'aria-pressed', on: String(el.getAttribute('aria-pressed') ?? '').trim().toLowerCase() === 'true', buttonLike };
107
+ }
108
+ if (el.hasAttribute('aria-checked')) {
109
+ return { source: 'aria-checked', on: String(el.getAttribute('aria-checked') ?? '').trim().toLowerCase() === 'true', buttonLike };
110
+ }
111
+ // Role claims checkable but nothing is published — let Playwright raise its own, precise error.
112
+ if (ariaCheckableRole) return { source: 'native', on: false, buttonLike };
113
+ return { source: 'none', on: false, buttonLike };
114
+ }
115
+
116
+ /** The declaration both helpers forward into the page. Undefined when nothing was declared, so a
117
+ * control with real ARIA keeps being read exactly as it was before any of this existed. */
118
+ const declaredSignal = (
119
+ options?: { checkedClass?: string; checkedAttribute?: string },
120
+ ): DeclaredSignal | undefined => (
121
+ options?.checkedClass ? { class: options.checkedClass }
122
+ : options?.checkedAttribute ? { attribute: options.checkedAttribute }
123
+ : undefined
124
+ );
125
+
126
+ const sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));
127
+ /**
128
+ * Time left on a budget, floored at 250ms. Never 0 — to Playwright that means "no timeout", i.e.
129
+ * hang forever. And never a sliver either: a 1ms floor makes the last poll fail with
130
+ * `Timeout 1ms exceeded`, which masks the real, explanatory error this helper is about to throw.
131
+ * The floor lets a budget overrun by at most 250ms; the loops below terminate on the deadline.
132
+ */
133
+ const left = (deadline: number): number => Math.max(250, deadline - Date.now());
134
+
135
+ /** Read the live state. A REMOVED attribute means off: `aria-pressed={on || undefined}` is a common
136
+ * React/Vue idiom, so requiring a literal "false" would fail a control that is correctly off. */
137
+ async function readOn(target: Locator, attr: 'aria-pressed' | 'aria-checked', deadline: number): Promise<boolean> {
138
+ const raw = await target.getAttribute(attr, { timeout: left(deadline) });
139
+ return String(raw ?? '').trim().toLowerCase() === 'true';
140
+ }
141
+
142
+ /**
143
+ * Drive `target` to the requested on/off state, idempotently.
144
+ *
145
+ * @param target the control
146
+ * @param want `true` = checked/pressed, `false` = unchecked/unpressed
147
+ * @param label the `[Selector Ref]` from the feature file, used only in error messages
148
+ * @param options.checkedClass `checked:`/`selected:` from selectors.yaml — the class marking ON,
149
+ * for a control that publishes no ARIA at all (issue #730). Overrides every ARIA reading.
150
+ * @param options.checkedAttribute the same declaration published as a boolean attribute
151
+ * ('true'/'false') instead of a class. A selector declares one or the other, never both.
152
+ */
153
+ export async function setCheckedState(
154
+ target: Locator, want: boolean, label: string,
155
+ options?: { timeout?: number; checkedClass?: string; checkedAttribute?: string },
156
+ ): Promise<void> {
157
+ const timeout = options?.timeout ?? TOGGLE_TIMEOUT_MS;
158
+ const declared = declaredSignal(options);
159
+ // TWO budgets, not one shared deadline: a control that hydrates late would otherwise spend the
160
+ // whole budget being classified and leave the post-click check a single sample — which then
161
+ // reports "the click landed on the label" when the real problem was the clock.
162
+ const classifyDeadline = Date.now() + timeout;
163
+
164
+ // `locator.evaluate` waits only for ATTACHED. Playwright's own .check() re-resolved the locator on
165
+ // every actionability retry, so a control that gains its role/aria-* on hydration still worked —
166
+ // classifying once at first attach would turn a slow mount into a hard failure.
167
+ let probe = await target.evaluate(probeControl, declared, { timeout: left(classifyDeadline) });
168
+ while (probe.source === 'none' && classifyDeadline - Date.now() > POLL_INTERVAL_MS) {
169
+ await sleep(POLL_INTERVAL_MS);
170
+ probe = await target.evaluate(probeControl, declared, { timeout: left(classifyDeadline) });
171
+ }
172
+
173
+ if (probe.source === 'native') {
174
+ if (want) await target.check({ timeout });
175
+ else await target.uncheck({ timeout });
176
+ return;
177
+ }
178
+
179
+ // A declared class: drive it the way the ARIA path below drives a toggle — click ONLY when the
180
+ // current state differs, then require the class to reach the requested state. Same idempotence,
181
+ // and the same refusal to report success on a blind click.
182
+ if (probe.source === 'class' || probe.source === 'attribute') {
183
+ if (probe.on === want) return;
184
+ await target.click({ timeout });
185
+ const classStart = Date.now();
186
+ const classDeadline = classStart + timeout;
187
+ for (;;) {
188
+ const after = await target.evaluate(probeControl, declared, { timeout: left(classDeadline) });
189
+ if (after.on === want) return;
190
+ if (classDeadline - Date.now() <= POLL_INTERVAL_MS) {
191
+ throw new Error(
192
+ `[${label}] did not become ${want ? 'checked' : 'unchecked'} within ${Date.now() - classStart}ms of `
193
+ + `being clicked — the declared ${probe.source} "${declared?.class ?? declared?.attribute}" still reads `
194
+ + `${want ? 'off' : 'on'}${probe.source === 'class' ? ' on the element and on its descendants' : ''}. `
195
+ + `Either the click landed on the label rather than the control, or that is not the `
196
+ + `${probe.source} this component swaps for its on/off state.`,
197
+ );
198
+ }
199
+ await sleep(POLL_INTERVAL_MS);
200
+ }
201
+ }
202
+
203
+ if (probe.source === 'none') {
204
+ // Absence on a PRESSABLE control means off — a toggle written as `aria-pressed={on || undefined}`
205
+ // (React/Vue, and several component libraries a QA team does not own) drops the attribute
206
+ // entirely when unpressed. Treating that as an error made `uncheck` pass on the first run and
207
+ // fail on the second, which is precisely the rerun-dependent flake this helper exists to stop.
208
+ if (probe.buttonLike) {
209
+ if (!want) {
210
+ // Nothing to do — but say so, because the alternative is a green step that did nothing at
211
+ // all (a mis-resolved selector pointing at a plain button looks exactly like this).
212
+ console.warn(
213
+ `[sungen] uncheck [${label}]: the control publishes no aria-pressed/aria-checked, so it was `
214
+ + `read as already unpressed and NOT clicked. If it should have been a toggle, expose `
215
+ + `aria-pressed in both states; if this is not a toggle at all, the step is a no-op.`,
216
+ );
217
+ return;
218
+ }
219
+ // Not a blind click: press once, then REQUIRE the control to publish the requested state.
220
+ // A plain button publishes nothing afterwards either, so it still fails — just one click later.
221
+ await target.click({ timeout });
222
+ const pressedStart = Date.now();
223
+ const pressedDeadline = pressedStart + timeout;
224
+ for (;;) {
225
+ const after = await target.evaluate(probeControl, undefined, { timeout: left(pressedDeadline) });
226
+ if (after.source !== 'none' && after.on === want) return;
227
+ if (pressedDeadline - Date.now() <= POLL_INTERVAL_MS) {
228
+ throw new Error(
229
+ `Cannot check [${label}] — it published no aria-pressed/aria-checked before the click and `
230
+ + `still none ${Date.now() - pressedStart}ms after it, so it is a plain button rather than a `
231
+ + `toggle. Give the control a real ARIA toggle state, or use "toggles [${label}]" if an `
232
+ + `unconditional flip is what you meant.`,
233
+ );
234
+ }
235
+ await sleep(POLL_INTERVAL_MS);
236
+ }
237
+ }
238
+ // Not pressable and publishes nothing — there is no reading of this that makes the step meaningful.
239
+ throw new Error(
240
+ `Cannot ${want ? 'check' : 'uncheck'} [${label}] — it is not a checkbox/radio/switch, is not a `
241
+ + `button, and publishes no aria-pressed/aria-checked, so it has no on/off state to set. Point the `
242
+ + `selector at the control itself, or give it a real ARIA toggle role.`,
243
+ );
244
+ }
245
+
246
+ const attr = probe.source;
247
+ // Already in the requested state → nothing to do. This is the idempotence `check` promises.
248
+ if (probe.on === want) return;
249
+ await target.click({ timeout });
250
+
251
+ // Fresh budget: this measures the CONTROL's reaction, not time already spent finding it.
252
+ const verifyStart = Date.now();
253
+ const verifyDeadline = verifyStart + timeout;
254
+ for (;;) {
255
+ if (await readOn(target, attr, verifyDeadline) === want) return;
256
+ if (verifyDeadline - Date.now() <= POLL_INTERVAL_MS) {
257
+ throw new Error(
258
+ `[${label}] did not become ${want ? 'pressed' : 'unpressed'} within ${Date.now() - verifyStart}ms of being `
259
+ + `clicked — ${attr} still reads ${want ? 'off' : 'on'}. Either the click landed on the label rather than `
260
+ + `the control, or the handler did not change the state.`,
261
+ );
262
+ }
263
+ await sleep(POLL_INTERVAL_MS);
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Assert the on/off state of the same control family — the read side of #675.
269
+ *
270
+ * `expect(locator).toBeChecked()` throws the identical "Not a checkbox or radio button" on a
271
+ * `<button aria-pressed>`, so driving a toggle worked while asserting it did not. Polls like
272
+ * Playwright's own web-first assertions rather than sampling once, and reads state exactly the way
273
+ * setCheckedState does, so an action and the assertion after it can never disagree about what the
274
+ * control says. Uses `locator.isChecked()` (not `expect`) for the native family, which keeps this
275
+ * file free of any test-runner dependency.
276
+ */
277
+ export async function expectCheckedState(
278
+ target: Locator, expected: boolean, label: string,
279
+ options?: { timeout?: number; checkedClass?: string; checkedAttribute?: string },
280
+ ): Promise<void> {
281
+ const timeout = options?.timeout ?? TOGGLE_TIMEOUT_MS;
282
+ // Same signal the action side drives (issue #730) — passing it here is what keeps the invariant
283
+ // above true for a class-only control too: `source: 'class'` falls into the generic `probe.on`
284
+ // branch below, so check-then-assert cannot disagree.
285
+ const declared = declaredSignal(options);
286
+ const start = Date.now();
287
+ const deadline = start + timeout;
288
+ for (;;) {
289
+ const probe = await target.evaluate(probeControl, declared, { timeout: left(deadline) });
290
+ let actual: boolean | null = null;
291
+ if (probe.source === 'native') actual = await target.isChecked({ timeout: left(deadline) });
292
+ else if (probe.source !== 'none') actual = probe.on;
293
+ else if (probe.buttonLike) {
294
+ // Absence on a pressable control reads as off, mirroring setCheckedState. But a plain button
295
+ // and a correctly-off toggle are indistinguishable HERE, and this is an ASSERTION: returning
296
+ // green having verified nothing is worse than the loud "Not a checkbox or radio button" it
297
+ // replaced. So say so, exactly as the action side does for the same reading.
298
+ if (!expected) {
299
+ console.warn(
300
+ `[sungen] see [${label}] is unchecked: the control publishes no aria-pressed/aria-checked, `
301
+ + `so it was read as unpressed WITHOUT verifying anything. If it should be a toggle, expose `
302
+ + `aria-pressed in both states; if it is not a toggle, this assertion proves nothing.`,
303
+ );
304
+ }
305
+ actual = false;
306
+ }
307
+ if (actual === expected) return;
308
+ if (deadline - Date.now() <= POLL_INTERVAL_MS) {
309
+ if (actual === null) {
310
+ throw new Error(
311
+ `Cannot assert [${label}] is ${expected ? 'checked' : 'unchecked'} — it is not a `
312
+ + `checkbox/radio/switch, is not a button, and publishes no aria-pressed/aria-checked, so it `
313
+ + `reports no state to assert. Point the selector at the control itself, or give it a real `
314
+ + `ARIA toggle role.`,
315
+ );
316
+ }
317
+ throw new Error(
318
+ `Expected [${label}] to be ${expected ? 'checked' : 'unchecked'}, but it is `
319
+ + `${actual ? 'checked' : 'unchecked'} after ${Date.now() - start}ms.`,
320
+ );
321
+ }
322
+ await sleep(POLL_INTERVAL_MS);
323
+ }
324
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Playwright reporter that rewrites the operator's machine paths out of the JSON result file.
3
+ *
4
+ * The JSON reporter records absolute paths — `config.configFile`, `rootDir`, `projects[]`, every
5
+ * `error.location.file`, attachment paths, and the paths quoted inside stack traces and messages.
6
+ * Teams commit that file next to the spec (sungen delivery reads it), so a username and a machine
7
+ * layout travel into the repository and the deliverable. Nothing downstream needs them absolute.
8
+ *
9
+ * Runs in `onExit()` — after every reporter, the JSON one included, has finished writing — reads the
10
+ * JSON reporter's `outputFile`, rewrites it in place, and stays silent otherwise. Paths under the
11
+ * project root (the directory of `playwright.config.ts`) become project-relative; outside it a path that
12
+ * names a machine (a home directory, a drive) keeps only its basename while any other absolute string
13
+ * — a URL route — is left alone; home directories quoted inside text become `~/`. `sungen results
14
+ * sanitize` applies the same rules to files that already exist.
15
+ *
16
+ * Wired in playwright.config.ts: reporter: [['html'], ['json', {…}], ['./specs/generated/report-path-sanitize-reporter.ts']].
17
+ * Regenerated by `sungen generate` / `sungen update` — DO NOT EDIT.
18
+ */
19
+ import type { FullConfig, Reporter } from '@playwright/test/reporter';
20
+ declare class ReportPathSanitizeReporter implements Reporter {
21
+ private config?;
22
+ onBegin(config: FullConfig): void;
23
+ printsToStdio(): boolean;
24
+ onExit(): Promise<void>;
25
+ private configDir;
26
+ /** The JSON reporter's output file: its `outputFile` option, else the env var the config reads. */
27
+ private jsonOutputFile;
28
+ }
29
+ export default ReportPathSanitizeReporter;
30
+ export declare function sanitizeReportPaths<T>(doc: T, opts: {
31
+ root: string;
32
+ }): {
33
+ doc: T;
34
+ rewritten: number;
35
+ };
36
+ //# sourceMappingURL=specs-report-path-sanitize-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specs-report-path-sanitize-reporter.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/templates/specs-report-path-sanitize-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAItE,cAAM,0BAA2B,YAAW,QAAQ;IAClD,OAAO,CAAC,MAAM,CAAC,CAAa;IAE5B,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAIjC,aAAa,IAAI,OAAO;IAIlB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB7B,OAAO,CAAC,SAAS;IAIjB,mGAAmG;IACnG,OAAO,CAAC,cAAc;CAWvB;AAED,eAAe,0BAA0B,CAAC;AAW1C,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAmBpG"}