@sun-asterisk/sungen 3.2.2-beta.9 → 3.2.3-beta.3

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 (346) hide show
  1. package/dist/capabilities/discover.d.ts.map +1 -1
  2. package/dist/capabilities/discover.js +26 -3
  3. package/dist/capabilities/discover.js.map +1 -1
  4. package/dist/cli/commands/add-flow.d.ts.map +1 -1
  5. package/dist/cli/commands/add-flow.js +2 -0
  6. package/dist/cli/commands/add-flow.js.map +1 -1
  7. package/dist/cli/commands/add.d.ts.map +1 -1
  8. package/dist/cli/commands/add.js +4 -0
  9. package/dist/cli/commands/add.js.map +1 -1
  10. package/dist/cli/commands/capability.d.ts.map +1 -1
  11. package/dist/cli/commands/capability.js +61 -0
  12. package/dist/cli/commands/capability.js.map +1 -1
  13. package/dist/cli/commands/delivery.d.ts.map +1 -1
  14. package/dist/cli/commands/delivery.js +89 -2
  15. package/dist/cli/commands/delivery.js.map +1 -1
  16. package/dist/cli/commands/eval.js +3 -3
  17. package/dist/cli/commands/eval.js.map +1 -1
  18. package/dist/cli/commands/generate.d.ts.map +1 -1
  19. package/dist/cli/commands/generate.js +2 -1
  20. package/dist/cli/commands/generate.js.map +1 -1
  21. package/dist/cli/commands/init.d.ts.map +1 -1
  22. package/dist/cli/commands/init.js +32 -2
  23. package/dist/cli/commands/init.js.map +1 -1
  24. package/dist/cli/commands/journey.d.ts.map +1 -1
  25. package/dist/cli/commands/journey.js +24 -2
  26. package/dist/cli/commands/journey.js.map +1 -1
  27. package/dist/cli/commands/update.d.ts.map +1 -1
  28. package/dist/cli/commands/update.js +10 -3
  29. package/dist/cli/commands/update.js.map +1 -1
  30. package/dist/dashboard/snapshot-builder.d.ts.map +1 -1
  31. package/dist/dashboard/snapshot-builder.js +10 -1
  32. package/dist/dashboard/snapshot-builder.js.map +1 -1
  33. package/dist/exporters/csv-exporter.d.ts.map +1 -1
  34. package/dist/exporters/csv-exporter.js +3 -1
  35. package/dist/exporters/csv-exporter.js.map +1 -1
  36. package/dist/exporters/json-exporter.js +3 -1
  37. package/dist/exporters/json-exporter.js.map +1 -1
  38. package/dist/exporters/mobile-app-id.d.ts +22 -0
  39. package/dist/exporters/mobile-app-id.d.ts.map +1 -0
  40. package/dist/exporters/mobile-app-id.js +37 -0
  41. package/dist/exporters/mobile-app-id.js.map +1 -0
  42. package/dist/exporters/spec-parser.d.ts.map +1 -1
  43. package/dist/exporters/spec-parser.js +6 -2
  44. package/dist/exporters/spec-parser.js.map +1 -1
  45. package/dist/generators/test-generator/adapters/adapter-interface.d.ts +3 -0
  46. package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
  47. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +7 -4
  48. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +20 -3
  49. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +4 -1
  50. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +4 -1
  51. package/dist/generators/test-generator/adapters/appium/templates/test-file.hbs +3 -0
  52. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  53. package/dist/generators/test-generator/code-generator.js +48 -9
  54. package/dist/generators/test-generator/code-generator.js.map +1 -1
  55. package/dist/generators/test-generator/template-engine.d.ts +3 -0
  56. package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
  57. package/dist/generators/test-generator/template-engine.js +11 -1
  58. package/dist/generators/test-generator/template-engine.js.map +1 -1
  59. package/dist/generators/test-generator/utils/selector-resolver.d.ts +11 -1
  60. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  61. package/dist/generators/test-generator/utils/selector-resolver.js +33 -0
  62. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  63. package/dist/harness/audit.d.ts.map +1 -1
  64. package/dist/harness/audit.js +8 -1
  65. package/dist/harness/audit.js.map +1 -1
  66. package/dist/harness/catalog/universal-viewpoints.yaml +15 -0
  67. package/dist/harness/eval/skill-lint.d.ts +3 -3
  68. package/dist/harness/eval/skill-lint.d.ts.map +1 -1
  69. package/dist/harness/eval/skill-lint.js +88 -68
  70. package/dist/harness/eval/skill-lint.js.map +1 -1
  71. package/dist/harness/journey.d.ts +37 -1
  72. package/dist/harness/journey.d.ts.map +1 -1
  73. package/dist/harness/journey.js +146 -19
  74. package/dist/harness/journey.js.map +1 -1
  75. package/dist/harness/quality-gates.d.ts +13 -0
  76. package/dist/harness/quality-gates.d.ts.map +1 -1
  77. package/dist/harness/quality-gates.js +23 -0
  78. package/dist/harness/quality-gates.js.map +1 -1
  79. package/dist/harness/sensors.d.ts +1 -1
  80. package/dist/harness/sensors.d.ts.map +1 -1
  81. package/dist/harness/sensors.js +32 -9
  82. package/dist/harness/sensors.js.map +1 -1
  83. package/dist/orchestrator/ai-rules-updater.d.ts +11 -3
  84. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
  85. package/dist/orchestrator/ai-rules-updater.js +44 -180
  86. package/dist/orchestrator/ai-rules-updater.js.map +1 -1
  87. package/dist/orchestrator/ai-skills/adapters.d.ts +28 -0
  88. package/dist/orchestrator/ai-skills/adapters.d.ts.map +1 -0
  89. package/dist/orchestrator/ai-skills/adapters.js +34 -0
  90. package/dist/orchestrator/ai-skills/adapters.js.map +1 -0
  91. package/dist/orchestrator/ai-skills/build.d.ts +10 -0
  92. package/dist/orchestrator/ai-skills/build.d.ts.map +1 -0
  93. package/dist/orchestrator/ai-skills/build.js +128 -0
  94. package/dist/orchestrator/ai-skills/build.js.map +1 -0
  95. package/dist/orchestrator/ai-skills/cap-stripper.d.ts +27 -0
  96. package/dist/orchestrator/ai-skills/cap-stripper.d.ts.map +1 -0
  97. package/dist/orchestrator/ai-skills/cap-stripper.js +78 -0
  98. package/dist/orchestrator/ai-skills/cap-stripper.js.map +1 -0
  99. package/dist/orchestrator/ai-skills/commands.d.ts +22 -0
  100. package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -0
  101. package/dist/orchestrator/ai-skills/commands.js +109 -0
  102. package/dist/orchestrator/ai-skills/commands.js.map +1 -0
  103. package/dist/orchestrator/ai-skills/generator.d.ts +23 -0
  104. package/dist/orchestrator/ai-skills/generator.d.ts.map +1 -0
  105. package/dist/orchestrator/ai-skills/generator.js +79 -0
  106. package/dist/orchestrator/ai-skills/generator.js.map +1 -0
  107. package/dist/orchestrator/ai-skills/golden-skills.test.d.ts +2 -0
  108. package/dist/orchestrator/ai-skills/golden-skills.test.d.ts.map +1 -0
  109. package/dist/orchestrator/ai-skills/golden-skills.test.js +183 -0
  110. package/dist/orchestrator/ai-skills/golden-skills.test.js.map +1 -0
  111. package/dist/orchestrator/ai-skills/resolve-assistants.d.ts +8 -0
  112. package/dist/orchestrator/ai-skills/resolve-assistants.d.ts.map +1 -0
  113. package/dist/orchestrator/ai-skills/resolve-assistants.js +28 -0
  114. package/dist/orchestrator/ai-skills/resolve-assistants.js.map +1 -0
  115. package/dist/orchestrator/ai-skills/writer.d.ts +15 -0
  116. package/dist/orchestrator/ai-skills/writer.d.ts.map +1 -0
  117. package/dist/orchestrator/ai-skills/writer.js +129 -0
  118. package/dist/orchestrator/ai-skills/writer.js.map +1 -0
  119. package/dist/orchestrator/flow-manager.d.ts +11 -0
  120. package/dist/orchestrator/flow-manager.d.ts.map +1 -1
  121. package/dist/orchestrator/flow-manager.js +147 -29
  122. package/dist/orchestrator/flow-manager.js.map +1 -1
  123. package/dist/orchestrator/mobile-runtime-scaffolder.d.ts +59 -0
  124. package/dist/orchestrator/mobile-runtime-scaffolder.d.ts.map +1 -0
  125. package/dist/orchestrator/mobile-runtime-scaffolder.js +298 -0
  126. package/dist/orchestrator/mobile-runtime-scaffolder.js.map +1 -0
  127. package/dist/orchestrator/project-initializer.d.ts +44 -7
  128. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  129. package/dist/orchestrator/project-initializer.js +147 -79
  130. package/dist/orchestrator/project-initializer.js.map +1 -1
  131. package/dist/orchestrator/screen-manager.d.ts +30 -0
  132. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  133. package/dist/orchestrator/screen-manager.js +205 -22
  134. package/dist/orchestrator/screen-manager.js.map +1 -1
  135. package/dist/orchestrator/templates/ai-src/README.md +58 -0
  136. package/dist/orchestrator/templates/{ai-instructions/claude-cmd-add-flow.md → ai-src/commands/add-flow.md} +63 -2
  137. package/dist/orchestrator/templates/{ai-instructions/claude-cmd-add-screen.md → ai-src/commands/add-screen.md} +171 -6
  138. package/dist/orchestrator/templates/{ai-instructions/claude-cmd-create-test.md → ai-src/commands/create-test.md} +118 -5
  139. package/{src/orchestrator/templates/ai-instructions/claude-cmd-dashboard.md → dist/orchestrator/templates/ai-src/commands/dashboard.md} +25 -3
  140. package/{src/orchestrator/templates/ai-instructions/claude-cmd-delivery.md → dist/orchestrator/templates/ai-src/commands/delivery.md} +67 -3
  141. package/dist/orchestrator/templates/ai-src/commands/design.md +29 -0
  142. package/{src/orchestrator/templates/ai-instructions/claude-cmd-feedback.md → dist/orchestrator/templates/ai-src/commands/feedback.md} +34 -3
  143. package/dist/orchestrator/templates/{ai-instructions/claude-cmd-locale.md → ai-src/commands/locale.md} +56 -4
  144. package/{src/orchestrator/templates/ai-instructions/claude-cmd-review.md → dist/orchestrator/templates/ai-src/commands/review.md} +57 -2
  145. package/dist/orchestrator/templates/{ai-instructions/claude-cmd-run-test.md → ai-src/commands/run-test.md} +116 -8
  146. package/dist/orchestrator/templates/ai-src/config/codex.md +8 -0
  147. package/{src/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md → dist/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md} +11 -0
  148. package/dist/orchestrator/templates/{ai-instructions/github-skill-sungen-error-mapping.md → ai-src/skills/sungen-error-mapping/SKILL.md} +31 -10
  149. package/{src/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md → dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md} +5 -5
  150. package/{src/orchestrator/templates/ai-instructions/claude-skill-locale.md → dist/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md} +275 -3
  151. package/{src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md → dist/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md} +17 -0
  152. package/{src/orchestrator/templates/ai-instructions/claude-skill-selector-fix-mobile.md → dist/orchestrator/templates/ai-src/skills/sungen-selector-fix-mobile/SKILL.md} +5 -0
  153. package/dist/orchestrator/templates/{ai-instructions/claude-skill-tc-generation.md → ai-src/skills/sungen-tc-generation/SKILL.md} +5 -0
  154. package/dist/orchestrator/templates/playwright.config.ts +7 -4
  155. package/package.json +3 -3
  156. package/src/capabilities/discover.ts +29 -3
  157. package/src/cli/commands/add-flow.ts +2 -0
  158. package/src/cli/commands/add.ts +4 -0
  159. package/src/cli/commands/capability.ts +64 -1
  160. package/src/cli/commands/delivery.ts +89 -2
  161. package/src/cli/commands/eval.ts +3 -3
  162. package/src/cli/commands/generate.ts +2 -1
  163. package/src/cli/commands/init.ts +50 -3
  164. package/src/cli/commands/journey.ts +20 -3
  165. package/src/cli/commands/update.ts +14 -4
  166. package/src/dashboard/snapshot-builder.ts +10 -1
  167. package/src/exporters/csv-exporter.ts +3 -1
  168. package/src/exporters/json-exporter.ts +3 -1
  169. package/src/exporters/mobile-app-id.ts +34 -0
  170. package/src/exporters/spec-parser.ts +6 -2
  171. package/src/generators/test-generator/adapters/adapter-interface.ts +3 -0
  172. package/src/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +7 -4
  173. package/src/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +20 -3
  174. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +4 -1
  175. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +4 -1
  176. package/src/generators/test-generator/adapters/appium/templates/test-file.hbs +3 -0
  177. package/src/generators/test-generator/code-generator.ts +49 -9
  178. package/src/generators/test-generator/template-engine.ts +14 -1
  179. package/src/generators/test-generator/utils/selector-resolver.ts +51 -1
  180. package/src/harness/audit.ts +9 -2
  181. package/src/harness/catalog/universal-viewpoints.yaml +15 -0
  182. package/src/harness/eval/skill-lint.ts +71 -60
  183. package/src/harness/journey.ts +167 -19
  184. package/src/harness/quality-gates.ts +20 -0
  185. package/src/harness/sensors.ts +25 -8
  186. package/src/orchestrator/ai-rules-updater.ts +35 -197
  187. package/src/orchestrator/ai-skills/adapters.ts +52 -0
  188. package/src/orchestrator/ai-skills/build.ts +103 -0
  189. package/src/orchestrator/ai-skills/cap-stripper.ts +85 -0
  190. package/src/orchestrator/ai-skills/commands.ts +112 -0
  191. package/src/orchestrator/ai-skills/generator.ts +47 -0
  192. package/src/orchestrator/ai-skills/golden-skills.test.ts +124 -0
  193. package/src/orchestrator/ai-skills/resolve-assistants.ts +18 -0
  194. package/src/orchestrator/ai-skills/writer.ts +92 -0
  195. package/src/orchestrator/flow-manager.ts +165 -29
  196. package/src/orchestrator/mobile-runtime-scaffolder.ts +277 -0
  197. package/src/orchestrator/project-initializer.ts +159 -86
  198. package/src/orchestrator/screen-manager.ts +237 -22
  199. package/src/orchestrator/templates/ai-src/README.md +58 -0
  200. package/src/orchestrator/templates/{ai-instructions/claude-cmd-add-flow.md → ai-src/commands/add-flow.md} +63 -2
  201. package/src/orchestrator/templates/{ai-instructions/claude-cmd-add-screen.md → ai-src/commands/add-screen.md} +171 -6
  202. package/src/orchestrator/templates/{ai-instructions/claude-cmd-create-test.md → ai-src/commands/create-test.md} +118 -5
  203. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-dashboard.md → src/orchestrator/templates/ai-src/commands/dashboard.md} +25 -3
  204. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-delivery.md → src/orchestrator/templates/ai-src/commands/delivery.md} +67 -3
  205. package/src/orchestrator/templates/ai-src/commands/design.md +29 -0
  206. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-feedback.md → src/orchestrator/templates/ai-src/commands/feedback.md} +34 -3
  207. package/src/orchestrator/templates/{ai-instructions/claude-cmd-locale.md → ai-src/commands/locale.md} +56 -4
  208. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-review.md → src/orchestrator/templates/ai-src/commands/review.md} +57 -2
  209. package/src/orchestrator/templates/{ai-instructions/claude-cmd-run-test.md → ai-src/commands/run-test.md} +116 -8
  210. package/src/orchestrator/templates/ai-src/config/codex.md +8 -0
  211. package/{dist/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md → src/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md} +11 -0
  212. package/{dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md → src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md} +31 -10
  213. package/{dist/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md → src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md} +5 -5
  214. package/{dist/orchestrator/templates/ai-instructions/claude-skill-locale.md → src/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md} +275 -3
  215. package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md → src/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md} +17 -0
  216. package/{dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix-mobile.md → src/orchestrator/templates/ai-src/skills/sungen-selector-fix-mobile/SKILL.md} +5 -0
  217. package/src/orchestrator/templates/{ai-instructions/claude-skill-tc-generation.md → ai-src/skills/sungen-tc-generation/SKILL.md} +5 -0
  218. package/src/orchestrator/templates/playwright.config.ts +7 -4
  219. package/dist/orchestrator/templates/ai-instructions/claude-cmd-design.md +0 -12
  220. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +0 -347
  221. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +0 -86
  222. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +0 -131
  223. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +0 -94
  224. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-dashboard.md +0 -65
  225. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +0 -83
  226. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-design.md +0 -13
  227. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +0 -24
  228. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-locale.md +0 -70
  229. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +0 -38
  230. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +0 -158
  231. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +0 -184
  232. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +0 -85
  233. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-locale.md +0 -291
  234. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +0 -316
  235. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +0 -221
  236. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +0 -617
  237. package/src/orchestrator/templates/ai-instructions/claude-cmd-design.md +0 -12
  238. package/src/orchestrator/templates/ai-instructions/claude-skill-api-design.md +0 -62
  239. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-mcp.md +0 -82
  240. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-pat.md +0 -117
  241. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-live.md +0 -60
  242. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-local.md +0 -38
  243. package/src/orchestrator/templates/ai-instructions/claude-skill-capture.md +0 -35
  244. package/src/orchestrator/templates/ai-instructions/claude-skill-dashboard.md +0 -121
  245. package/src/orchestrator/templates/ai-instructions/claude-skill-delivery.md +0 -141
  246. package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +0 -176
  247. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +0 -446
  248. package/src/orchestrator/templates/ai-instructions/claude-skill-ingest-legacy.md +0 -79
  249. package/src/orchestrator/templates/ai-instructions/claude-skill-mobile-gestures.md +0 -109
  250. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +0 -347
  251. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +0 -320
  252. package/src/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +0 -118
  253. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-a-data-entry.md +0 -203
  254. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-b-data-ops.md +0 -179
  255. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-c-data-explore.md +0 -233
  256. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-d-display.md +0 -226
  257. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-e-identity.md +0 -177
  258. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +0 -118
  259. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +0 -86
  260. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +0 -131
  261. package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +0 -94
  262. package/src/orchestrator/templates/ai-instructions/copilot-cmd-dashboard.md +0 -65
  263. package/src/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +0 -83
  264. package/src/orchestrator/templates/ai-instructions/copilot-cmd-design.md +0 -13
  265. package/src/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +0 -24
  266. package/src/orchestrator/templates/ai-instructions/copilot-cmd-locale.md +0 -70
  267. package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +0 -38
  268. package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +0 -158
  269. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md +0 -62
  270. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +0 -184
  271. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md +0 -82
  272. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md +0 -117
  273. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md +0 -60
  274. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md +0 -38
  275. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md +0 -35
  276. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-dashboard.md +0 -121
  277. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +0 -141
  278. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +0 -176
  279. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +0 -446
  280. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +0 -85
  281. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-ingest-legacy.md +0 -79
  282. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-locale.md +0 -291
  283. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-mobile-gestures.md +0 -109
  284. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +0 -316
  285. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +0 -221
  286. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +0 -617
  287. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +0 -320
  288. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +0 -118
  289. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md +0 -203
  290. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md +0 -179
  291. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md +0 -233
  292. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md +0 -226
  293. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md +0 -177
  294. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +0 -118
  295. /package/dist/orchestrator/templates/{ai-instructions/claude-agent-challenge.md → ai-src/agents/challenge.md} +0 -0
  296. /package/dist/orchestrator/templates/{ai-instructions/claude-agent-discovery.md → ai-src/agents/discovery.md} +0 -0
  297. /package/dist/orchestrator/templates/{ai-instructions/claude-agent-generator.md → ai-src/agents/generator.md} +0 -0
  298. /package/dist/orchestrator/templates/{ai-instructions/claude-agent-reviewer.md → ai-src/agents/reviewer.md} +0 -0
  299. /package/dist/orchestrator/templates/{ai-instructions/claude-config.md → ai-src/config/claude.md} +0 -0
  300. /package/dist/orchestrator/templates/{ai-instructions/copilot-config.md → ai-src/config/copilot.md} +0 -0
  301. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-api-design.md → ai-src/skills/sungen-api-design/SKILL.md} +0 -0
  302. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture.md → ai-src/skills/sungen-capture/SKILL.md} +0 -0
  303. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-figma-mcp.md → ai-src/skills/sungen-capture/mode-figma-mcp.md} +0 -0
  304. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-figma-pat.md → ai-src/skills/sungen-capture/mode-figma-pat.md} +0 -0
  305. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-live.md → ai-src/skills/sungen-capture/mode-live.md} +0 -0
  306. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-local.md → ai-src/skills/sungen-capture/mode-local.md} +0 -0
  307. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-dashboard.md → ai-src/skills/sungen-dashboard/SKILL.md} +0 -0
  308. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-delivery.md → ai-src/skills/sungen-delivery/SKILL.md} +0 -0
  309. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-gherkin-syntax.md → ai-src/skills/sungen-gherkin-syntax/SKILL.md} +0 -0
  310. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-ingest-legacy.md → ai-src/skills/sungen-ingest-legacy/SKILL.md} +0 -0
  311. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-mobile-gestures.md → ai-src/skills/sungen-mobile-gestures/SKILL.md} +0 -0
  312. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-selector-keys.md → ai-src/skills/sungen-selector-keys/SKILL.md} +0 -0
  313. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-tc-review.md → ai-src/skills/sungen-tc-review/SKILL.md} +0 -0
  314. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-test-design-techniques.md → ai-src/skills/sungen-test-design-techniques/SKILL.md} +0 -0
  315. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint.md → ai-src/skills/sungen-viewpoint/SKILL.md} +0 -0
  316. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-a-data-entry.md → ai-src/skills/sungen-viewpoint/group-a-data-entry.md} +0 -0
  317. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-b-data-ops.md → ai-src/skills/sungen-viewpoint/group-b-data-ops.md} +0 -0
  318. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-c-data-explore.md → ai-src/skills/sungen-viewpoint/group-c-data-explore.md} +0 -0
  319. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-d-display.md → ai-src/skills/sungen-viewpoint/group-d-display.md} +0 -0
  320. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-e-identity.md → ai-src/skills/sungen-viewpoint/group-e-identity.md} +0 -0
  321. /package/src/orchestrator/templates/{ai-instructions/claude-agent-challenge.md → ai-src/agents/challenge.md} +0 -0
  322. /package/src/orchestrator/templates/{ai-instructions/claude-agent-discovery.md → ai-src/agents/discovery.md} +0 -0
  323. /package/src/orchestrator/templates/{ai-instructions/claude-agent-generator.md → ai-src/agents/generator.md} +0 -0
  324. /package/src/orchestrator/templates/{ai-instructions/claude-agent-reviewer.md → ai-src/agents/reviewer.md} +0 -0
  325. /package/src/orchestrator/templates/{ai-instructions/claude-config.md → ai-src/config/claude.md} +0 -0
  326. /package/src/orchestrator/templates/{ai-instructions/copilot-config.md → ai-src/config/copilot.md} +0 -0
  327. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md → src/orchestrator/templates/ai-src/skills/sungen-api-design/SKILL.md} +0 -0
  328. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md → src/orchestrator/templates/ai-src/skills/sungen-capture/SKILL.md} +0 -0
  329. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-figma-mcp.md} +0 -0
  330. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-figma-pat.md} +0 -0
  331. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-live.md} +0 -0
  332. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-local.md} +0 -0
  333. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-dashboard.md → src/orchestrator/templates/ai-src/skills/sungen-dashboard/SKILL.md} +0 -0
  334. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md → src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md} +0 -0
  335. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md → src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md} +0 -0
  336. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-ingest-legacy.md → src/orchestrator/templates/ai-src/skills/sungen-ingest-legacy/SKILL.md} +0 -0
  337. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-mobile-gestures.md → src/orchestrator/templates/ai-src/skills/sungen-mobile-gestures/SKILL.md} +0 -0
  338. /package/src/orchestrator/templates/{ai-instructions/claude-skill-selector-keys.md → ai-src/skills/sungen-selector-keys/SKILL.md} +0 -0
  339. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md → src/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md} +0 -0
  340. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md → src/orchestrator/templates/ai-src/skills/sungen-test-design-techniques/SKILL.md} +0 -0
  341. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md} +0 -0
  342. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-a-data-entry.md} +0 -0
  343. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-b-data-ops.md} +0 -0
  344. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-c-data-explore.md} +0 -0
  345. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-d-display.md} +0 -0
  346. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-e-identity.md} +0 -0
@@ -1,320 +0,0 @@
1
- ---
2
- name: sungen-tc-review
3
- description: 'Test case review — 7-dimension rubric (100 pts), Syntax gate + Coverage matrix. Auto-loaded by review command.'
4
- user-invocable: false
5
- ---
6
-
7
- ## How to use this skill
8
-
9
- Review one `.feature` (plus `selectors.yaml` + `test-data.yaml` if present) in 3 steps:
10
-
11
- 1. **Syntax Gate (Layer A)** — check Sungen syntax. On a hard-fail, return to the author; do NOT proceed to detailed scoring.
12
- 2. **Coverage Matrix (Layer B)** — map against Sun Common Checklist viewpoints; list the gaps.
13
- 3. **Scoring (Layer C)** — score the 7-dimension/100-pt rubric. Layers A and B are *how* to evaluate each dimension, not separate bonus points.
14
-
15
- > Scope: Sungen tests run through Playwright — **UI-only**. No DB/API/email-body/server-side. Out-of-scope viewpoints (see Out-of-scope) are NOT penalized; if required, mandate `@manual` + a technical reason.
16
-
17
- ---
18
-
19
- ## Scoring (7 dimensions, 100 points)
20
-
21
- **≥ 70**: PASS | **50–69**: CONDITIONAL (fix before execution) | **< 50**: FAIL (revise & re-review)
22
-
23
- **Scoring convention**: Each row in a dimension table is scored independently. Full points if satisfied across all in-scope TCs; otherwise deduct ~1 pt per distinct violation, floor 0 per row (never negative). A row whose technique has no relevant case → 0 for that row only, it does not zero the whole dimension. Sum the rows for the dimension total.
24
-
25
- | Dimension | Pts |
26
- |---|---|
27
- | Structure & Format | 15 |
28
- | Coverage (6 sub-dimensions) | 30 |
29
- | Assertion Quality | 20 |
30
- | Test Data | 10 |
31
- | Security & Permission | 10 |
32
- | Automation Readiness | 10 |
33
- | Maintainability | 5 |
34
- | **Total** | **100** |
35
-
36
- ---
37
-
38
- ## Layer A — Syntax Gate (against `sungen-gherkin-syntax`)
39
-
40
- Hard-fail gate. Any ✗ is a syntax error — must be fixed; do not score further while errors remain.
41
-
42
- ### A1. Structure & Keyword
43
-
44
- - [ ] Correct shape: `User <Action> [Target] <Type> [in [Parent] pType] [with {{v}}] [is State]`
45
- - [ ] Actor is always `User`, active voice
46
- - [ ] `Given` → only `is on` · `When` → action (click/fill/select/press/clear/check/uncheck/hover/wait) · `Then` → only `see` · `And` inherits the preceding keyword
47
- - [ ] NO `Given User see…` (→ `Then`, or entry assertion `Given User is on [X] page`)
48
- - [ ] NO `When … And User is on [X] dialog` (→ `And User see` or a separate `Given`)
49
- - [ ] NO literal-URL navigation (`navigate to "/x"`) → `User is on [X] page` + declare in `selectors.yaml`
50
-
51
- ### A2. Action → Element type
52
-
53
- - [ ] checkbox/toggle → `check`/`uncheck` (NOT `click`)
54
- - [ ] dropdown → `select … with {{v}}` · field/textarea/search → `fill … with {{v}}` · button/tab/link/icon → `click`
55
- - [ ] radio: select another option via `check [Other] radio`, NOT `uncheck` a radio
56
- - [ ] `press` only for keys (`press Enter key`), NOT `press [Submit] button`
57
- - [ ] Element type is in the valid type table (Context/Input/Trigger/Data/Feedback/System)
58
- - [ ] `wait for` only for Spinner/Modal, minimize usage
59
-
60
- ### A3. Value — State — click-rule
61
-
62
- - [ ] Dynamic data: `with {{snake_case}}`, NO hardcoding (`with {{admin@mail.com}}` → ✗ `with {{invalid_email}}`)
63
- - [ ] State: `is <state>` (hidden/visible/disabled/checked/empty/loading…), NOT `{{disabled}}`, NOT missing `is`
64
- - [ ] **click + value**: static (`button/link/icon/tab`) takes NO value; dynamic (`row/item/card/option`) takes `with {{v}}`
65
- - [ ] `fill` always has a target type (`fill [email] field with {{v}}`, not `fill [email] with {{v}}`)
66
-
67
- ### A4. Assertion (8 patterns → determines the Playwright assertion)
68
-
69
- - [ ] Visibility `see [T] type` → NO redundant `is visible`; hidden uses `is hidden`
70
- - [ ] Correct pattern: text(`message/header/label with {{v}}`) · partial(`text contains {{v}}`) · input(`field/dropdown with {{v}}`) · state(`is …`) · attribute(`image/link with {{v}}`) · count(`row with {{count}}`) · page(`[T] page`)
71
- - [ ] Table: `[Col] column in [Table] table`, `[Ref] row in [Table] table with {{v}}`, `table with {{count}}`/`is empty`, `table match data:`; row scope used correctly
72
-
73
- ### A5. Alert / Scope / Background
74
-
75
- - [ ] Alert step appears **before** the action that triggers the dialog
76
- - [ ] Scope-dependent flow (dialog/frame) → use `@steps`/`@extend`, do NOT cram into `Background`
77
- - [ ] `@extend`: entry assertion must be `Given User is on [X] type`, NOT `Given User see`; name `@steps:module__action` (snake/kebab)
78
- - [ ] Scenario name matches the step's element type (a scenario that says "modal" must use `[X] dialog/modal` consistently)
79
-
80
- ### A6. YAML & Variables
81
-
82
- - [ ] Selector keys: lowercase, keep Unicode, use **spaces** (no underscores/dots); same label → `--type`/`--N` suffix; names >30 chars → shorten to 1–3 words
83
- - [ ] Types requiring explicit YAML: `date-picker`, `uploader`, `overlay`, `frame`, `step`
84
- - [ ] Every `{{var}}` in `.feature` exists in `test-data.yaml`; NO orphan keys
85
- - [ ] Dynamic vars (`{{$timestamp}}`/`{{$uuid}}`/`{{$random:a:b}}`) used correctly for run-unique data (CRUD)
86
- - [ ] `locator` (CSS) only as a last resort
87
-
88
- ### A7. Tags & Flow
89
-
90
- - [ ] Exactly **one** priority tag per scenario (`@high`/`@normal`/`@low`…)
91
- - [ ] `@manual`/`@auth:role`/`@no-auth`/`@cleanup:*`/`@parallel`/`@flow` used in the right context
92
- - [ ] `@parallel` is REQUIRED when a feature mixes auth groups (`@auth:user` + `@no-auth`)
93
- - [ ] `@flow`: `[Screen:Element]` namespace is consistent; YAML keys quoted with the colon (`"login:submit":`)
94
-
95
- ---
96
-
97
- ## Layer B — Coverage Matrix (against Sun Common Checklist for QA)
98
-
99
- Build a mapping table: for each applicable group, does the feature have a matching scenario → list the **gaps**. Each group maps to a Sungen VP classification.
100
-
101
- | Category | Sub-viewpoint to check | VP map | Sungen representation |
102
- |---|---|---|---|
103
- | **Check Accessing** | Not logged in → redirect login; logged in with correct role; wrong role → access denied/hide menu | VP-SEC | `@no-auth` (→ login), `@auth:role` (right/wrong role) |
104
- | **Check Initial** | Default field state; autofocus; tab order; display per spec | VP-UI | `Then User see [T] field is empty/focused`, `see [T] page` |
105
- | **Check Required** | Submit with one / multiple required fields blank | VP-VAL | empty `fill` → `see [Err] message with {{v}}` |
106
- | **Check Format** | Email/phone… invalid format; leading/trailing space; uppercase | VP-VAL | `with {{invalid_email}}` → error |
107
- | **Check Maxlength** | Exceed maxlength per field | VP-VAL | `with {{over_max_name}}` → error/blocked input |
108
- | **Check Exist/Duplicate** | Duplicate email/username | VP-VAL | `with {{existing_email}}` → "already exists" |
109
- | **Check Valid** | Happy path: all valid fields; required-only | VP-UI/LOGIC | real data → success message + post-action state |
110
- | **Check Expire** | OTP/token/link expired | VP-LOGIC | usually `@manual` (time-dependent) |
111
- | **Behavior Handling** | Rapid double-click; slow network; reload keeps/loses data; copy-paste; Enter in field | VP-LOGIC | `double click`, `wait for [Spinner]`, `press Enter key` |
112
- | **Account Status** | Deleted / blocked / inactive account login | VP-LOGIC | corresponding account data → error message |
113
- | **Security** | SQL Injection; XSS; Data Integrity (edit dropdown/remove `disabled` via DevTools → server rejects). SQL on LIKE/search fields → 2 TCs per the `sungen-viewpoint` SQL 2-layer rule. | VP-SEC | `with {{xss_*}}`/`{{sql_*}}`; data-integrity usually `@manual` |
114
- | **Cross-surface outcomes** | Admin action → outcome on user-facing surface (portal, mobile, widget); spec defines display condition on another URL | VP-LOGIC-CS | `@high @manual` per surface per business rule — at minimum 1 per cross-surface rule; use `@auth:role` + `@extend` if surface reachable in same test run |
115
-
116
- **Tier-aware**: if the suite only has `@high` (Tier 1) → do NOT penalize missing pure VP-UI (deferred to Tier 2). Require full VP coverage only on a Full review.
117
-
118
- ### EP/BVA rules when mapping
119
-
120
- - **EP**: keep only **one representative** per invalid class; same-class duplicates → flag as redundant.
121
- - **BVA**: spec defines min/max → cover `min-1`, `min`, `max`, `max+1` (Maxlength, counts…).
122
- - Error messages must match the spec **word-for-word**, not generic.
123
- - **Data-driven (`@cases`)**: a `@cases:<dataset>` scenario legitimately covers many inputs in ONE scenario (one row per EP class / boundary / rule). Do **not** flag it as "too few negative cases" or as duplication — instead review the **dataset rows**: are all EP classes / boundary triples present, each labelled, expected values exact? N near-identical scenarios that differ only by input value → flag and recommend collapsing to `@cases`.
124
-
125
- ---
126
-
127
- ## Layer C — Dimension details
128
-
129
- ### Structure & Format (15)
130
-
131
- | Check | Pts |
132
- |---|---|
133
- | ID format `VP-<CAT>-<NNN>` (e.g. `VP-LOGIC-001`, `VP-VAL-001`); deleted IDs never reused | 3 |
134
- | Clear title: `[object] + [result/behavior] + [condition]` | 3 |
135
- | Correct module/screen + exactly **one** priority tag | 2 |
136
- | `Given` = state (`User is on [T] page`), not an action | 3 |
137
- | `When`/`And` = atomic steps (1 action), no vague words, last step is the trigger | 2 |
138
- | `Then` is specific & measurable (`see [T] type with {{v}}`/`is state`), not mere existence | 2 |
139
-
140
- ### Coverage (30) — 6 sub-dimensions
141
-
142
- | Sub | Technique | Pts | What to check |
143
- |---|---|---|---|
144
- | Happy paths | — | 5 | ≥1 happy path per core function; realistic data; full result assertions |
145
- | Negative | EP | 6 | one representative per invalid class, no duplicates; error matches spec |
146
- | Edge | EP | 5 | empty/whitespace, special chars (XSS/SQLi), long strings, abnormal file uploads |
147
- | Boundary | BVA | 6 | `min-1/min/max/max+1` per range |
148
- | State transition | ST | 4 | all valid transitions + ≥3 blocked transitions (**UI-only**; full points if all spec states covered) |
149
- | Condition combo | DT | 4 | decision table for ≥2 dependent conditions; test only rules with distinct outcomes |
150
-
151
- > Use the quick estimate `(VPs_covered / 6) * 30` ONLY when cases can't be inspected in depth (portfolio scan); never combine the two methods in one score.
152
-
153
- ### Assertion Quality (20)
154
-
155
- | Check | Pts |
156
- |---|---|
157
- | Specific, not generic — "if this assertion PASSES, am I sure the feature works?" must be a confident yes | 6 |
158
- | Avoids anti-patterns: re-asserting input just typed; exact-match on dynamic content; missing negative assertions | 6 |
159
- | **Syntax compliance** — steps match `sungen-gherkin-syntax` patterns, correct `[Ref] type with {{v}}`, no bare `is visible` | 4 |
160
- | Grouping — each case has 2–7 related assertions for the same action | 4 |
161
-
162
- ### Test Data (10)
163
-
164
- | Check | Pts |
165
- |---|---|
166
- | No hardcoded env values in `.feature` — use `{{variables}}` | 3 |
167
- | **Allow test credentials** in `test-data.yaml` if: (a) `.feature` uses `{{var}}` not hardcoded, (b) dedicated test accounts (not prod/personal), (c) env-specific values via `<screen>.<env>.yaml` overrides | 3 |
168
- | Idempotent — has teardown or unique data (`{{$timestamp}}`/`{{$uuid}}`) so it can run repeatedly | 2 |
169
- | Realistic data — accented names, real formats, not `abc`/`1` | 2 |
170
-
171
- ### Security & Permission (10) — UI-level
172
-
173
- | Check | Pts |
174
- |---|---|
175
- | Authentication — `@no-auth` → redirect login; expired/forged token tests are `@manual` + reason | 3 |
176
- | Authorization — via `@auth:role`: each role sees the correct elements/pages | 3 |
177
- | Viewpoint classification — VP-UI/VAL/LOGIC/SEC assigned correctly | 2 |
178
- | Input security — XSS/SQLi via `{{xss_*}}`/`{{sql_*}}` | 2 |
179
-
180
- ### Automation Readiness (10)
181
-
182
- | Check | Pts |
183
- |---|---|
184
- | `@manual` has a valid **technical** reason (not "don't know how to automate" — document as `# TODO: automate when...` comment instead) | 3 |
185
- | Stable selectors — per `sungen-selector-keys`: keys use spaces, standard types, `locator` only as last resort | 3 |
186
- | Each step names a concrete element by name/label/role (enough to implement without asking) | 2 |
187
- | Idempotent + no fixed waits (`wait for [T] dialog` instead of `wait N seconds`) | 2 |
188
-
189
- ### Maintainability (5)
190
-
191
- | Check | Pts |
192
- |---|---|
193
- | Title reflects the **assertion**, not the action (reading the title tells you when it FAILS) | 2 |
194
- | No duplicate TCs; remove obsolete tests when a feature is removed; no same-class VP/EP redundancy | 1 |
195
- | Short enough: `Background` ≤2 lines, scenario ≤10 steps, 2–7 assertions | 1 |
196
- | Comments where needed: `# --- Section:` for VP grouping; `@manual` explains why | 1 |
197
-
198
- ---
199
-
200
- ## Out-of-scope (UI-only Sungen)
201
-
202
- Do NOT deduct points when a `.feature` lacks the following viewpoints (Playwright UI cannot verify them). If required → `@manual` + reason, or move to another test layer:
203
-
204
- - `API Behavior` (direct status/body response)
205
- - `Email Verification` content (header/from/to/body/link) — only the post-click UI is verifiable
206
- - Server-side `Data Integrity` (DevTools edits payload → server rejects)
207
- - `Performance/Load`, `Rate limit`
208
- - DB/record verification after an action
209
-
210
- ---
211
-
212
- ## Quick Scan (run first, ~2 minutes)
213
-
214
- 10 questions; many "No" → return to author, skip detailed review.
215
-
216
- 1. ID unique + correct format `VP-<CAT>-<NNN>`?
217
- 2. Title understandable immediately, no context needed?
218
- 3. Every step uses the right keyword (`Given`=is on / `When`=action / `Then`=see)?
219
- 4. Every `{{var}}` exists in `test-data.yaml`?
220
- 5. At least one happy path?
221
- 6. Negative cases for invalid classes (EP)?
222
- 7. Boundary covers the 4 points (`min-1/min/max/max+1`)?
223
- 8. `Then` specific, not generic, no redundant `is visible`?
224
- 9. Test data doesn't hardcode env/static values?
225
- 10. Exactly one priority tag + valid functional tags?
226
-
227
- **Interpret**: 9–10 Yes → detailed review | 6–8 Yes → review with caveats | <6 Yes → return for revision.
228
-
229
- ---
230
-
231
- ## Auto-fix (on detection → suggest fix)
232
-
233
- > **Never renumber existing `VP-<CAT>-<NNN>` IDs while fixing** (e.g. after removing an EP duplicate). IDs are the dashboard's tracking key — renumbering survivors loses their pass/fail history. Leave gaps; only assign the next unused number to genuinely new scenarios.
234
-
235
- 1. **Wrong keyword/action-type** → correct it (`click checkbox` → `check checkbox`; `Given … see` → `Then …`).
236
- 2. **Hardcoded data** → `with {{snake_case}}` + add the key to `test-data.yaml`.
237
- 3. **Redundant `is visible` / state as value** → drop `is visible`; `{{disabled}}` → `is disabled`.
238
- 4. **Missing target type** → add the type (`fill [email] field with {{v}}`).
239
- 5. **click static with value** → remove value; **click dynamic missing value** → add `with {{v}}`.
240
- 6. **Same-class EP duplicates** → keep one representative.
241
- 7. **Generic expected result** → rewrite to assert specific field/element/state.
242
- 8. **Missing BVA** → add `min-1/min/max/max+1`.
243
- 9. **Missing negative path** → map invalid classes, add scenarios.
244
- 10. **All `@high`** → reset by user impact per the `sungen-gherkin-syntax` priority table (auth/CRUD/security/required → `@high`; format/standard-range boundary/search → `@normal`; cosmetic → `@low`).
245
- 11. **`@manual` without reason** → add a technical reason comment explaining why automation is not possible.
246
- 12. **Orphan var in test-data** → delete or reconnect.
247
- 13. **Unnecessary CSS/locator selector** → switch to role+name/label/text; keys use spaces.
248
- 14. **Scope crammed into `Background`** → split into `@steps`/`@extend`.
249
- 15. **Mixed auth groups missing `@parallel`** → add `@parallel`.
250
- 16. **Missing secondary behaviors** — spec defines tiebreaker, fallback rule, or secondary sort but no scenario tests it? Add 1 `@high` TC per rule.
251
- 17. **Missing concurrency scenarios** — spec or test-viewpoint mentions multi-tab, multi-user, or simultaneous actions but no `@manual` scenario exists? Add 1 `@manual` TC per risk (`@normal` by default; `@high` if data integrity at risk).
252
-
253
- ---
254
-
255
- ## Unverified Selectors (non-scoring metric)
256
-
257
- If `selectors/<name>.yaml` exists, count lines matching `@needs-live-verify` (provisional selectors from Figma, not yet checked against a live page).
258
- - Report the count in the review output; **never** deduct points — the suite can PASS with unverified selectors.
259
- - If the count > 0, add to the summary: `⚠ <N> selectors flagged @needs-live-verify — run run-test against a live URL to verify.`
260
- - If `selectors.yaml` does not exist yet (not generated) → omit this metric entirely.
261
-
262
- ---
263
-
264
- ## Output Format
265
-
266
- ```markdown
267
- ## Review: <screen / feature>
268
- **Date**: YYYY-MM-DD | **Total TCs**: <n> | **Tier**: <1/2> | **Unverified selectors**: <n / n/a>
269
-
270
- | Dimension | Score | Max | Notes |
271
- |------------------------|-------|-----|-------|
272
- | Structure & Format | | 15 | |
273
- | Coverage | | 30 | x/6 sub-dimensions |
274
- | Assertion Quality | | 20 | |
275
- | Test Data | | 10 | |
276
- | Security & Permission | | 10 | |
277
- | Automation Readiness | | 10 | |
278
- | Maintainability | | 5 | |
279
- | **Total** | | 100 | **PASS / CONDITIONAL / FAIL** |
280
-
281
- ### Syntax Gate (Layer A — hard-fail)
282
- - [ ] Keyword→Action correct
283
- - [ ] Action→Type correct; click-rule correct
284
- - [ ] Assertions follow the 8 patterns, no redundant `is visible`
285
- - [ ] Every {{var}} exists in test-data.yaml; no orphan keys
286
- - [ ] Selector keys follow sungen-selector-keys; locator only as last resort
287
- - [ ] Tags valid; @parallel when mixing auth groups
288
- - Syntax errors found: <n>
289
-
290
- ### Coverage Matrix (Layer B)
291
- | Category | Has scenario? | Gap |
292
- |---|---|---|
293
- | Check Accessing | ✓/✗ | ... |
294
- | Check Required/Format/Maxlength/Duplicate/Valid | ... | ... |
295
- | Behavior Handling / Account Status | ... | ... |
296
- | Security (XSS/SQLi) | ... | ... |
297
- | Cross-surface outcomes | ... | ... |
298
-
299
- ### ✗ Must-fix
300
- 1. [DIMENSION] VP-XXX issue description
301
- → Fix: ...
302
-
303
- ### ⚠ Suggested
304
- 1. [TEST-DATA] ...
305
-
306
- ### ✓ Strengths
307
- - ...
308
-
309
- ### Recommendations (if CONDITIONAL/FAIL)
310
- - ...
311
- ```
312
-
313
- ---
314
-
315
- ## Scope & Maintenance
316
-
317
- - **When NOT to apply**: exploratory charters, performance/load scripts, pure NFR specs — this rubric grades functional test cases.
318
- - **Adapting weights**: a project may rebalance the 7 dimensions (e.g. security-critical service: Security→15, Maintainability→0) as long as the total stays 100 and the PASS/CONDITIONAL/FAIL thresholds are restated. Record any change in this section.
319
- - **References**: detailed syntax → `sungen-gherkin-syntax`; selector keys → `sungen-selector-keys`; VP classification → `sungen-viewpoint`; generation workflow → `sungen-tc-generation`.
320
- - **Owner / version**: Owner: `<QA Lead>` · Version: `2.0` · Last updated: `2026-06-03`.
@@ -1,118 +0,0 @@
1
- ---
2
- name: sungen-test-design-techniques
3
- description: 'Test design techniques (EP, BVA, Decision Table, State Transition) for systematic scenario generation from spec constraints. Auto-loaded by create-test command.'
4
- user-invocable: false
5
- ---
6
-
7
- ## When to Apply
8
-
9
- Apply selectively — not every screen needs all four techniques. Use the technique only when the spec provides the trigger condition.
10
-
11
- | Technique | Apply when spec mentions | Skip when |
12
- |---|---|---|
13
- | EP (Equivalence Partitioning) | Input types, categories, roles, valid/invalid ranges | No validation or only a required-field check |
14
- | BVA (Boundary Value Analysis) | Numeric range, string length, date range, count limit | No boundary defined in spec |
15
- | Decision Table | 2+ mutually dependent conditions with different outcomes | Conditions are independent of each other |
16
- | State Transition | Entity lifecycle, workflow states, status changes | No state machine in spec |
17
-
18
- **Rule:** These techniques determine **how many** and **which** scenarios to generate. `sungen-viewpoint` determines **which viewpoints** to cover.
19
-
20
- **Implementing the data table → `@cases` (data-driven):** when EP classes / BVA boundary triples /
21
- decision-table rows share the *same step shape* and differ only by input/expected values, encode
22
- them as ONE `@cases:<dataset>` scenario (each class/boundary/rule = one row in the test-data list,
23
- labelled by a `case` column) instead of N near-duplicate scenarios. The technique still decides the
24
- rows; `@cases` is how you write them compactly. See `sungen-gherkin-syntax` → Data-driven.
25
-
26
- ---
27
-
28
- ## 1. Equivalence Partitioning (EP)
29
-
30
- **Goal:** One representative per input class. If one value in a partition passes, all values in that partition pass.
31
-
32
- **How to apply:**
33
- 1. Extract partitions from `spec.md` constraints (e.g., field accepts 1-100)
34
- 2. Valid class: 1 <= value <= 100
35
- 3. Invalid class (below): value < 1
36
- 4. Invalid class (above): value > 100
37
- 5. Write **one** scenario per class
38
-
39
- **Anti-pattern:**
40
- ```gherkin
41
- # BAD — 3 scenarios, same class, same result:
42
- Scenario: VP-VAL-001 Enter value 10
43
- Scenario: VP-VAL-002 Enter value 50
44
- Scenario: VP-VAL-003 Enter value 80
45
- ```
46
- ```gherkin
47
- # GOOD — one representative per class:
48
- Scenario: VP-VAL-001 Valid range value is accepted # value = 50
49
- Scenario: VP-VAL-002 Below minimum is rejected # value = 0
50
- Scenario: VP-VAL-003 Above maximum is rejected # value = 101
51
- ```
52
-
53
- ---
54
-
55
- ## 2. Boundary Value Analysis (BVA)
56
-
57
- **Goal:** Test exact edges where off-by-one errors occur (`>` vs `>=`, `<` vs `<=`).
58
-
59
- ### Two modes
60
-
61
- | Mode | Values | Use when |
62
- |---|---|---|
63
- | **Compact (default)** | `min-1`, `min`, `max`, `max+1` | Most fields |
64
- | **Full 6-point** | `min-1`, `min`, `min+1`, `max-1`, `max`, `max+1` | High-risk fields with `@high` priority |
65
-
66
- **How to apply** (example: "quantity must be 1-10"):
67
- - `min-1` = 0 -> invalid
68
- - `min` = 1 -> valid (lower boundary)
69
- - `max` = 10 -> valid (upper boundary)
70
- - `max+1` = 11 -> invalid
71
- - Midpoint (e.g., 5) already covered by EP valid class
72
-
73
- **BVA scenarios** (example: quantity 1-10) — 4 TCs per range:
74
- - `VP-VAL-010 Below minimum (0) is rejected`
75
- - `VP-VAL-011 Minimum boundary (1) is accepted`
76
- - `VP-VAL-012 Maximum boundary (10) is accepted`
77
- - `VP-VAL-013 Above maximum (11) is rejected`
78
-
79
- **Priority by field risk:**
80
- - Critical field / inclusive operator (`<=`, `>=`) / business-rule boundary → `@high` (Tier 1)
81
- - Standard field with a spec-defined range → `@normal` (Tier 2)
82
-
83
- **Low-risk fields:** Apply EP only (valid class + invalid class) — skip BVA entirely. Reserve BVA for fields where off-by-one errors have user impact (quantity limits, file size, password length, date ranges).
84
-
85
- ---
86
-
87
- ## 3. Decision Table
88
-
89
- **Goal:** Cover all condition combinations when 2+ conditions constrain each other.
90
-
91
- **How to apply:** List conditions from `spec.md` → build combination→outcome table → one scenario per row.
92
-
93
- **Cap:** When >3 boolean conditions (>8 rows), prioritize rows with **distinct outcomes** and add `@manual` for exhaustive combos.
94
-
95
- **Example** — Submit requires valid form AND permission → 4 combos, 2 distinct outcomes:
96
- - `@normal` Form invalid + no permission → disabled
97
- - `@normal` Form valid + no permission → disabled
98
- - `@normal` Has permission + form invalid → disabled
99
- - `@high` Form valid + has permission → succeeds
100
-
101
- **Tier mapping for DT rows:**
102
- - Row with a **distinct outcome not covered by any other row** → Tier 1 `@high`
103
- - Row whose outcome is already tested by another row (same result, different condition path) → Tier 2 `@normal`
104
- - When >3 boolean conditions (>8 rows): keep all distinct-outcome rows as Tier 1, move redundant-outcome rows to Tier 2 or `@manual`.
105
-
106
- ---
107
-
108
- ## 4. State Transition
109
-
110
- **Goal:** Verify every valid transition AND block invalid ones.
111
-
112
- **How to apply:** Extract state diagram from `spec.md` → one scenario per valid transition + key invalid transitions.
113
-
114
- **Example** — Order lifecycle (Draft→Pending→Approved→Completed):
115
- - `@high` Valid: Draft → Pending, Pending → Approved, Approved → Completed
116
- - `@normal` Invalid: Completed → Draft (blocked), Pending → Completed (skip approval)
117
-
118
- **test-data:** Use named state keys (`order_in_draft`, `order_in_pending`).
@@ -1,203 +0,0 @@
1
- # GROUP A: DATA ENTRY
2
-
3
- > The user feeds data into the system — field by field, file by file, or in bulk.
4
-
5
- Patterns: 1. Form & Inputs · 2. File Upload · 3. Import / Export
6
- See `SKILL.md` for the 4 Viewpoints, Shared Checks, and Security Tag Rules.
7
-
8
- ---
9
-
10
- ## 1. Form & Inputs
11
-
12
- > **Base pattern.** The field-level validation here is inherited by Create (4), Update (5), Login (15), Register (16), Password (17). Generate this as a standalone section only for a plain form with no more-specific role (settings, profile, contact) — see *Pattern selection* in `SKILL.md`.
13
-
14
- **Apply when**: the screen has at least 1 input field and 1 submit button that sends data to the server, and no more-specific pattern (4/5/15/16/17) applies.
15
-
16
- **Shared checks applied**: XSS/Injection
17
-
18
- ---
19
-
20
- ### Tier 1 — @high
21
-
22
- **[VP-LOGIC] Business behavior**
23
-
24
- - All required fields empty → Submit button is disabled, no request is sent on click
25
- - All required fields filled validly → Submit button becomes enabled and clickable
26
- - Submit the form with valid data → success feedback appears (toast/message/redirect), data is saved to the system
27
- - Submit the form → server returns an error (5xx, business error) → error message appears, all entered data is preserved on the form
28
- - User clicks submit twice in a row before the response arrives → only 1 request is sent, no duplicate record is created
29
- - Field A value changes → Field B updates its options accordingly immediately (field dependency; override if the spec uses field visibility: Field B is shown/hidden instead of changing options)
30
-
31
- **[VP-VAL] Input validation**
32
-
33
- - Submit while a required field is empty (applies if Submit is not disabled — Pattern B) → error message appears right at that field, not only a generic toast
34
- - Enter beyond max length → field accepts no more characters (HTML maxlength default; override if the spec uses server-side: input accepted but rejected on submit with an error stating the limit)
35
- - Enter the wrong format (email, phone, date…) → error message appears at the field, field is highlighted (text comes from {{format_error}} in test-data.yaml)
36
- - User fixes the field after an error → the error clears immediately once the value becomes valid (real-time clear)
37
- - Input containing only whitespace → treated as empty, submit shows the required error (override if the spec requires auto-trim and accept)
38
-
39
- **[VP-SEC]** → Apply Shared Check: XSS/Injection
40
-
41
- ---
42
-
43
- ### Tier 2 — @normal + @low
44
-
45
- **[VP-UI] Interface states**
46
-
47
- - [@normal] Required fields have a visual indicator (asterisk, color, "Required" label)
48
- - [@normal] Disabled fields: visually dimmed, cursor not-allowed, accept no input
49
- - [@normal] Focused field: border/outline highlight is clear, distinguishable from an unfocused field
50
- - [@low] Tab order: the Tab key moves focus in a logical order, top to bottom, left to right
51
- - [@low] Placeholder text: shows the correct hint text per spec, disappears once the user starts typing
52
- - [@low] Character counter (if the spec has one): shows the remaining character count, changes color near or at the limit
53
-
54
- **[VP-VAL] Boundary values**
55
-
56
- 4 TCs per range (min-1, min, max, max+1). Default tag = @normal (Tier 2).
57
- **Override to @high (Tier 1)** when the field is on a critical business rule or the spec uses inclusive operators (`<=`, `>=`).
58
-
59
- - [@normal] Exactly the min value → accepted, no error
60
- - [@normal] Exactly the max value → accepted, no error
61
- - [@normal] Min - 1 unit → rejected, appropriate error
62
- - [@normal] Max + 1 unit → rejected, appropriate error
63
-
64
- ---
65
-
66
- ### ⚡ Cross-pattern interactions
67
-
68
- - **+ Modal/Dialog**: Form inside a modal → on submit success the modal closes, background data updates immediately without a full-page reload
69
- - **+ Create/Add**: Apply this entire checklist. Add: the form opens as a blank slate, no data cached from a previous submit or a previous open
70
- - **+ Update/Edit**: Apply this entire checklist. Add: the form pre-fills the correct current data from the DB
71
- - **+ Notification**: Submit success → toast shows {{success_message}} from test-data.yaml, auto-dismisses after a few seconds
72
-
73
- ---
74
-
75
- ## 2. File Upload
76
-
77
- **Apply when**: the screen has a component letting the user upload a file (image, PDF, video, document…). It can be standalone or a field within a larger form.
78
-
79
- **Shared checks applied**: XSS/Injection (via file name)
80
-
81
- ---
82
-
83
- ### Tier 1 — @high
84
-
85
- **[VP-LOGIC] Upload behavior**
86
-
87
- - Upload a file of the right type and size → upload succeeds, file name/thumbnail/preview appears in the UI
88
- - Upload in progress → progress indicator appears, the form's submit button is disabled until the upload completes
89
- - Upload fails (network error, server timeout) → error message states the reason clearly, the user can retry
90
- - User removes an uploaded file → the file is removed from the form and deleted from the server immediately (override if the spec uses lazy delete: only deleted on form submit)
91
- - Multiple files (if the spec allows) → each file has its own upload progress and status
92
-
93
- **[VP-VAL] File constraints**
94
-
95
- - Upload a file with a disallowed extension (not in the whitelist) → rejected immediately, error lists the allowed types
96
- - Upload a file exceeding the size limit → rejected, error states the limit and the actual size of the selected file
97
- - Submit the form without uploading a file (field required) → "file required" error appears, the form does not submit
98
- - Upload an empty file (0 bytes) → rejected with an appropriate error
99
-
100
- **[VP-SEC]**
101
-
102
- - Upload a file with a valid extension but whose real MIME type is executable (file-type spoofing) → server validates the real MIME type and rejects it
103
- - File name containing a path-traversal string (`../../etc/passwd`, `../config`) → file name is sanitized, not executed, no path is exposed
104
- - Upload without authentication → 401/403, the file is not stored on the server
105
-
106
- ---
107
-
108
- ### Tier 2 — @normal + @low
109
-
110
- **[VP-UI] Interface states**
111
-
112
- - [@normal] Drop zone or "Choose file" button is clearly visible and easy to recognize
113
- - [@normal] The list of accepted file types and the size limit appear in the UI (helper text or tooltip)
114
- - [@normal] During upload: progress bar or percentage is shown, a cancel button is available
115
- - [@normal] Upload success: thumbnail (image) or file icon + file name + size are clearly shown
116
- - [@normal] Multiple upload with a limit: a "2/5 files" counter shows, the upload button hides/disables when the limit is reached
117
- - [@low] Drag & drop: dragging a file over the zone → drop zone highlights, upload starts automatically on drop
118
-
119
- **[VP-VAL] Edge cases**
120
-
121
- - [@normal] Upload a file with the same name as an existing one → rejected, error "File already exists" (override if the spec defines overwrite or auto-rename to file(1))
122
- - [@normal] File name with special characters or Unicode (accented Vietnamese) → upload succeeds, the name is displayed correctly
123
-
124
- ---
125
-
126
- ### ⚡ Cross-pattern interactions
127
-
128
- - **+ Form & Inputs**: Upload is a field in the form → the form cannot submit if the upload is incomplete or failed
129
- - **+ Create/Add**: The created record includes the correct file reference, the file is accessible after reopening the record
130
- - **+ Update/Edit**: The current file is shown → the user can replace it (new upload overwrites the old) or remove it separately
131
- - **+ Modal/Dialog**: Upload inside a modal → the modal does not close while uploading, progress is not lost
132
- - **+ Notification**: Upload success/fail → toast shows the correct message and the correct type (success/error)
133
-
134
- ---
135
-
136
- ## 3. Import / Export
137
-
138
- **Apply when**: the screen has a function to bulk-import data from a file (CSV, Excel) or export the current data to a file.
139
-
140
- **Shared checks applied**: Loading State
141
-
142
- ---
143
-
144
- ### Tier 1 — @high
145
-
146
- **[VP-LOGIC] Import behavior**
147
-
148
- *No preview:*
149
- - Upload a valid file (correct format, all required columns, valid data) → import succeeds, the number of imported records is clearly shown
150
- - After import → new data appears in the list/table immediately without a reload (override if the spec requires a manual reload)
151
- - Large file (many records, async processing) → UI shows "processing", the user gets a notification when done
152
-
153
- *With preview:*
154
- - Upload a file → a preview table appears with the parsed data, the user sees it before confirming
155
- - Preview shows inline errors for each invalid row: highlights the row, states the column and the reason
156
- - User confirms after viewing the preview → valid records are imported, invalid rows are skipped with a row-level error summary (override if the spec requires rejecting all when any row is invalid)
157
- - User cancels at the preview step → no record is created, the system returns to the state before the upload
158
-
159
- *Export:*
160
- - User clicks Export → the file download starts automatically, format CSV (override if the spec uses XLSX or another format)
161
- - Export with an active filter → the file contains only the filtered data, not the entire dataset
162
- - Export success → the file downloads without navigating the user away from the current page
163
-
164
- **[VP-VAL] File & data validation**
165
-
166
- - Import a file in the wrong format (not CSV/Excel, wrong delimiter) → rejected, error states the required format with an example
167
- - Import a file missing required columns → rejected, error lists the missing column names
168
- - Import a file with a wrong column header name → rejected, error lists the required column names (override if the spec allows partial import ignoring unknown columns)
169
- - Import records with a key that already exists → skip that row, count it under "Y skipped" in the result summary (override if the spec requires overwrite or rejecting the whole file)
170
- - Import a file with invalid data in cells (wrong type, over max length) → row-level errors state the row number, column, and reason
171
-
172
- **[VP-SEC]**
173
-
174
- - Import an Excel file containing formula injection (`=HYPERLINK(...)`, `=CMD(...)` in a cell) → the cell value is sanitized to plain text, not executed
175
- - Export another user's/tenant's data via IDOR (changing a param in the URL/request) → blocked, 403 Forbidden
176
-
177
- ---
178
-
179
- ### Tier 2 — @normal + @low
180
-
181
- **[VP-UI] Interface states**
182
-
183
- - [@normal] Import: accepted file types, size limit, and a "download template" link appear clearly before the user picks a file
184
- - [@normal] Import processing: progress/spinner shows, the Import button is disabled to prevent a double submit
185
- - [@normal] Import result summary: "X records imported, Y skipped, Z failed" is clearly shown, with a downloadable error report if the spec requires
186
- - [@normal] Export: the Export button switches to a loading state while generating the file
187
- - [@low] Template download: the template file has the correct column headers and at least 1 row of example data
188
-
189
- **[VP-VAL] Edge cases**
190
-
191
- - [@normal] Import an empty file (header row only, no data) → warning "No data to import", no crash, no record created
192
- - [@normal] Export when data is empty → the file still downloads, with the header row only and no data rows (override if the spec wants to block the download and show a "No data to export" toast)
193
- - [@normal] Export a large file (10k+ records) → the file generates within the allowed timeout, no 504 error
194
- - [@normal] Export encoding is correct: opening the CSV in Excel shows no broken Vietnamese font (UTF-8 BOM)
195
-
196
- ---
197
-
198
- ### ⚡ Cross-pattern interactions
199
-
200
- - **+ Data Table**: After import → the table auto-refreshes to show new records; Export takes exactly the data currently shown in the table
201
- - **+ Filter**: Export with an active filter → the exported file count matches the number of records shown in the UI
202
- - **+ Pagination**: After import → the total count in the pagination updates correctly
203
- - **+ Notification**: Import/Export complete (especially async) → toast or notification shows the result summary