@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
@@ -18,9 +18,12 @@
18
18
  * (`--version`, `capability remove`) even when a driver is missing/broken.
19
19
  */
20
20
  import { createRequire } from 'module';
21
+ import * as fs from 'fs';
21
22
  import * as path from 'path';
23
+ import { coreVersion } from '../orchestrator/lockstep-version';
22
24
  import { capabilityRegistry } from './registry';
23
25
  import { LOCAL_DRIVERS, registerCoreCapability } from './builtins';
26
+ import { loadDriverCatalog, readCapabilities } from '../harness/capability';
24
27
 
25
28
  /**
26
29
  * Driver packages relocated out of core, loaded before the in-core `LOCAL_DRIVERS`. As `db`/`api`
@@ -44,18 +47,116 @@ const EXTERNAL_DRIVERS = ['@sungen/driver-ui', '@sungen/driver-db', '@sungen/dri
44
47
  // test-data available out of the box (no `capability add` needed); inert until a field-map/recipe exists.
45
48
  const BUNDLED_DRIVERS = new Set(['@sungen/driver-ui', '@sungen/driver-data-factory']);
46
49
 
50
+ /** One installed copy of a driver package: where it was found from, and which version lives there. */
51
+ export interface DriverCopy {
52
+ /** The anchor the lookup was made from — the project's package.json, or core's own file. */
53
+ anchor: 'project' | 'core';
54
+ resolved: string;
55
+ version: string | undefined;
56
+ }
57
+
58
+ /** `3.2.28-beta.2` and `3.2.28` sit on the same lockstep line; `3.2.20` does not. */
59
+ export function sameVersionLine(a: string | undefined, b: string | undefined): boolean {
60
+ if (!a || !b || a === 'latest' || b === 'latest') return false;
61
+ const line = (v: string) => v.split('-')[0];
62
+ return line(a) === line(b);
63
+ }
64
+
65
+ /**
66
+ * Pick which installed copy of a driver to load.
67
+ *
68
+ * Project-first is right for an OPT-IN driver: `sungen capability add db` installs into the
69
+ * project's node_modules, and a globally-installed core would never see it from its own anchor.
70
+ *
71
+ * It was wrong for a BUNDLED driver. Core pins `@sungen/driver-ui` to its exact version, but the
72
+ * project may hold an older copy — a `^` range from an earlier scaffold, a lock file nobody
73
+ * refreshed — and that copy loaded first, unconditionally. Core 3.2.25 started gating every state
74
+ * clause on `pattern.states` (SG-E021); driver-ui 3.2.20 predates the field; so
75
+ * `see [Filter] button is hidden` threw on the very pattern (`is-hidden`) the message told the
76
+ * author to use. Every `is <state>` step in every project holding a stale driver, on Gherkin that
77
+ * was correct — and the message blamed the Gherkin.
78
+ *
79
+ * So for a bundled driver the copy on core's own version line wins wherever it lives. Only when no
80
+ * copy is on that line does the first one load — and the caller then warns, because that skew is
81
+ * exactly the breakage the user is about to see. An unknown core version (`latest`) keeps the old
82
+ * project-first order: there is no line to match against.
83
+ */
84
+ export function pickDriverCopy(copies: readonly DriverCopy[], core: string, bundled: boolean): DriverCopy | undefined {
85
+ if (!copies.length) return undefined;
86
+ if (bundled && core !== 'latest') {
87
+ const lockstep = copies.find((c) => sameVersionLine(c.version, core));
88
+ if (lockstep) return lockstep;
89
+ }
90
+ return copies[0];
91
+ }
92
+
93
+ function readDriverVersion(req: NodeRequire, name: string, resolved: string): string | undefined {
94
+ // `<pkg>/package.json` is not always exported; fall back to walking up from the entry file.
95
+ try { return req(`${name}/package.json`)?.version; } catch { /* try the walk */ }
96
+ let dir = path.dirname(resolved);
97
+ for (let i = 0; i < 6; i++) {
98
+ try {
99
+ const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'));
100
+ if (pkg?.name === name) return pkg.version;
101
+ } catch { /* keep walking */ }
102
+ const parent = path.dirname(dir);
103
+ if (parent === dir) break;
104
+ dir = parent;
105
+ }
106
+ return undefined;
107
+ }
108
+
109
+ /** The lockstep contract, in the user's terms, with the one command that restores it. */
110
+ function versionSkewWarning(name: string, loaded: string | undefined, core: string, bypassed?: DriverCopy): string {
111
+ const fix = ` Fix: run \`sungen update\` in the project (or \`npm i ${name}@${core}\`) so every @sungen/driver-* matches sungen ${core}.`;
112
+ if (bypassed) {
113
+ return (
114
+ `⚠ sungen: the project holds "${name}" ${bypassed.version ?? '(unknown version)'} but sungen is ${core} — ` +
115
+ `loading core's own ${loaded ?? core} copy instead. The two are published in lockstep; a driver behind core misses ` +
116
+ `metadata core now requires (for the UI driver: every "is hidden"/"is disabled" clause fails SG-E021 on the pattern that should assert it).\n` + fix
117
+ );
118
+ }
119
+ return (
120
+ `⚠ sungen: "${name}" ${loaded ?? '(unknown version)'} is loaded against sungen ${core} — the two are published in lockstep, ` +
121
+ `and a driver on another version line misses metadata core requires (for the UI driver: every "is hidden"/"is disabled" ` +
122
+ `clause fails SG-E021 on the pattern that should assert it).\n` + fix
123
+ );
124
+ }
125
+
47
126
  function loadExternalDriver(name: string): void {
48
- // Resolve from the user's PROJECT first, then from core's own location. Opt-in drivers
49
- // (`sungen capability add db|api`) install into the PROJECT's node_modules — a globally-installed
50
- // core (`npm i -g`) wouldn't see them via a core-anchored `require`. The bundled @sungen/driver-ui
51
- // is a core dependency (co-located with core), so the second anchor finds it.
52
- for (const anchor of [path.join(process.cwd(), 'package.json'), __filename]) {
127
+ const bundled = BUNDLED_DRIVERS.has(name);
128
+ // Look from the user's PROJECT and from core's own location. Opt-in drivers (`sungen capability add
129
+ // db|api`) install into the PROJECT's node_modules — a globally-installed core (`npm i -g`) wouldn't
130
+ // see them via a core-anchored `require`. The bundled @sungen/driver-ui is a core dependency
131
+ // (co-located with core), so the second anchor always has a copy on core's version line.
132
+ const anchors: Array<[DriverCopy['anchor'], string]> = [
133
+ ['project', path.join(process.cwd(), 'package.json')],
134
+ ['core', __filename],
135
+ ];
136
+ const copies: DriverCopy[] = [];
137
+ const requires = new Map<string, NodeRequire>();
138
+ for (const [anchor, file] of anchors) {
53
139
  let req: NodeRequire;
54
- try { req = createRequire(anchor); } catch { continue; }
140
+ try { req = createRequire(file); } catch { continue; }
55
141
  let resolved: string;
56
142
  try { resolved = req.resolve(name); } catch { continue; } // not installed at this anchor → try next
143
+ if (copies.some((c) => c.resolved === resolved)) continue; // one install seen from both anchors
144
+ requires.set(resolved, req);
145
+ copies.push({ anchor, resolved, version: readDriverVersion(req, name, resolved) });
146
+ }
147
+
148
+ const core = coreVersion();
149
+ const chosen = pickDriverCopy(copies, core, bundled);
150
+ if (chosen) {
151
+ if (core !== 'latest' && chosen.version && !sameVersionLine(chosen.version, core)) {
152
+ console.warn(versionSkewWarning(name, chosen.version, core));
153
+ } else if (bundled && chosen.anchor === 'core' && copies[0] !== chosen) {
154
+ // A stale project copy was bypassed. Loading the right one already fixed the compile; the line
155
+ // is there so the stale dependency gets cleaned up rather than lingering under every future run.
156
+ console.warn(versionSkewWarning(name, chosen.version, core, copies[0]));
157
+ }
57
158
  try {
58
- const mod = req(resolved);
159
+ const mod = requires.get(chosen.resolved)!(chosen.resolved);
59
160
  const register: ((r: typeof capabilityRegistry) => void) | undefined = mod?.sungenDriver?.register ?? mod?.register;
60
161
  if (typeof register === 'function') register(capabilityRegistry);
61
162
  } catch (e) {
@@ -68,10 +169,10 @@ function loadExternalDriver(name: string): void {
68
169
  ` Fix: reinstall it (\`sungen capability add ${name.replace(/^@sungen\/driver-/, '')}\`) or remove it.`,
69
170
  );
70
171
  }
71
- return; // found at this anchor (loaded or warned) — don't fall through to other anchors
172
+ return;
72
173
  }
73
174
  // Not resolvable at ANY anchor.
74
- if (BUNDLED_DRIVERS.has(name)) {
175
+ if (bundled) {
75
176
  // A bundled default is missing → broken install, not a declined opt-in. Warn loudly so the user
76
177
  // sees the real cause instead of a wall of "Unrecognized step pattern".
77
178
  console.warn(
@@ -86,9 +187,44 @@ function loadExternalDriver(name: string): void {
86
187
  // Opt-in driver not installed — capabilities are opt-in, so skip silently.
87
188
  }
88
189
 
190
+ /**
191
+ * Should this driver package load for the project's declared platform?
192
+ *
193
+ * Only an **opt-in platform** driver is gated. Three exclusions, each load-bearing:
194
+ * - `kind: 'capability'` (api/db/mock/data-factory) is gated by its ANNOTATION TAG, not by
195
+ * platform. Gating it here would break `@query`/`@api` on a project that legitimately has both.
196
+ * - `bundled: true` (driver-ui) is the BASELINE vocabulary, not a platform choice. Mobile reuses
197
+ * the whole web pattern set — click, fill, visibility — on the appium adapter, so skipping
198
+ * driver-ui on a `platform: mobile` project would delete almost every step the suite uses.
199
+ * - No `platform:` in `qa/capabilities.yaml` → load everything, exactly as before. A project that
200
+ * predates the profile, and every `--framework`-override path, must keep working.
201
+ *
202
+ * A package the catalog does not know stays ungated: an unknown driver is not evidence of a
203
+ * platform mismatch, and silently dropping it would be the hardest failure here to diagnose.
204
+ */
205
+ function servesPlatform(pkg: string, platform: string | undefined): boolean {
206
+ if (!platform) return true;
207
+ const meta = Object.values(loadDriverCatalog()).find((m) => m.package === pkg);
208
+ if (!meta || meta.kind !== 'platform' || meta.bundled) return true;
209
+ if (meta.id === platform) return true;
210
+ // Record what the gate dropped. SG-W001 needs it: without the driver's patterns in the registry a
211
+ // mobile-only step reads as "sungen has no step form for it", which is untrue — the form exists in
212
+ // a vocabulary this project declined. Recording the SKIP is the honest half; naming the step would
213
+ // need a static list that rots on the next pattern added.
214
+ capabilityRegistry.noteGatedDriver(pkg, meta.id, platform);
215
+ return false;
216
+ }
217
+
89
218
  export function discoverAndRegisterCapabilities(): void {
90
219
  if (capabilityRegistry.isPopulated()) return;
91
- for (const name of EXTERNAL_DRIVERS) loadExternalDriver(name); // ui (external) — first, default capability
220
+ // CG-1b — discovery never read the project's platform, so on a machine holding both drivers the
221
+ // mobile vocabulary was live on web projects and vice versa. `platforms:` on the patterns is what
222
+ // makes a cross-platform step FAIL WELL; this is what keeps it from being reachable at all.
223
+ const { platform } = readCapabilities(process.cwd());
224
+ for (const name of EXTERNAL_DRIVERS) {
225
+ if (!servesPlatform(name, platform)) continue;
226
+ loadExternalDriver(name); // ui (external) — first, default capability
227
+ }
92
228
  for (const driver of LOCAL_DRIVERS) driver.register(capabilityRegistry); // db, api (in-core for now)
93
229
  registerCoreCapability(capabilityRegistry); // generic layer, always present, registered last
94
230
  }
@@ -76,6 +76,10 @@ export interface CapabilityDescriptor {
76
76
 
77
77
  export class CapabilityRegistry {
78
78
  private caps = new Map<string, CapabilityDescriptor>();
79
+ /** package → the platform it serves, for drivers the platform gate skipped. See `noteGatedDriver`. */
80
+ private gated = new Map<string, string>();
81
+ /** The project platform those skips were made FOR — the same value for every entry in `gated`. */
82
+ private gatedFor: string | undefined;
79
83
 
80
84
  /** Register (or replace, by id) a capability descriptor. Idempotent by id. */
81
85
  register(descriptor: CapabilityDescriptor): void {
@@ -116,9 +120,35 @@ export class CapabilityRegistry {
116
120
  return kind ? all.filter((s) => s.kind === kind) : all;
117
121
  }
118
122
 
123
+ /**
124
+ * Record a driver discovery SKIPPED because it does not serve the project's platform.
125
+ *
126
+ * Gating removes the driver's patterns from the registry, which is the point — but it also means
127
+ * a step belonging to that driver reaches SG-W001 ("sungen has no step form for it") instead of
128
+ * SG-W020 ("this step is mobile-only"). SG-W001's sentence is then false. This is the only fact
129
+ * available to correct it: patterns were never loaded, so what was skipped is knowable and which
130
+ * step it owned is not.
131
+ */
132
+ noteGatedDriver(pkg: string, serves: string, projectPlatform: string): void {
133
+ this.gated.set(pkg, serves);
134
+ this.gatedFor = projectPlatform;
135
+ }
136
+
137
+ /** Drivers skipped by the platform gate, as `[package, platform it serves]`. Empty when nothing was gated. */
138
+ gatedDrivers(): Array<[string, string]> {
139
+ return [...this.gated.entries()];
140
+ }
141
+
142
+ /** The project platform the gate applied, or undefined when nothing was gated. */
143
+ gatedForPlatform(): string | undefined {
144
+ return this.gatedFor;
145
+ }
146
+
119
147
  /** Test seam: drop all registrations. */
120
148
  _reset(): void {
121
149
  this.caps.clear();
150
+ this.gated.clear();
151
+ this.gatedFor = undefined;
122
152
  }
123
153
  }
124
154
 
@@ -92,6 +92,15 @@ function render(r: AuditReport): void {
92
92
  for (const c of r.duplicates.clusters.slice(0, 3)) {
93
93
  L(` ${c.sameDataLikely ? '✗ exact' : '○ EP/data family'} (${c.scenarios.length}): ${c.scenarios.slice(0, 3).join(' | ')}${c.scenarios.length > 3 ? ' …' : ''}`);
94
94
  }
95
+ // #694 — printed under the duplicate axis because that is where a reader looks for it, but it
96
+ // is a DIFFERENT signal: ⑤ clusters identical steps, this catches one id on distinct scenarios.
97
+ // Marked BLOCKING inline so a red build states its cause without scrolling to the findings.
98
+ if (r.reusedScenarioIds.length > 0) {
99
+ L(` ✗ BLOCKING — ${r.reusedScenarioIds.length} reused scenario id(s): a shared id ships as several deliverable rows under ONE testcase id`);
100
+ for (const d of r.reusedScenarioIds.slice(0, 3)) {
101
+ L(` ${d.id} ×${d.count}${d.file ? ` in ${d.file}` : ''}: ${d.titles.slice(0, 2).join(' | ')}${d.titles.length > 2 ? ' …' : ''}`);
102
+ }
103
+ }
95
104
  L('');
96
105
  L(` ⑥ Traceability — ${(r.trace.mappedRatio * 100).toFixed(0)}% scenarios linked to viewpoint-overview`);
97
106
  L(` ${r.trace.note}`);
@@ -98,7 +98,7 @@ export function registerCapabilityCommand(program: Command): void {
98
98
  // ── plan (Planner — recommend-only, no install) ──────────────────────────
99
99
  cap
100
100
  .command('plan')
101
- .description('Capability Planner: classify execution modes + @manual reasons (M1–M9) + recommend drivers (no install)')
101
+ .description('Capability Planner: classify execution modes + @manual reasons (M1–M11) + recommend drivers (no install)')
102
102
  .requiredOption('-s, --screen <name>', 'Screen or flow name')
103
103
  .option('--json', 'Output the raw plan JSON')
104
104
  .action((o: { screen: string; json?: boolean }) => {
@@ -39,6 +39,7 @@ import {
39
39
  hasReview,
40
40
  } from '../../exporters/matrix/export';
41
41
  import { MatrixFinding } from '../../exporters/matrix/types';
42
+ import { formatTestOutcome, resultTotals } from '../../exporters/matrix/result-totals';
42
43
 
43
44
  const COLOR = {
44
45
  reset: '\x1b[0m',
@@ -703,7 +704,7 @@ async function exportMatrixTarget(
703
704
  return null;
704
705
  }
705
706
 
706
- log(`${COLOR.bold}${paths.label}${COLOR.reset} — ${model.manifest.itemCount} delivery item(s), ${model.manifest.variantCount} coverage variant(s), state: ${model.manifest.approvalState}`);
707
+ log(`${COLOR.bold}${paths.label}${COLOR.reset} — ${model.manifest.itemCount} delivery item(s), ${model.manifest.variantCount} coverage variant(s), review: ${model.manifest.approvalState} (design), test outcome: ${formatTestOutcome(resultTotals(model.items))}`);
707
708
  {
708
709
  const mocked = model.items.flatMap((it) => it.variants.filter((v) => v.mocked));
709
710
  if (mocked.length > 0) {
@@ -238,8 +238,11 @@ export function registerGenerateCommand(program: Command): void {
238
238
  const advisorySensors = capabilityRegistry.sensors('advisory');
239
239
  const ddWarnings = scanDirs.flatMap((d) => advisorySensors.flatMap((s) => s.run({ dir: d, cwd })));
240
240
  if (ddWarnings.length) {
241
- console.log(`\n⚠️ Data-driven lint (@cases / @query) — review:`);
242
- for (const w of ddWarnings.slice(0, 20)) console.log(` ${w.scenario ? w.scenario + ': ' : ''}${w.message}`);
241
+ console.log(`\n⚠️ Data-driven lint (@cases / @query / dead test-data) — advisory, review:`);
242
+ const verbose = !!program.opts().verbose;
243
+ const shown = verbose ? ddWarnings : ddWarnings.slice(0, 20);
244
+ for (const w of shown) console.log(` ${w.scenario ? w.scenario + ': ' : ''}${w.message}`);
245
+ if (shown.length < ddWarnings.length) console.log(` … and ${ddWarnings.length - shown.length} more (run with -v to list all)`);
243
246
  }
244
247
 
245
248
  const nextStep = platform === 'mobile' ? 'npm run test:mobile' : 'npx playwright test --ui';
@@ -63,7 +63,7 @@ export function inspectProject(cwd: string): ProjectInspection {
63
63
  const perfPass = model.perf ? model.perf.pass : null;
64
64
 
65
65
  const reasons: string[] = [];
66
- if (!approved) reasons.push('delivery map not approved');
66
+ if (!approved) reasons.push('delivery map not approved (design review state — not a test outcome)');
67
67
  if (!frozen) reasons.push('sources drifted since approval (not frozen — Gate E)');
68
68
  if (failed.length) reasons.push(`${failed.length} golden variant(s) FAILED`);
69
69
  if (pending.length) reasons.push(`${pending.length} golden variant(s) have no run result`);
@@ -9,6 +9,8 @@ import * as fs from 'fs';
9
9
  import * as path from 'path';
10
10
  import { Command } from 'commander';
11
11
  import { mergeResultsReports, findGhostTitles } from '../../exporters/results-merge';
12
+ import { detectReportRoot, sanitizeReportPaths } from '../../exporters/report-path-sanitizer';
13
+ import { registerResultsSanitizeCommand } from './results-sanitize';
12
14
  import { resolveResultsPath } from '../../exporters/playwright-report-parser';
13
15
  import { parseSpecFile } from '../../exporters/spec-parser';
14
16
 
@@ -95,8 +97,12 @@ export function runResultsMerge(baseArg: string | undefined, newArg: string | un
95
97
  throw new Error('results merge: expected <base.json> <new.json>, or --screen <name> <new.json>.');
96
98
  }
97
99
 
98
- const base = readReport(baseFile, 'base');
99
- const fresh = readReport(newFile, 'new');
100
+ // Each report relativizes against ITS OWN root before the merge: `config` is copied from the base
101
+ // wholesale, so a base produced on another machine would otherwise carry that machine's paths
102
+ // into the merged file for good.
103
+ const sanitize = (doc: any): any => sanitizeReportPaths(doc, { root: detectReportRoot(doc) ?? cwd }).doc;
104
+ const base = sanitize(readReport(baseFile, 'base'));
105
+ const fresh = sanitize(readReport(newFile, 'new'));
100
106
  const { merged, replaced, added, kept } = mergeResultsReports(base, fresh);
101
107
 
102
108
  if (specTitles) {
@@ -136,6 +142,7 @@ export function registerResultsCommand(program: Command): void {
136
142
  const results = program
137
143
  .command('results')
138
144
  .description('Operate on per-target Playwright result files');
145
+ registerResultsSanitizeCommand(results);
139
146
 
140
147
  results
141
148
  .command('merge [base] [new]')
@@ -0,0 +1,98 @@
1
+ /**
2
+ * `sungen results sanitize [files…]` — rewrite the operator's machine paths out of result/report JSON.
3
+ *
4
+ * Playwright's JSON reporter and sungen's own reports record absolute paths, and teams commit those
5
+ * files next to the spec (delivery reads them). The reporter registered in `playwright.config.ts`
6
+ * sanitizes a fresh run's report on exit; this command is the safety net that reaches every file a
7
+ * project already has — and every project whose config predates the reporter. Idempotent: a clean
8
+ * file is left untouched (no rewrite, no timestamp churn).
9
+ *
10
+ * Each report relativizes against ITS OWN root (`dirname(config.configFile)` when it carries one), so
11
+ * a file produced on another machine comes out right too; a report that does not say falls back to
12
+ * the working directory.
13
+ */
14
+ import { Command } from 'commander';
15
+ import * as fs from 'fs';
16
+ import * as path from 'path';
17
+ import fg from 'fast-glob';
18
+ import { detectReportRoot, sanitizeReportPaths } from '../../exporters/report-path-sanitizer';
19
+
20
+ /** Where a project keeps the JSON files that carry paths. */
21
+ export const DEFAULT_REPORT_GLOBS = [
22
+ 'specs/generated/**/*-test-result*.json',
23
+ 'test-result.json',
24
+ '*-test-result*.json',
25
+ '.sungen/reports/*-script-check.json', // the one sungen report that records a path (`specPath`)
26
+ ];
27
+
28
+ export interface SanitizedFile {
29
+ file: string; // relative to cwd
30
+ rewritten: number; // string values changed (0 = already clean)
31
+ }
32
+
33
+ /** Sanitize the given files (or the project's default report locations). Returns one row per file. */
34
+ export function runResultsSanitize(files: string[] | undefined, cwd: string = process.cwd()): SanitizedFile[] {
35
+ const targets = files && files.length
36
+ ? files.map((f) => path.resolve(cwd, f))
37
+ : fg.sync(DEFAULT_REPORT_GLOBS, { cwd, absolute: true, onlyFiles: true, dot: true });
38
+ const out: SanitizedFile[] = [];
39
+ for (const file of targets.sort()) {
40
+ const raw = fs.readFileSync(file, 'utf-8');
41
+ let doc: unknown;
42
+ try {
43
+ doc = JSON.parse(raw);
44
+ } catch (err) {
45
+ throw new Error(`results sanitize: ${path.relative(cwd, file)} is not JSON (${err instanceof Error ? err.message : String(err)})`);
46
+ }
47
+ // A report that does not describe its root belongs to the project it sits in — the nearest
48
+ // ancestor holding a playwright.config.ts or .sungen/ — not to wherever the command was run from
49
+ // (a monorepo root would otherwise turn `specs/generated/x/x.spec.ts` into a bare basename).
50
+ const root = detectReportRoot(doc) ?? nearestProjectRoot(path.dirname(file)) ?? cwd;
51
+ const { doc: clean, rewritten } = sanitizeReportPaths(doc, { root });
52
+ if (rewritten > 0) {
53
+ // Atomic write, same as `results merge`: a crash mid-write must never leave a truncated report.
54
+ const tmp = `${file}.tmp-${process.pid}`;
55
+ try {
56
+ fs.writeFileSync(tmp, JSON.stringify(clean, null, 2) + (raw.endsWith('\n') ? '\n' : ''));
57
+ fs.renameSync(tmp, file);
58
+ } catch (err) {
59
+ try { fs.rmSync(tmp, { force: true }); } catch { /* best-effort cleanup */ }
60
+ throw err;
61
+ }
62
+ }
63
+ out.push({ file: path.relative(cwd, file), rewritten });
64
+ }
65
+ return out;
66
+ }
67
+
68
+ export function registerResultsSanitizeCommand(results: Command): void {
69
+ results
70
+ .command('sanitize [files...]')
71
+ .description('Rewrite absolute machine paths in result/report JSON to project-relative ones (default: every *-test-result*.json under specs/generated and .sungen/reports/*.json)')
72
+ .action((files: string[]) => {
73
+ try {
74
+ const rows = runResultsSanitize(files.length ? files : undefined);
75
+ if (rows.length === 0) {
76
+ console.log('results sanitize: no report files found.');
77
+ return;
78
+ }
79
+ const changed = rows.filter((r) => r.rewritten > 0);
80
+ for (const r of changed) console.log(`✓ ${r.file} — ${r.rewritten} path(s) made project-relative`);
81
+ console.log(`results sanitize: ${changed.length} of ${rows.length} file(s) rewritten${changed.length === 0 ? ' (all already clean)' : ''}.`);
82
+ } catch (err) {
83
+ console.error(err instanceof Error ? err.message : String(err));
84
+ process.exitCode = 1;
85
+ }
86
+ });
87
+ }
88
+
89
+ /** Nearest ancestor directory that looks like a sungen/Playwright project root. */
90
+ function nearestProjectRoot(from: string): string | undefined {
91
+ let dir = from;
92
+ for (;;) {
93
+ if (fs.existsSync(path.join(dir, 'playwright.config.ts')) || fs.existsSync(path.join(dir, '.sungen'))) return dir;
94
+ const parent = path.dirname(dir);
95
+ if (parent === dir) return undefined;
96
+ dir = parent;
97
+ }
98
+ }
@@ -3,6 +3,7 @@ import * as path from 'path';
3
3
  import * as fs from 'fs';
4
4
  import { runScriptCheck } from '../../harness/script-check';
5
5
  import { reportSlug } from '../../harness/unit-paths';
6
+ import { sanitizeReportPaths } from '../../exporters/report-path-sanitizer';
6
7
 
7
8
  export function registerScriptCheckCommand(program: Command): void {
8
9
  program
@@ -23,7 +24,8 @@ export function registerScriptCheckCommand(program: Command): void {
23
24
  const dir = kind === 'screen' ? screen : kind === 'flow' ? flow : kind === 'api' ? api : null;
24
25
  if (!dir || !kind) throw new Error(`Not found: qa/screens|flows|api/${name}`);
25
26
 
26
- const r = await runScriptCheck(dir, name, kind);
27
+ // The report is committed next to the spec — keep the operator's machine paths out of it.
28
+ const r = sanitizeReportPaths(await runScriptCheck(dir, name, kind), { root: process.cwd() }).doc;
27
29
 
28
30
  const outDir = path.join(process.cwd(), '.sungen', 'reports');
29
31
  fs.mkdirSync(outDir, { recursive: true });
@@ -100,6 +100,9 @@ export function registerUpdateCommand(program: Command): void {
100
100
  const { AIRulesUpdater } = require('../../orchestrator/ai-rules-updater');
101
101
  const updater = new AIRulesUpdater(process.cwd());
102
102
  await updater.update(options.dryRun ?? false, { agents: resolveAssistants(options.assistant), force: options.force ?? false });
103
+ // playwright.config.ts is written once at init and never re-synced — patch the reporter in.
104
+ const { installReportSanitizeReporter } = require('../../orchestrator/report-sanitize-reporter-install');
105
+ installReportSanitizeReporter(process.cwd(), options.dryRun ?? false);
103
106
  } catch (error) {
104
107
  console.error('❌ Update failed:', error);
105
108
  process.exit(1);
@@ -116,7 +116,7 @@ use chrome, FireFox or Internet Explorer 11`)}var a=e(`safe-buffer`),o=e(`random
116
116
  `)):s=e.stylize(`[Circular]`,`special`)),v(o)){if(a&&i.match(/^\d+$/))return s;(o=JSON.stringify(``+i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,`name`)):(o=o.replace(/'/g,`\\'`).replace(/\\"/g,`"`).replace(/(^"|"$)/g,`'`),o=e.stylize(o,`string`))}return o+`: `+s}function p(e){return Array.isArray(e)}function m(e){return typeof e==`boolean`}function h(e){return e===null}function g(e){return typeof e==`number`}function _(e){return typeof e==`string`}function v(e){return e===void 0}function y(e){return b(e)&&w(e)===`[object RegExp]`}function b(e){return typeof e==`object`&&!!e}function x(e){return b(e)&&w(e)===`[object Date]`}function S(e){return b(e)&&(w(e)===`[object Error]`||e instanceof Error)}function C(e){return typeof e==`function`}function w(e){return Object.prototype.toString.call(e)}function T(e){return e<10?`0`+e.toString(10):e.toString(10)}n.debuglog=function(e){if(v(a)&&(a=t.env.NODE_DEBUG||``),e=e.toUpperCase(),!o[e])if(RegExp(`\\b`+e+`\\b`,`i`).test(a)){var r=t.pid;o[e]=function(){var t=n.format.apply(n,arguments);console.error(`%s %d: %s`,e,r,t)}}else o[e]=function(){};return o[e]},n.inspect=s,s.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},s.styles={special:`cyan`,number:`yellow`,boolean:`yellow`,undefined:`grey`,null:`bold`,string:`green`,date:`magenta`,regexp:`red`},n.isArray=p,n.isBoolean=m,n.isNull=h,n.isNullOrUndefined=function(e){return e==null},n.isNumber=g,n.isString=_,n.isSymbol=function(e){return typeof e==`symbol`},n.isUndefined=v,n.isRegExp=y,n.isObject=b,n.isDate=x,n.isError=S,n.isFunction=C,n.isPrimitive=function(e){return e===null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`||typeof e==`symbol`||e===void 0},n.isBuffer=e(`./support/isBuffer`);var E=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];function D(){var e=new Date,t=[T(e.getHours()),T(e.getMinutes()),T(e.getSeconds())].join(`:`);return[e.getDate(),E[e.getMonth()],t].join(` `)}function O(e,t){return Object.prototype.hasOwnProperty.call(e,t)}n.log=function(){console.log(`%s - %s`,D(),n.format.apply(n,arguments))},n.inherits=e(`inherits`),n._extend=function(e,t){if(!t||!b(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e}}).call(this)}).call(this,e(`_process`),typeof global<`u`?global:typeof self<`u`?self:typeof window<`u`?window:{})},{"./support/isBuffer":526,_process:467,inherits:525}],528:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),Object.defineProperty(n,"v1",{enumerable:!0,get:function(){return r.default}}),Object.defineProperty(n,"v3",{enumerable:!0,get:function(){return i.default}}),Object.defineProperty(n,"v4",{enumerable:!0,get:function(){return a.default}}),Object.defineProperty(n,"v5",{enumerable:!0,get:function(){return o.default}}),Object.defineProperty(n,"NIL",{enumerable:!0,get:function(){return s.default}}),Object.defineProperty(n,"version",{enumerable:!0,get:function(){return c.default}}),Object.defineProperty(n,"validate",{enumerable:!0,get:function(){return l.default}}),Object.defineProperty(n,"stringify",{enumerable:!0,get:function(){return u.default}}),Object.defineProperty(n,"parse",{enumerable:!0,get:function(){return d.default}});var r=f(e(`./v1.js`)),i=f(e(`./v3.js`)),a=f(e(`./v4.js`)),o=f(e(`./v5.js`)),s=f(e(`./nil.js`)),c=f(e(`./version.js`)),l=f(e(`./validate.js`)),u=f(e(`./stringify.js`)),d=f(e(`./parse.js`));function f(e){return e&&e.__esModule?e:{default:e}}},{"./nil.js":530,"./parse.js":531,"./stringify.js":535,"./v1.js":536,"./v3.js":537,"./v4.js":539,"./v5.js":540,"./validate.js":541,"./version.js":542}],529:[function(e,t,n){function r(e){return 14+(e+64>>>9<<4)+1}function i(e,t){let n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function a(e,t,n,r,a,o){return i((s=i(i(t,e),i(r,o)))<<(c=a)|s>>>32-c,n);var s,c}function o(e,t,n,r,i,o,s){return a(t&n|~t&r,e,t,i,o,s)}function s(e,t,n,r,i,o,s){return a(t&r|n&~r,e,t,i,o,s)}function c(e,t,n,r,i,o,s){return a(t^n^r,e,t,i,o,s)}function l(e,t,n,r,i,o,s){return a(n^(t|~r),e,t,i,o,s)}Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0,n.default=function(e){if(typeof e==`string`){let t=unescape(encodeURIComponent(e));e=new Uint8Array(t.length);for(let n=0;n<t.length;++n)e[n]=t.charCodeAt(n)}return function(e){let t=[],n=32*e.length;for(let r=0;r<n;r+=8){let n=e[r>>5]>>>r%32&255,i=parseInt(`0123456789abcdef`.charAt(n>>>4&15)+`0123456789abcdef`.charAt(15&n),16);t.push(i)}return t}(function(e,t){e[t>>5]|=128<<t%32,e[r(t)-1]=t;let n=1732584193,a=-271733879,u=-1732584194,d=271733878;for(let t=0;t<e.length;t+=16){let r=n,f=a,p=u,m=d;n=o(n,a,u,d,e[t],7,-680876936),d=o(d,n,a,u,e[t+1],12,-389564586),u=o(u,d,n,a,e[t+2],17,606105819),a=o(a,u,d,n,e[t+3],22,-1044525330),n=o(n,a,u,d,e[t+4],7,-176418897),d=o(d,n,a,u,e[t+5],12,1200080426),u=o(u,d,n,a,e[t+6],17,-1473231341),a=o(a,u,d,n,e[t+7],22,-45705983),n=o(n,a,u,d,e[t+8],7,1770035416),d=o(d,n,a,u,e[t+9],12,-1958414417),u=o(u,d,n,a,e[t+10],17,-42063),a=o(a,u,d,n,e[t+11],22,-1990404162),n=o(n,a,u,d,e[t+12],7,1804603682),d=o(d,n,a,u,e[t+13],12,-40341101),u=o(u,d,n,a,e[t+14],17,-1502002290),a=o(a,u,d,n,e[t+15],22,1236535329),n=s(n,a,u,d,e[t+1],5,-165796510),d=s(d,n,a,u,e[t+6],9,-1069501632),u=s(u,d,n,a,e[t+11],14,643717713),a=s(a,u,d,n,e[t],20,-373897302),n=s(n,a,u,d,e[t+5],5,-701558691),d=s(d,n,a,u,e[t+10],9,38016083),u=s(u,d,n,a,e[t+15],14,-660478335),a=s(a,u,d,n,e[t+4],20,-405537848),n=s(n,a,u,d,e[t+9],5,568446438),d=s(d,n,a,u,e[t+14],9,-1019803690),u=s(u,d,n,a,e[t+3],14,-187363961),a=s(a,u,d,n,e[t+8],20,1163531501),n=s(n,a,u,d,e[t+13],5,-1444681467),d=s(d,n,a,u,e[t+2],9,-51403784),u=s(u,d,n,a,e[t+7],14,1735328473),a=s(a,u,d,n,e[t+12],20,-1926607734),n=c(n,a,u,d,e[t+5],4,-378558),d=c(d,n,a,u,e[t+8],11,-2022574463),u=c(u,d,n,a,e[t+11],16,1839030562),a=c(a,u,d,n,e[t+14],23,-35309556),n=c(n,a,u,d,e[t+1],4,-1530992060),d=c(d,n,a,u,e[t+4],11,1272893353),u=c(u,d,n,a,e[t+7],16,-155497632),a=c(a,u,d,n,e[t+10],23,-1094730640),n=c(n,a,u,d,e[t+13],4,681279174),d=c(d,n,a,u,e[t],11,-358537222),u=c(u,d,n,a,e[t+3],16,-722521979),a=c(a,u,d,n,e[t+6],23,76029189),n=c(n,a,u,d,e[t+9],4,-640364487),d=c(d,n,a,u,e[t+12],11,-421815835),u=c(u,d,n,a,e[t+15],16,530742520),a=c(a,u,d,n,e[t+2],23,-995338651),n=l(n,a,u,d,e[t],6,-198630844),d=l(d,n,a,u,e[t+7],10,1126891415),u=l(u,d,n,a,e[t+14],15,-1416354905),a=l(a,u,d,n,e[t+5],21,-57434055),n=l(n,a,u,d,e[t+12],6,1700485571),d=l(d,n,a,u,e[t+3],10,-1894986606),u=l(u,d,n,a,e[t+10],15,-1051523),a=l(a,u,d,n,e[t+1],21,-2054922799),n=l(n,a,u,d,e[t+8],6,1873313359),d=l(d,n,a,u,e[t+15],10,-30611744),u=l(u,d,n,a,e[t+6],15,-1560198380),a=l(a,u,d,n,e[t+13],21,1309151649),n=l(n,a,u,d,e[t+4],6,-145523070),d=l(d,n,a,u,e[t+11],10,-1120210379),u=l(u,d,n,a,e[t+2],15,718787259),a=l(a,u,d,n,e[t+9],21,-343485551),n=i(n,r),a=i(a,f),u=i(u,p),d=i(d,m)}return[n,a,u,d]}(function(e){if(e.length===0)return[];let t=8*e.length,n=new Uint32Array(r(t));for(let r=0;r<t;r+=8)n[r>>5]|=(255&e[r/8])<<r%32;return n}(e),8*e.length))}},{}],530:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0,n.default=`00000000-0000-0000-0000-000000000000`},{}],531:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r,i=(r=e(`./validate.js`))&&r.__esModule?r:{default:r};n.default=function(e){if(!(0,i.default)(e))throw TypeError(`Invalid UUID`);let t,n=new Uint8Array(16);return n[0]=(t=parseInt(e.slice(0,8),16))>>>24,n[1]=t>>>16&255,n[2]=t>>>8&255,n[3]=255&t,n[4]=(t=parseInt(e.slice(9,13),16))>>>8,n[5]=255&t,n[6]=(t=parseInt(e.slice(14,18),16))>>>8,n[7]=255&t,n[8]=(t=parseInt(e.slice(19,23),16))>>>8,n[9]=255&t,n[10]=(t=parseInt(e.slice(24,36),16))/1099511627776&255,n[11]=t/4294967296&255,n[12]=t>>>24&255,n[13]=t>>>16&255,n[14]=t>>>8&255,n[15]=255&t,n}},{"./validate.js":541}],532:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0,n.default=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i},{}],533:[function(e,t,n){let r;Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(){if(!r&&(r=typeof crypto<`u`&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||typeof msCrypto<`u`&&typeof msCrypto.getRandomValues==`function`&&msCrypto.getRandomValues.bind(msCrypto),!r))throw Error(`crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported`);return r(i)};let i=new Uint8Array(16)},{}],534:[function(e,t,n){function r(e,t,n,r){switch(e){case 0:return t&n^~t&r;case 1:return t^n^r;case 2:return t&n^t&r^n&r;case 3:return t^n^r}}function i(e,t){return e<<t|e>>>32-t}Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0,n.default=function(e){let t=[1518500249,1859775393,2400959708,3395469782],n=[1732584193,4023233417,2562383102,271733878,3285377520];if(typeof e==`string`){let t=unescape(encodeURIComponent(e));e=[];for(let n=0;n<t.length;++n)e.push(t.charCodeAt(n))}else Array.isArray(e)||(e=Array.prototype.slice.call(e));e.push(128);let a=e.length/4+2,o=Math.ceil(a/16),s=Array(o);for(let t=0;t<o;++t){let n=new Uint32Array(16);for(let r=0;r<16;++r)n[r]=e[64*t+4*r]<<24|e[64*t+4*r+1]<<16|e[64*t+4*r+2]<<8|e[64*t+4*r+3];s[t]=n}s[o-1][14]=8*(e.length-1)/2**32,s[o-1][14]=Math.floor(s[o-1][14]),s[o-1][15]=8*(e.length-1)&4294967295;for(let e=0;e<o;++e){let a=new Uint32Array(80);for(let t=0;t<16;++t)a[t]=s[e][t];for(let e=16;e<80;++e)a[e]=i(a[e-3]^a[e-8]^a[e-14]^a[e-16],1);let o=n[0],c=n[1],l=n[2],u=n[3],d=n[4];for(let e=0;e<80;++e){let n=Math.floor(e/20),s=i(o,5)+r(n,c,l,u)+d+t[n]+a[e]>>>0;d=u,u=l,l=i(c,30)>>>0,c=o,o=s}n[0]=n[0]+o>>>0,n[1]=n[1]+c>>>0,n[2]=n[2]+l>>>0,n[3]=n[3]+u>>>0,n[4]=n[4]+d>>>0}return[n[0]>>24&255,n[0]>>16&255,n[0]>>8&255,255&n[0],n[1]>>24&255,n[1]>>16&255,n[1]>>8&255,255&n[1],n[2]>>24&255,n[2]>>16&255,n[2]>>8&255,255&n[2],n[3]>>24&255,n[3]>>16&255,n[3]>>8&255,255&n[3],n[4]>>24&255,n[4]>>16&255,n[4]>>8&255,255&n[4]]}},{}],535:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r,i=(r=e(`./validate.js`))&&r.__esModule?r:{default:r};let a=[];for(let e=0;e<256;++e)a.push((e+256).toString(16).substr(1));n.default=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0,n=(a[e[t+0]]+a[e[t+1]]+a[e[t+2]]+a[e[t+3]]+`-`+a[e[t+4]]+a[e[t+5]]+`-`+a[e[t+6]]+a[e[t+7]]+`-`+a[e[t+8]]+a[e[t+9]]+`-`+a[e[t+10]]+a[e[t+11]]+a[e[t+12]]+a[e[t+13]]+a[e[t+14]]+a[e[t+15]]).toLowerCase();if(!(0,i.default)(n))throw TypeError(`Stringified UUID is invalid`);return n}},{"./validate.js":541}],536:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r=a(e(`./rng.js`)),i=a(e(`./stringify.js`));function a(e){return e&&e.__esModule?e:{default:e}}let o,s,c=0,l=0;n.default=function(e,t,n){let a=t&&n||0,u=t||Array(16),d=(e=e||{}).node||o,f=e.clockseq===void 0?s:e.clockseq;if(d==null||f==null){let t=e.random||(e.rng||r.default)();d??(d=o=[1|t[0],t[1],t[2],t[3],t[4],t[5]]),f??(f=s=16383&(t[6]<<8|t[7]))}let p=e.msecs===void 0?Date.now():e.msecs,m=e.nsecs===void 0?l+1:e.nsecs,h=p-c+(m-l)/1e4;if(h<0&&e.clockseq===void 0&&(f=f+1&16383),(h<0||p>c)&&e.nsecs===void 0&&(m=0),m>=1e4)throw Error(`uuid.v1(): Can't create more than 10M uuids/sec`);c=p,l=m,s=f,p+=0xb1d069b5400;let g=(1e4*(268435455&p)+m)%4294967296;u[a++]=g>>>24&255,u[a++]=g>>>16&255,u[a++]=g>>>8&255,u[a++]=255&g;let _=p/4294967296*1e4&268435455;u[a++]=_>>>8&255,u[a++]=255&_,u[a++]=_>>>24&15|16,u[a++]=_>>>16&255,u[a++]=f>>>8|128,u[a++]=255&f;for(let e=0;e<6;++e)u[a+e]=d[e];return t||(0,i.default)(u)}},{"./rng.js":533,"./stringify.js":535}],537:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r=a(e(`./v35.js`)),i=a(e(`./md5.js`));function a(e){return e&&e.__esModule?e:{default:e}}n.default=(0,r.default)(`v3`,48,i.default)},{"./md5.js":529,"./v35.js":538}],538:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(e,t,n){function a(e,a,o,s){if(typeof e==`string`&&(e=function(e){e=unescape(encodeURIComponent(e));let t=[];for(let n=0;n<e.length;++n)t.push(e.charCodeAt(n));return t}(e)),typeof a==`string`&&(a=(0,i.default)(a)),a.length!==16)throw TypeError(`Namespace must be array-like (16 iterable integer values, 0-255)`);let c=new Uint8Array(16+e.length);if(c.set(a),c.set(e,a.length),c=n(c),c[6]=15&c[6]|t,c[8]=63&c[8]|128,o){s=s||0;for(let e=0;e<16;++e)o[s+e]=c[e];return o}return(0,r.default)(c)}try{a.name=e}catch{}return a.DNS=o,a.URL=s,a},n.URL=n.DNS=void 0;var r=a(e(`./stringify.js`)),i=a(e(`./parse.js`));function a(e){return e&&e.__esModule?e:{default:e}}let o=`6ba7b810-9dad-11d1-80b4-00c04fd430c8`;n.DNS=o;let s=`6ba7b811-9dad-11d1-80b4-00c04fd430c8`;n.URL=s},{"./parse.js":531,"./stringify.js":535}],539:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r=a(e(`./rng.js`)),i=a(e(`./stringify.js`));function a(e){return e&&e.__esModule?e:{default:e}}n.default=function(e,t,n){let a=(e=e||{}).random||(e.rng||r.default)();if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,t){n=n||0;for(let e=0;e<16;++e)t[n+e]=a[e];return t}return(0,i.default)(a)}},{"./rng.js":533,"./stringify.js":535}],540:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r=a(e(`./v35.js`)),i=a(e(`./sha1.js`));function a(e){return e&&e.__esModule?e:{default:e}}n.default=(0,r.default)(`v5`,80,i.default)},{"./sha1.js":534,"./v35.js":538}],541:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r,i=(r=e(`./regex.js`))&&r.__esModule?r:{default:r};n.default=function(e){return typeof e==`string`&&i.default.test(e)}},{"./regex.js":532}],542:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.default=void 0;var r,i=(r=e(`./validate.js`))&&r.__esModule?r:{default:r};n.default=function(e){if(!(0,i.default)(e))throw TypeError(`Invalid UUID`);return parseInt(e.substr(14,1),16)}},{"./validate.js":541}],543:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.CHAR=`
117
117
  \r -퟿-�𐀀-􏿿`,n.S=` \r
118
118
  `,n.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿`,n.NAME_CHAR=`-`+n.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.CHAR_RE=RegExp(`^[`+n.CHAR+`]$`,`u`),n.S_RE=RegExp(`^[`+n.S+`]+$`,`u`),n.NAME_START_CHAR_RE=RegExp(`^[`+n.NAME_START_CHAR+`]$`,`u`),n.NAME_CHAR_RE=RegExp(`^[`+n.NAME_CHAR+`]$`,`u`),n.NAME_RE=RegExp(`^[`+n.NAME_START_CHAR+`][`+n.NAME_CHAR+`]*$`,`u`),n.NMTOKEN_RE=RegExp(`^[`+n.NAME_CHAR+`]+$`,`u`);function r(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}n.S_LIST=[32,10,13,9],n.isChar=function(e){return e>=32&&e<=55295||e===10||e===13||e===9||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isS=function(e){return e===32||e===10||e===13||e===9},n.isNameStartChar=r,n.isNameChar=function(e){return r(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}],544:[function(e,t,n){Object.defineProperty(n,"__esModule",{value:!0}),n.CHAR=`-퟿-�𐀀-􏿿`,n.RESTRICTED_CHAR=`-\b\v\f--„†-Ÿ`,n.S=` \r
119
- `,n.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿`,n.NAME_CHAR=`-`+n.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.CHAR_RE=RegExp(`^[`+n.CHAR+`]$`,`u`),n.RESTRICTED_CHAR_RE=RegExp(`^[`+n.RESTRICTED_CHAR+`]$`,`u`),n.S_RE=RegExp(`^[`+n.S+`]+$`,`u`),n.NAME_START_CHAR_RE=RegExp(`^[`+n.NAME_START_CHAR+`]$`,`u`),n.NAME_CHAR_RE=RegExp(`^[`+n.NAME_CHAR+`]$`,`u`),n.NAME_RE=RegExp(`^[`+n.NAME_START_CHAR+`][`+n.NAME_CHAR+`]*$`,`u`),n.NMTOKEN_RE=RegExp(`^[`+n.NAME_CHAR+`]+$`,`u`);function r(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}n.S_LIST=[32,10,13,9],n.isChar=function(e){return e>=1&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isRestrictedChar=function(e){return e>=1&&e<=8||e===11||e===12||e>=14&&e<=31||e>=127&&e<=132||e>=134&&e<=159},n.isCharAndNotRestricted=function(e){return e===9||e===10||e===13||e>31&&e<127||e===133||e>159&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isS=function(e){return e===32||e===10||e===13||e===9},n.isNameStartChar=r,n.isNameChar=function(e){return r(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}],545:[function(e,t,n){function r(e){return e>=65&&e<=90||e===95||e>=97&&e<=122||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8204&&e<=8205||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}Object.defineProperty(n,"__esModule",{value:!0}),n.NC_NAME_START_CHAR=`A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿`,n.NC_NAME_CHAR=`-`+n.NC_NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.NC_NAME_START_CHAR_RE=RegExp(`^[`+n.NC_NAME_START_CHAR+`]$`,`u`),n.NC_NAME_CHAR_RE=RegExp(`^[`+n.NC_NAME_CHAR+`]$`,`u`),n.NC_NAME_RE=RegExp(`^[`+n.NC_NAME_START_CHAR+`][`+n.NC_NAME_CHAR+`]*$`,`u`),n.isNCNameStartChar=r,n.isNCNameChar=function(e){return r(e)||e===45||e===46||e>=48&&e<=57||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}]},{},[15])(15)}))})),aN=l(rN(),1),oN=l(iN()),sN=`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`,cN=`FFD9D2E9`,lN=`FF000000`,uN=`FFD9D2E9`,dN=`FFBFBFBF`,fN=`Times New Roman`,pN=`Arial`,mN={argb:`FF000000`},hN={argb:`FFFFFFFF`},gN={argb:`FFD9D2E9`},_N={style:`thin`,color:mN},vN={top:_N,left:_N,bottom:_N,right:_N};function yN(e){e.border={top:{style:`thin`,color:{argb:dN}},left:{style:`thin`,color:{argb:dN}},bottom:{style:`thin`,color:{argb:dN}},right:{style:`thin`,color:{argb:dN}}}}function bN(e,t,n,r,i=`BM-2-901-13`){let a=(()=>{let e=new Date;return`${String(e.getDate()).padStart(2,`0`)}/${String(e.getMonth()+1).padStart(2,`0`)}/${e.getFullYear()}`})();for(let e=1;e<=4;e++)t.getRow(e);t.mergeCells(`A1:C3`),t.mergeCells(`D1:F3`),t.mergeCells(`G1:H1`),t.mergeCells(`G2:H2`),t.mergeCells(`G3:H3`),t.mergeCells(`A4:F4`),t.mergeCells(`G4:H4`);let o=t.getCell(`A1`);o.alignment={horizontal:`center`,vertical:`middle`},o.border=vN;try{let n=e.addImage({base64:sN,extension:`png`});t.addImage(n,{tl:{nativeCol:0,nativeColOff:1237500,nativeRow:0,nativeRowOff:42862},ext:{width:90,height:51},editAs:`oneCell`})}catch{}let s=t.getCell(`D1`);s.value=n,s.font={bold:!0,size:18,name:fN},s.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},s.border=vN;let c=t.getCell(`G1`);c.value=`No: ${i}`,c.font={size:12,name:fN},c.alignment={vertical:`middle`},c.border={top:_N,left:_N,right:_N};let l=t.getCell(`G2`);l.value=`Version: ${r??`unknown`}`,l.font={size:12,name:fN},l.alignment={vertical:`middle`},l.border={left:_N,right:_N};let u=t.getCell(`G3`);u.value=`Issue Date: ${a}`,u.font={size:12,name:fN},u.alignment={vertical:`middle`},u.border={left:_N,right:_N,bottom:_N};let d=t.getCell(`A4`);d.value=`SUN ASTERISK VIETNAM CO., LTD`,d.font={bold:!0,size:10,name:fN},d.alignment={vertical:`middle`},d.border=vN;let f=t.getCell(`G4`);f.value=`ISO/IEC 27001:2022 & ISO 9001:2015`,f.font={bold:!0,size:10,name:fN},f.alignment={horizontal:`right`,vertical:`middle`,wrapText:!0},f.border=vN}var xN=[`#`,`Sheet name`,`Passed`,`Failed`,`Pending`,`N/A`,`Remain`,`Total`];function SN(e,t,n){let r=e.addWorksheet(`Overview`);r.columns=[{width:4},{width:6},{width:26},{width:13},{width:13},{width:13},{width:13},{width:13},{width:13}],bN(e,r,`${(t[0]?.summary.screen??``).toUpperCase()} TESTCASE`,n);let i=r.getRow(7);i.height=20,xN.forEach((e,t)=>{let n=i.getCell(2+t);n.value=e,n.font={bold:!0,size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:gN},n.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},n.border=vN});let a={passed:0,failed:0,pending:0,na:0,remain:0,total:0},o=(e,t,n)=>{let i=r.getRow(e);t.forEach((e,t)=>{let r=i.getCell(2+t);r.value=e,r.font={bold:n,size:10,color:mN,name:pN},r.alignment={horizontal:t<=1?`left`:`center`,vertical:`middle`},r.border=vN,n&&(r.fill={type:`pattern`,pattern:`solid`,fgColor:gN})})},s=e=>e.replace(/'/g,`''`),c=(e,t,n)=>({formula:`'${s(e)}'!${t}`,result:n}),l=8,u=l;t.forEach((e,t)=>{let n=e.summary,r=Math.max(0,n.total-n.passed-n.na);o(l,[t+1,e.sheetName,c(e.sheetName,`D7`,n.passed),c(e.sheetName,`E7`,n.failed),c(e.sheetName,`F7`,n.pending),c(e.sheetName,`G7`,n.na),c(e.sheetName,`H7`,r),c(e.sheetName,`C7`,n.total)],!1),a.passed+=n.passed,a.failed+=n.failed,a.pending+=n.pending,a.na+=n.na,a.remain+=r,a.total+=n.total,l+=1});let d=l-1,f=(e,t)=>({formula:`SUM(${e}${u}:${e}${d})`,result:t});o(l,[``,`Total`,f(`D`,a.passed),f(`E`,a.failed),f(`F`,a.pending),f(`G`,a.na),f(`H`,a.remain),f(`I`,a.total)],!0)}function CN(e,t,n,r,i,a){let o=e.addWorksheet(t,{views:[{state:`frozen`,ySplit:0,xSplit:0}]});o.columns=[{width:20},{width:12.5},{width:15.38},{width:16.25},{width:17},{width:25.5},{width:24.88},{width:50},{width:41},{width:12},{width:13.5},{width:15.88},{width:13.5},{width:16.5},{width:23},{width:29}],bN(e,o,`${n.screen.toUpperCase()} TESTCASE`,a);for(let e=5;e<=8;e++)o.getRow(e);for(let[e,t]of Object.entries({C:`Total TCs`,D:`Passed`,E:`Failed`,F:`Pending`,G:`N/A`,H:`Remaining`})){let n=o.getCell(`${e}6`);n.value=t,n.font={bold:!0,size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:gN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN}let s=1e4,c={C:{formula:`COUNTA(A14:A${s})`,result:n.total},D:{formula:`COUNTIF(L14:L${s},"Passed")`,result:n.passed},E:{formula:`COUNTIF(L14:L${s},"Failed")`,result:n.failed},F:{formula:`COUNTIF(L14:L${s},"Pending")`,result:n.pending},G:{formula:`COUNTIF(L14:L${s},"N/A")`,result:n.na},H:{formula:`C7-D7-G7`,result:n.failed+n.pending}};for(let[e,t]of Object.entries(c)){let n=o.getCell(`${e}7`);n.value=t,n.font={size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:hN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN,e===`H`&&(n.numFmt=`#,##0`)}let l=o.getCell(`C8`);l.font={size:10,color:mN,name:pN},l.fill={type:`pattern`,pattern:`solid`,fgColor:hN},l.alignment={horizontal:`center`,vertical:`top`},l.border=vN;let u={D:{formula:`IFERROR(D7/(C7-G7),0)`,result:n.passed/Math.max(1,n.total-n.na)},E:{formula:`IFERROR(E7/(C7-G7),0)`,result:n.failed/Math.max(1,n.total-n.na)},F:{formula:`IFERROR(F7/(C7-G7),0)`,result:n.pending/Math.max(1,n.total-n.na)},G:{formula:`IFERROR(G7/(C7-G7),0)`,result:n.na/Math.max(1,n.total-n.na)},H:{formula:`IFERROR(H7/(C7-G7),0)`,result:(n.failed+n.pending)/Math.max(1,n.total-n.na)}};for(let[e,t]of Object.entries(u)){let n=o.getCell(`${e}8`);n.value=t,n.font={size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:hN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN,n.numFmt=`0%`}for(;o.rowCount<9;)o.addRow([]);let d=o.addRow([`Spec/Design link:`,i]);d.getCell(1).font={bold:!0},d.getCell(2).font={color:{argb:`FF1F4E78`},underline:!0},o.addRow([]);let f=o.addRow([`*: Mandatory`]);f.getCell(1).font={italic:!0,color:{argb:`FF808080`}};let p=o.addRow([`TC ID*`,`Screen/Function`,`Big item`,`Medium item`,`Test Object`,`Pre-condition`,`Test Data`,`Steps*`,`Expected results*`,`Priority`,`Testcase type`,`Test Result*`,`Executed Date*`,`Test Executor*`,`Test Environment`,`Note
119
+ `,n.NAME_START_CHAR=`:A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿`,n.NAME_CHAR=`-`+n.NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.CHAR_RE=RegExp(`^[`+n.CHAR+`]$`,`u`),n.RESTRICTED_CHAR_RE=RegExp(`^[`+n.RESTRICTED_CHAR+`]$`,`u`),n.S_RE=RegExp(`^[`+n.S+`]+$`,`u`),n.NAME_START_CHAR_RE=RegExp(`^[`+n.NAME_START_CHAR+`]$`,`u`),n.NAME_CHAR_RE=RegExp(`^[`+n.NAME_CHAR+`]$`,`u`),n.NAME_RE=RegExp(`^[`+n.NAME_START_CHAR+`][`+n.NAME_CHAR+`]*$`,`u`),n.NMTOKEN_RE=RegExp(`^[`+n.NAME_CHAR+`]+$`,`u`);function r(e){return e>=65&&e<=90||e>=97&&e<=122||e===58||e===95||e===8204||e===8205||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}n.S_LIST=[32,10,13,9],n.isChar=function(e){return e>=1&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isRestrictedChar=function(e){return e>=1&&e<=8||e===11||e===12||e>=14&&e<=31||e>=127&&e<=132||e>=134&&e<=159},n.isCharAndNotRestricted=function(e){return e===9||e===10||e===13||e>31&&e<127||e===133||e>159&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111},n.isS=function(e){return e===32||e===10||e===13||e===9},n.isNameStartChar=r,n.isNameChar=function(e){return r(e)||e>=48&&e<=57||e===45||e===46||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}],545:[function(e,t,n){function r(e){return e>=65&&e<=90||e===95||e>=97&&e<=122||e>=192&&e<=214||e>=216&&e<=246||e>=248&&e<=767||e>=880&&e<=893||e>=895&&e<=8191||e>=8204&&e<=8205||e>=8304&&e<=8591||e>=11264&&e<=12271||e>=12289&&e<=55295||e>=63744&&e<=64975||e>=65008&&e<=65533||e>=65536&&e<=983039}Object.defineProperty(n,"__esModule",{value:!0}),n.NC_NAME_START_CHAR=`A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿`,n.NC_NAME_CHAR=`-`+n.NC_NAME_START_CHAR+`.0-9·̀-ͯ‿-⁀`,n.NC_NAME_START_CHAR_RE=RegExp(`^[`+n.NC_NAME_START_CHAR+`]$`,`u`),n.NC_NAME_CHAR_RE=RegExp(`^[`+n.NC_NAME_CHAR+`]$`,`u`),n.NC_NAME_RE=RegExp(`^[`+n.NC_NAME_START_CHAR+`][`+n.NC_NAME_CHAR+`]*$`,`u`),n.isNCNameStartChar=r,n.isNCNameChar=function(e){return r(e)||e===45||e===46||e>=48&&e<=57||e===183||e>=768&&e<=879||e>=8255&&e<=8256}},{}]},{},[15])(15)}))})),aN=l(rN(),1),oN=l(iN()),sN=`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`,cN=`FFD9D2E9`,lN=`FF000000`,uN=`FFD9D2E9`,dN=`FFBFBFBF`,fN=`Times New Roman`,pN=`Arial`,mN={argb:`FF000000`},hN={argb:`FFFFFFFF`},gN={argb:`FFD9D2E9`},_N={style:`thin`,color:mN},vN={top:_N,left:_N,bottom:_N,right:_N};function yN(e){e.border={top:{style:`thin`,color:{argb:dN}},left:{style:`thin`,color:{argb:dN}},bottom:{style:`thin`,color:{argb:dN}},right:{style:`thin`,color:{argb:dN}}}}function bN(e,t,n,r,i=`BM-2-901-13`){let a=(()=>{let e=new Date;return`${String(e.getDate()).padStart(2,`0`)}/${String(e.getMonth()+1).padStart(2,`0`)}/${e.getFullYear()}`})();for(let e=1;e<=4;e++)t.getRow(e);t.mergeCells(`A1:C3`),t.mergeCells(`D1:F3`),t.mergeCells(`G1:H1`),t.mergeCells(`G2:H2`),t.mergeCells(`G3:H3`),t.mergeCells(`A4:F4`),t.mergeCells(`G4:H4`);let o=t.getCell(`A1`);o.alignment={horizontal:`center`,vertical:`middle`},o.border=vN;try{let n=e.addImage({base64:sN,extension:`png`});t.addImage(n,{tl:{nativeCol:0,nativeColOff:1237500,nativeRow:0,nativeRowOff:42862},ext:{width:90,height:51},editAs:`oneCell`})}catch{}let s=t.getCell(`D1`);s.value=n,s.font={bold:!0,size:18,name:fN},s.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},s.border=vN;let c=t.getCell(`G1`);c.value=`No: ${i}`,c.font={size:12,name:fN},c.alignment={vertical:`middle`},c.border={top:_N,left:_N,right:_N};let l=t.getCell(`G2`);l.value=`Version: ${r??`unknown`}`,l.font={size:12,name:fN},l.alignment={vertical:`middle`},l.border={left:_N,right:_N};let u=t.getCell(`G3`);u.value=`Issue Date: ${a}`,u.font={size:12,name:fN},u.alignment={vertical:`middle`},u.border={left:_N,right:_N,bottom:_N};let d=t.getCell(`A4`);d.value=`SUN ASTERISK VIETNAM CO., LTD`,d.font={bold:!0,size:10,name:fN},d.alignment={vertical:`middle`},d.border=vN;let f=t.getCell(`G4`);f.value=`ISO/IEC 27001:2022 & ISO 9001:2015`,f.font={bold:!0,size:10,name:fN},f.alignment={horizontal:`right`,vertical:`middle`,wrapText:!0},f.border=vN}var xN=[`#`,`Sheet name`,`Passed`,`Failed`,`Pending`,`N/A`,`Remain`,`Total`];function SN(e,t,n,r){let i=e.addWorksheet(`Overview`);i.columns=[{width:4},{width:6},{width:26},{width:13},{width:13},{width:13},{width:13},{width:13},{width:13}];let a=t[0]?.summary.screen??``;bN(e,i,r?.titleLabel??`${a.toUpperCase()} TESTCASE`,n,r?.formNo);let o=i.getRow(7);o.height=20,xN.forEach((e,t)=>{let n=o.getCell(2+t);n.value=e,n.font={bold:!0,size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:gN},n.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},n.border=vN});let s={passed:0,failed:0,pending:0,na:0,remain:0,total:0},c=(e,t,n)=>{let r=i.getRow(e);t.forEach((e,t)=>{let i=r.getCell(2+t);i.value=e,i.font={bold:n,size:10,color:mN,name:pN},i.alignment={horizontal:t<=1?`left`:`center`,vertical:`middle`},i.border=vN,n&&(i.fill={type:`pattern`,pattern:`solid`,fgColor:gN})})},l=e=>e.replace(/'/g,`''`),u=(e,t,n)=>({formula:`'${l(e)}'!${t}`,result:n}),d=8,f=d;t.forEach((e,t)=>{let n=e.summary,r=Math.max(0,n.total-n.passed-n.na);c(d,[t+1,e.sheetName,u(e.sheetName,`D7`,n.passed),u(e.sheetName,`E7`,n.failed),u(e.sheetName,`F7`,n.pending),u(e.sheetName,`G7`,n.na),u(e.sheetName,`H7`,r),u(e.sheetName,`C7`,n.total)],!1),s.passed+=n.passed,s.failed+=n.failed,s.pending+=n.pending,s.na+=n.na,s.remain+=r,s.total+=n.total,d+=1});let p=d-1,m=(e,t)=>({formula:`SUM(${e}${f}:${e}${p})`,result:t});c(d,[``,`Total`,m(`D`,s.passed),m(`E`,s.failed),m(`F`,s.pending),m(`G`,s.na),m(`H`,s.remain),m(`I`,s.total)],!0)}function CN(e,t,n,r,i,a){let o=e.addWorksheet(t,{views:[{state:`frozen`,ySplit:0,xSplit:0}]});o.columns=[{width:20},{width:12.5},{width:15.38},{width:16.25},{width:17},{width:25.5},{width:24.88},{width:50},{width:41},{width:12},{width:13.5},{width:15.88},{width:13.5},{width:16.5},{width:23},{width:29}],bN(e,o,`${n.screen.toUpperCase()} TESTCASE`,a);for(let e=5;e<=8;e++)o.getRow(e);for(let[e,t]of Object.entries({C:`Total TCs`,D:`Passed`,E:`Failed`,F:`Pending`,G:`N/A`,H:`Remaining`})){let n=o.getCell(`${e}6`);n.value=t,n.font={bold:!0,size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:gN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN}let s=1e4,c={C:{formula:`COUNTA(A14:A${s})`,result:n.total},D:{formula:`COUNTIF(L14:L${s},"Passed")`,result:n.passed},E:{formula:`COUNTIF(L14:L${s},"Failed")`,result:n.failed},F:{formula:`COUNTIF(L14:L${s},"Pending")`,result:n.pending},G:{formula:`COUNTIF(L14:L${s},"N/A")`,result:n.na},H:{formula:`C7-D7-G7`,result:n.failed+n.pending}};for(let[e,t]of Object.entries(c)){let n=o.getCell(`${e}7`);n.value=t,n.font={size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:hN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN,e===`H`&&(n.numFmt=`#,##0`)}let l=o.getCell(`C8`);l.font={size:10,color:mN,name:pN},l.fill={type:`pattern`,pattern:`solid`,fgColor:hN},l.alignment={horizontal:`center`,vertical:`top`},l.border=vN;let u={D:{formula:`IFERROR(D7/(C7-G7),0)`,result:n.passed/Math.max(1,n.total-n.na)},E:{formula:`IFERROR(E7/(C7-G7),0)`,result:n.failed/Math.max(1,n.total-n.na)},F:{formula:`IFERROR(F7/(C7-G7),0)`,result:n.pending/Math.max(1,n.total-n.na)},G:{formula:`IFERROR(G7/(C7-G7),0)`,result:n.na/Math.max(1,n.total-n.na)},H:{formula:`IFERROR(H7/(C7-G7),0)`,result:(n.failed+n.pending)/Math.max(1,n.total-n.na)}};for(let[e,t]of Object.entries(u)){let n=o.getCell(`${e}8`);n.value=t,n.font={size:10,color:mN,name:pN},n.fill={type:`pattern`,pattern:`solid`,fgColor:hN},n.alignment={horizontal:`center`,vertical:`top`},n.border=vN,n.numFmt=`0%`}for(;o.rowCount<9;)o.addRow([]);let d=o.addRow([`Spec/Design link:`,i]);d.getCell(1).font={bold:!0},d.getCell(2).font={color:{argb:`FF1F4E78`},underline:!0},o.addRow([]);let f=o.addRow([`*: Mandatory`]);f.getCell(1).font={italic:!0,color:{argb:`FF808080`}};let p=o.addRow([`TC ID*`,`Screen/Function`,`Big item`,`Medium item`,`Test Object`,`Pre-condition`,`Test Data`,`Steps*`,`Expected results*`,`Priority`,`Testcase type`,`Test Result*`,`Executed Date*`,`Test Executor*`,`Test Environment`,`Note
120
120
  (Test evidence, DefectID, Actual result)`]);p.height=38,p.eachCell(e=>{e.font={bold:!0,color:{argb:lN}},e.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:cN}},e.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},yN(e)}),o.views=[{state:`normal`}];let m=[`Basic Flow`,`Alternate Flow`,`Exception Flow`,`Accessing`,`GUI`,`Function`],h=new Map;for(let e of r){let t=h.get(e.category2)||[];t.push(e),h.set(e.category2,t)}let g=new Set;function _(e,t){let n=o.addRow([]);n.getCell(2).value=e,n.getCell(2).font={bold:!0},n.eachCell({includeEmpty:!1},e=>{e.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:uN}}});for(let e=1;e<=16;e++){let t=n.getCell(e);t.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:uN}},yN(t)}for(let e of t){let t=o.addRow([e.tcId,``,``,``,e.category1,e.precondition,e.testData,e.steps,e.expectedResults,e.priority,e.testcaseType,e.testResult,e.executedDate,e.testExecutor,e.testEnvironment,e.note]);t.alignment={vertical:`top`,wrapText:!0},t.eachCell({includeEmpty:!0},(e,t)=>{if(yN(e),t===1&&(e.font={bold:!0}),t===12){let t=String(e.value||``);t===`Passed`?e.font={color:{argb:`FF107C41`},bold:!0}:t===`Failed`?e.font={color:{argb:`FFC00000`},bold:!0}:t===`Pending`?e.font={color:{argb:`FF996D00`},bold:!0}:t===`N/A`&&(e.font={color:{argb:`FF808080`}})}})}}for(let e of m){let t=h.get(e);!t||t.length===0||(g.add(e),_(e,t))}for(let[e,t]of h.entries())g.has(e)||_(e,t);o.autoFilter={from:{row:p.number,column:1},to:{row:o.rowCount,column:16}},o.sheetProtection={sheet:!0,objects:!1,scenarios:!1}}var wN=`FF2E5984`,TN=`FFFFFFFF`;function EN(e,t){let n=e.addWorksheet(`API detail`),r=`Arial`;n.columns=[{header:`Endpoint`,width:35},{header:`Method`,width:10},{header:`Auth / Datasource`,width:22},{header:`Request shape`,width:40},{header:`Expected-status matrix`,width:30},{header:`Flow steps`,width:40},{header:`Concurrency invariant`,width:35}];let i=n.getRow(1);i.height=30,i.eachCell(e=>{e.font={bold:!0,color:{argb:TN},name:r},e.fill={type:`pattern`,pattern:`solid`,fgColor:{argb:wN}},e.alignment={horizontal:`center`,vertical:`middle`,wrapText:!0},yN(e)}),n.views=[{state:`frozen`,ySplit:1}];for(let e of t){let t=n.addRow([e.endpoint,e.method,e.authDatasource,e.requestShape,e.expectedStatusMatrix,e.flowSteps,e.concurrencyInvariant]);t.alignment={vertical:`top`,wrapText:!0},t.eachCell({includeEmpty:!0},e=>{yN(e),e.font={name:r}})}n.autoFilter={from:{row:1,column:1},to:{row:n.rowCount,column:7}}}function DN(e,t){if(e.length===0)throw Error(`renderXlsxMultiSheet requires at least one locale sheet`);let n=new oN.default.Workbook;n.creator=`sungen delivery`,n.created=new Date,SN(n,e,t?.sungenVersion);for(let r of e)CN(n,r.sheetName,r.summary,r.rows,r.specLink,t?.sungenVersion);return n}function ON(e){let t=e.features??[],n=e=>e.platform?`${e.featureBaseName}.${e.platform}`:e.featureBaseName;if(t.length>1)return t.map(t=>({basename:n(t),featureName:t.featureName,specLink:t.specLink??e.specLink,summary:t.summary,scenarios:t.scenarios,locales:t.locales,apiDetail:t.apiDetail}));let r=t[0];return[{basename:r?n(r):e.name,featureName:r?.featureName??e.featureName,specLink:r?.specLink??e.specLink,summary:r?.summary??e.summary,scenarios:r?.scenarios??e.scenarios,locales:r?.locales,apiDetail:r?.apiDetail}]}var kN=420*60*1e3;function AN(e,t){let n=IN(e,t.screens),r=VN();for(let t of n)for(let n of ON(t)){let t=n.locales&&n.locales.length>=2?n.locales.map(e=>({locale:e.locale,summary:e.summary,scenarios:e.scenarios})):[{locale:``,summary:n.summary,scenarios:n.scenarios}];for(let i of t){let t=jN(n,e.environment.sungenVersion,i.summary,i.scenarios),a=i.locale?`.${i.locale}`:``;WN(`${n.basename}-testcases${a}_${r}.csv`,t,`text/csv;charset=utf-8`)}}}function jN(e,t,n,r){let i=BN(),a=n??e.summary,o=r??e.scenarios,s=a.total||1,c=e=>`${Math.round(e/s*100)}%`,l=`${e.basename.toUpperCase()} TESTCASE`,u=e.specLink??``,d=[];d.push(UN([``,``,``,l,``,``,`No: BM-2-901-13`,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,`Version: ${t}`,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,`Issue Date: ${i}`,``,``,``,``,``,``,``,``,``])),d.push(UN([`SUN ASTERISK VIETNAM CO., LTD`,``,``,``,``,``,`ISO/IEC 27001:2022 & ISO 9001:2015`,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,`Total TCs`,`Passed`,`Failed`,`Pending`,`N/A`,`Remaining`,``,``,``,``,``,``,``,``])),d.push(UN([``,``,a.total,a.passed,a.failed,a.pending,a.na,a.pending+a.na,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,c(a.passed),c(a.failed),c(a.pending),c(a.na),c(a.pending+a.na),``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([`Spec/Design link:`,u,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([``,``,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([`*: Mandatory`,``,``,``,``,``,``,``,``,``,``,``,``,``,``,``])),d.push(UN([`TC ID*`,`Screen/Function`,`Big item`,`Medium item`,`Test Object`,`Pre-condition`,`Test Data`,`Steps*`,`Expected results*`,`Priority`,`Testcase type`,`Test Result*`,`Executed Date*`,`Test Executor*`,`Test Environment`,`Note
121
121
  (Test evidence, DefectID, Actual result)`]));let f=[`Accessing`,`GUI`,`Function`],p=new Map;for(let e of o){let t=p.get(e.category2)||[];t.push(e),p.set(e.category2,t)}let m=new Set,h=(e,t)=>{d.push(UN([``,e,``,``,``,``,``,``,``,``,``,``,``,``,``,``]));for(let e of t)d.push(UN(LN(e)))};for(let e of f){let t=p.get(e);!t||t.length===0||(m.add(e),h(e,t))}for(let[e,t]of p.entries())m.has(e)||h(e,t);return``+d.join(`
122
122
  `)+`