@mohasinac/appkit 4.34.1 → 4.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +32 -2
  2. package/dist/features/tester/components/TesterChecklistStepRow.d.ts +9 -1
  3. package/dist/features/tester/components/TesterChecklistStepRow.js +31 -2
  4. package/dist/features/tester/components/TesterHubView.js +8 -0
  5. package/dist/features/tester/schemas/firestore.d.ts +109 -0
  6. package/dist/features/tester/schemas/firestore.js +14 -0
  7. package/dist/features/tester/seed-data/_money-flows.d.ts +23 -0
  8. package/dist/features/tester/seed-data/_money-flows.js +430 -0
  9. package/dist/features/tester/seed-data/authored/_types.d.ts +33 -0
  10. package/dist/features/tester/seed-data/authored/_types.js +35 -0
  11. package/dist/features/tester/seed-data/authored/account-auth__profile-settings.d.ts +2 -0
  12. package/dist/features/tester/seed-data/authored/account-auth__profile-settings.js +207 -0
  13. package/dist/features/tester/seed-data/authored/account-auth__signup-login.d.ts +2 -0
  14. package/dist/features/tester/seed-data/authored/account-auth__signup-login.js +298 -0
  15. package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.d.ts +2 -0
  16. package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.js +33 -0
  17. package/dist/features/tester/seed-data/authored/account-auth__testing-program.d.ts +2 -0
  18. package/dist/features/tester/seed-data/authored/account-auth__testing-program.js +138 -0
  19. package/dist/features/tester/seed-data/authored/addresses__address-filters.d.ts +2 -0
  20. package/dist/features/tester/seed-data/authored/addresses__address-filters.js +36 -0
  21. package/dist/features/tester/seed-data/authored/addresses__postal-lookup.d.ts +2 -0
  22. package/dist/features/tester/seed-data/authored/addresses__postal-lookup.js +75 -0
  23. package/dist/features/tester/seed-data/authored/addresses__postal-validation.d.ts +2 -0
  24. package/dist/features/tester/seed-data/authored/addresses__postal-validation.js +72 -0
  25. package/dist/features/tester/seed-data/authored/addresses__state-picker.d.ts +2 -0
  26. package/dist/features/tester/seed-data/authored/addresses__state-picker.js +54 -0
  27. package/dist/features/tester/seed-data/authored/addresses__unban-request.d.ts +2 -0
  28. package/dist/features/tester/seed-data/authored/addresses__unban-request.js +39 -0
  29. package/dist/features/tester/seed-data/authored/admin__bans-and-trust.d.ts +2 -0
  30. package/dist/features/tester/seed-data/authored/admin__bans-and-trust.js +226 -0
  31. package/dist/features/tester/seed-data/authored/admin__blog-faqs.d.ts +2 -0
  32. package/dist/features/tester/seed-data/authored/admin__blog-faqs.js +82 -0
  33. package/dist/features/tester/seed-data/authored/admin__bulk-actions.d.ts +2 -0
  34. package/dist/features/tester/seed-data/authored/admin__bulk-actions.js +177 -0
  35. package/dist/features/tester/seed-data/authored/admin__bundles.d.ts +2 -0
  36. package/dist/features/tester/seed-data/authored/admin__bundles.js +97 -0
  37. package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.d.ts +2 -0
  38. package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.js +232 -0
  39. package/dist/features/tester/seed-data/authored/admin__catalog-listings.d.ts +2 -0
  40. package/dist/features/tester/seed-data/authored/admin__catalog-listings.js +306 -0
  41. package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.d.ts +2 -0
  42. package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.js +158 -0
  43. package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.d.ts +2 -0
  44. package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.js +78 -0
  45. package/dist/features/tester/seed-data/authored/admin__content-deletes.d.ts +2 -0
  46. package/dist/features/tester/seed-data/authored/admin__content-deletes.js +261 -0
  47. package/dist/features/tester/seed-data/authored/admin__content-marketing.d.ts +2 -0
  48. package/dist/features/tester/seed-data/authored/admin__content-marketing.js +151 -0
  49. package/dist/features/tester/seed-data/authored/admin__coupons.d.ts +2 -0
  50. package/dist/features/tester/seed-data/authored/admin__coupons.js +214 -0
  51. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.d.ts +2 -0
  52. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +160 -0
  53. package/dist/features/tester/seed-data/authored/admin__media-watermark.d.ts +2 -0
  54. package/dist/features/tester/seed-data/authored/admin__media-watermark.js +104 -0
  55. package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.d.ts +2 -0
  56. package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.js +350 -0
  57. package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.d.ts +2 -0
  58. package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.js +105 -0
  59. package/dist/features/tester/seed-data/authored/admin__site-system.d.ts +2 -0
  60. package/dist/features/tester/seed-data/authored/admin__site-system.js +590 -0
  61. package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.d.ts +2 -0
  62. package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.js +235 -0
  63. package/dist/features/tester/seed-data/authored/admin__users-trust.d.ts +2 -0
  64. package/dist/features/tester/seed-data/authored/admin__users-trust.js +569 -0
  65. package/dist/features/tester/seed-data/authored/buying__bidding.d.ts +2 -0
  66. package/dist/features/tester/seed-data/authored/buying__bidding.js +417 -0
  67. package/dist/features/tester/seed-data/authored/buying__browsing-search.d.ts +2 -0
  68. package/dist/features/tester/seed-data/authored/buying__browsing-search.js +653 -0
  69. package/dist/features/tester/seed-data/authored/buying__buying-checkout.d.ts +2 -0
  70. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +533 -0
  71. package/dist/features/tester/seed-data/authored/buying__buying-coupons.d.ts +2 -0
  72. package/dist/features/tester/seed-data/authored/buying__buying-coupons.js +379 -0
  73. package/dist/features/tester/seed-data/authored/buying__cart.d.ts +2 -0
  74. package/dist/features/tester/seed-data/authored/buying__cart.js +1171 -0
  75. package/dist/features/tester/seed-data/authored/buying__image-tile-layout.d.ts +2 -0
  76. package/dist/features/tester/seed-data/authored/buying__image-tile-layout.js +140 -0
  77. package/dist/features/tester/seed-data/authored/buying__my-orders.d.ts +2 -0
  78. package/dist/features/tester/seed-data/authored/buying__my-orders.js +257 -0
  79. package/dist/features/tester/seed-data/authored/buying__offers.d.ts +2 -0
  80. package/dist/features/tester/seed-data/authored/buying__offers.js +1111 -0
  81. package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.d.ts +2 -0
  82. package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.js +252 -0
  83. package/dist/features/tester/seed-data/authored/buying__product-detail.d.ts +2 -0
  84. package/dist/features/tester/seed-data/authored/buying__product-detail.js +387 -0
  85. package/dist/features/tester/seed-data/authored/buying__return-request.d.ts +2 -0
  86. package/dist/features/tester/seed-data/authored/buying__return-request.js +152 -0
  87. package/dist/features/tester/seed-data/authored/buying__reviews-pagination.d.ts +2 -0
  88. package/dist/features/tester/seed-data/authored/buying__reviews-pagination.js +242 -0
  89. package/dist/features/tester/seed-data/authored/buying__reviews.d.ts +2 -0
  90. package/dist/features/tester/seed-data/authored/buying__reviews.js +113 -0
  91. package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.d.ts +2 -0
  92. package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.js +283 -0
  93. package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.d.ts +2 -0
  94. package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.js +167 -0
  95. package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.d.ts +2 -0
  96. package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.js +90 -0
  97. package/dist/features/tester/seed-data/authored/buying__wishlist-history.d.ts +2 -0
  98. package/dist/features/tester/seed-data/authored/buying__wishlist-history.js +344 -0
  99. package/dist/features/tester/seed-data/authored/community-support__public-profile.d.ts +2 -0
  100. package/dist/features/tester/seed-data/authored/community-support__public-profile.js +53 -0
  101. package/dist/features/tester/seed-data/authored/community-support__support-tickets.d.ts +2 -0
  102. package/dist/features/tester/seed-data/authored/community-support__support-tickets.js +76 -0
  103. package/dist/features/tester/seed-data/authored/content-discovery__blog.d.ts +2 -0
  104. package/dist/features/tester/seed-data/authored/content-discovery__blog.js +93 -0
  105. package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.d.ts +2 -0
  106. package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.js +149 -0
  107. package/dist/features/tester/seed-data/authored/content-discovery__coupons.d.ts +2 -0
  108. package/dist/features/tester/seed-data/authored/content-discovery__coupons.js +121 -0
  109. package/dist/features/tester/seed-data/authored/content-discovery__event-participation.d.ts +2 -0
  110. package/dist/features/tester/seed-data/authored/content-discovery__event-participation.js +207 -0
  111. package/dist/features/tester/seed-data/authored/content-discovery__events.d.ts +2 -0
  112. package/dist/features/tester/seed-data/authored/content-discovery__events.js +318 -0
  113. package/dist/features/tester/seed-data/authored/content-discovery__faq-help.d.ts +2 -0
  114. package/dist/features/tester/seed-data/authored/content-discovery__faq-help.js +65 -0
  115. package/dist/features/tester/seed-data/authored/content-discovery__notifications.d.ts +2 -0
  116. package/dist/features/tester/seed-data/authored/content-discovery__notifications.js +147 -0
  117. package/dist/features/tester/seed-data/authored/content-discovery__search.d.ts +2 -0
  118. package/dist/features/tester/seed-data/authored/content-discovery__search.js +332 -0
  119. package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.d.ts +2 -0
  120. package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.js +53 -0
  121. package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.d.ts +2 -0
  122. package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.js +52 -0
  123. package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.d.ts +2 -0
  124. package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.js +35 -0
  125. package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.d.ts +2 -0
  126. package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.js +141 -0
  127. package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.d.ts +2 -0
  128. package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.js +35 -0
  129. package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.d.ts +2 -0
  130. package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.js +95 -0
  131. package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.d.ts +2 -0
  132. package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.js +191 -0
  133. package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.d.ts +2 -0
  134. package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.js +158 -0
  135. package/dist/features/tester/seed-data/authored/design-ux__footer-theme.d.ts +2 -0
  136. package/dist/features/tester/seed-data/authored/design-ux__footer-theme.js +106 -0
  137. package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.d.ts +2 -0
  138. package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.js +88 -0
  139. package/dist/features/tester/seed-data/authored/design-ux__general-design.d.ts +2 -0
  140. package/dist/features/tester/seed-data/authored/design-ux__general-design.js +204 -0
  141. package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.d.ts +2 -0
  142. package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.js +301 -0
  143. package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.d.ts +2 -0
  144. package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.js +407 -0
  145. package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.d.ts +2 -0
  146. package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.js +214 -0
  147. package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.d.ts +2 -0
  148. package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.js +275 -0
  149. package/dist/features/tester/seed-data/authored/index.d.ts +2 -0
  150. package/dist/features/tester/seed-data/authored/index.js +237 -0
  151. package/dist/features/tester/seed-data/authored/page-wiring__data-loss.d.ts +2 -0
  152. package/dist/features/tester/seed-data/authored/page-wiring__data-loss.js +102 -0
  153. package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.d.ts +2 -0
  154. package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.js +50 -0
  155. package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.d.ts +2 -0
  156. package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.js +66 -0
  157. package/dist/features/tester/seed-data/authored/page-wiring__reachability.d.ts +2 -0
  158. package/dist/features/tester/seed-data/authored/page-wiring__reachability.js +115 -0
  159. package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.d.ts +2 -0
  160. package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.js +136 -0
  161. package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.d.ts +2 -0
  162. package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.js +69 -0
  163. package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.d.ts +2 -0
  164. package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.js +263 -0
  165. package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.d.ts +2 -0
  166. package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.js +102 -0
  167. package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.d.ts +2 -0
  168. package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.js +234 -0
  169. package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.d.ts +2 -0
  170. package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.js +126 -0
  171. package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.d.ts +2 -0
  172. package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.js +255 -0
  173. package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.d.ts +2 -0
  174. package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.js +59 -0
  175. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +2 -0
  176. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +88 -0
  177. package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.d.ts +2 -0
  178. package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.js +51 -0
  179. package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.d.ts +2 -0
  180. package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.js +35 -0
  181. package/dist/features/tester/seed-data/authored/selling__become-seller.d.ts +2 -0
  182. package/dist/features/tester/seed-data/authored/selling__become-seller.js +94 -0
  183. package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.d.ts +2 -0
  184. package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.js +107 -0
  185. package/dist/features/tester/seed-data/authored/selling__listing-a-product.d.ts +2 -0
  186. package/dist/features/tester/seed-data/authored/selling__listing-a-product.js +285 -0
  187. package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.d.ts +2 -0
  188. package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.js +326 -0
  189. package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.d.ts +2 -0
  190. package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.js +136 -0
  191. package/dist/features/tester/seed-data/authored/selling__media-limits.d.ts +2 -0
  192. package/dist/features/tester/seed-data/authored/selling__media-limits.js +128 -0
  193. package/dist/features/tester/seed-data/authored/selling__sectionised-forms.d.ts +2 -0
  194. package/dist/features/tester/seed-data/authored/selling__sectionised-forms.js +167 -0
  195. package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.d.ts +2 -0
  196. package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.js +117 -0
  197. package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.d.ts +2 -0
  198. package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.js +88 -0
  199. package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.d.ts +2 -0
  200. package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.js +151 -0
  201. package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.d.ts +2 -0
  202. package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.js +105 -0
  203. package/dist/features/tester/seed-data/authored/selling__seller-guide.d.ts +2 -0
  204. package/dist/features/tester/seed-data/authored/selling__seller-guide.js +33 -0
  205. package/dist/features/tester/seed-data/authored/selling__seller-listing-types.d.ts +2 -0
  206. package/dist/features/tester/seed-data/authored/selling__seller-listing-types.js +347 -0
  207. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.d.ts +2 -0
  208. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +166 -0
  209. package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.d.ts +2 -0
  210. package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.js +89 -0
  211. package/dist/features/tester/seed-data/authored/selling__seller-orders.d.ts +2 -0
  212. package/dist/features/tester/seed-data/authored/selling__seller-orders.js +195 -0
  213. package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.d.ts +2 -0
  214. package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.js +180 -0
  215. package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.d.ts +2 -0
  216. package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.js +164 -0
  217. package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.d.ts +2 -0
  218. package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.js +116 -0
  219. package/dist/features/tester/seed-data/authored/seo__canonical-and-host.d.ts +2 -0
  220. package/dist/features/tester/seed-data/authored/seo__canonical-and-host.js +111 -0
  221. package/dist/features/tester/seed-data/authored/seo__og-images.d.ts +2 -0
  222. package/dist/features/tester/seed-data/authored/seo__og-images.js +91 -0
  223. package/dist/features/tester/seed-data/authored/seo__page-metadata.d.ts +2 -0
  224. package/dist/features/tester/seed-data/authored/seo__page-metadata.js +122 -0
  225. package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.d.ts +2 -0
  226. package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.js +105 -0
  227. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +744 -1
  228. package/dist/seed/carousel-slides-seed-data.js +1 -1
  229. package/dist/seed/products-standard-seed-data.js +2 -2
  230. package/dist/seed/reviews-seed-data.js +6 -1
  231. package/package.json +1 -1
  232. package/scripts/seed-cli.mjs +6 -0
@@ -0,0 +1,332 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the content-discovery/search page.
3
+ * WHAT: 20 case(s), keyed by full checklist id.
4
+ *
5
+ * Written by hand, case by case, against the label each one states. There is no
6
+ * generator: the authoring scripts were deleted once it was clear they were
7
+ * scaffolding around work that is simply writing.
8
+ *
9
+ * 🛑 EVERY SEARCH CASE HERE CARRIES A CONTROL, because a search box that has
10
+ * stopped filtering returns plausible rows for any real term and looks identical
11
+ * to one that works. "zzzznope" returning zero is what separates the two, and it
12
+ * is the only assertion in this file that cannot pass by accident.
13
+ *
14
+ * @tag domain:tester
15
+ * @tag layer:seed
16
+ * @tag pattern:none
17
+ * @tag access:server-only
18
+ * @tag consumers:seed-data/authored/index.ts
19
+ * @tag sideEffects:none
20
+ */
21
+ export const authored = {
22
+ "checklist-content-discovery-search-search-typeahead-differs": {
23
+ roles: ["guest"],
24
+ startPage: "/",
25
+ steps: [
26
+ "Open / in a private window with no session.",
27
+ "Click into the header search and type dranzer.",
28
+ "Write down every suggestion offered.",
29
+ "Clear the box and type dragoon.",
30
+ "Write down every suggestion offered.",
31
+ "Compare the two lists.",
32
+ ],
33
+ inputs: { query1: "dranzer", query2: "dragoon" },
34
+ expectedBehaviour: "Suggestions are computed from the current query. Two different queries producing identical suggestions means the list is not query-driven at all — it is a fixed set of popular items wearing a typeahead's clothes.",
35
+ expectedUiState: "'dranzer' suggests Dranzer items and 'dragoon' suggests Dragoon items. The two lists are visibly different. Identical lists are the failure even when both look plausible.",
36
+ endResult: "Read-only; nothing persists.",
37
+ },
38
+ "checklist-content-discovery-search-search-typeahead-no-drafts": {
39
+ roles: ["guest"],
40
+ startPage: "/",
41
+ steps: [
42
+ "Open / in a private window with no session.",
43
+ "Click into the header search and type beyblade.",
44
+ "Read every suggestion and note its title.",
45
+ "Open each suggestion in turn and read the page it lands on.",
46
+ "Note any that 404s or shows an unpublished listing.",
47
+ ],
48
+ inputs: { query: "beyblade" },
49
+ expectedBehaviour: "Suggestions are filtered to published, publicly-visible listings. A status filter applied only when the caller explicitly asks for one is absent here, because a typeahead rarely asks — which is exactly how draft rows reach a public suggestion list.",
50
+ expectedUiState: "Every suggestion opens a real published listing. None 404s, none opens a draft or archived listing, and none names a tester sandbox item for a signed-out visitor.",
51
+ expectedData: { draftSuggestions: 0 },
52
+ endResult: "Read-only; nothing persists.",
53
+ },
54
+ "checklist-content-discovery-search-search-prefix-match": {
55
+ roles: ["guest"],
56
+ startPage: "/products",
57
+ steps: [
58
+ "Open /products in a private window and read the total result count.",
59
+ "Type dran in the search field and click 'Search'.",
60
+ "Read the result count and every card title.",
61
+ "Clear the field, type zzzznope, and click 'Search'.",
62
+ "Read the result count.",
63
+ ],
64
+ inputs: { prefixQuery: "dran", nonsenseQuery: "zzzznope" },
65
+ expectedBehaviour: "A prefix matches whole words that begin with it, so a partial term still finds the product. Search is tokenised on an edge-n-gram field for exactly this reason — an exact-equality search would need the buyer to type the full title.",
66
+ expectedUiState: "'dran' returns Dranzer and Dran Sword items and a count lower than the unfiltered total. 'zzzznope' returns zero and an empty state, not the full catalogue.",
67
+ expectedData: { nonsenseResultCount: 0 },
68
+ endResult: "Read-only; nothing persists beyond the URL.",
69
+ },
70
+ "checklist-content-discovery-search-search-both-words-required": {
71
+ roles: ["guest"],
72
+ startPage: "/products",
73
+ steps: [
74
+ "Open /products in a private window.",
75
+ "Type dranzer in the search field, click 'Search', and note the result count.",
76
+ "Clear the field, type original, click 'Search', and note the count.",
77
+ "Clear the field, type 'original dranzer', click 'Search', and note the count.",
78
+ "Read the titles returned by the two-word query.",
79
+ ],
80
+ inputs: { word1: "dranzer", word2: "original", bothWords: "original dranzer" },
81
+ expectedBehaviour: "Multiple words narrow rather than widen — every word must match. An OR search returns MORE results for two words than for one, which is the opposite of what a user typing a second word is asking for.",
82
+ expectedUiState: "The two-word count is less than or equal to the smaller of the two single-word counts. Every returned title matches both words. A two-word count higher than either single-word count is the OR failure.",
83
+ endResult: "Read-only; nothing persists beyond the URL.",
84
+ },
85
+ "checklist-content-discovery-search-search-plus-category-filter": {
86
+ roles: ["guest"],
87
+ startPage: "/products",
88
+ steps: [
89
+ "Open /products in a private window.",
90
+ "Type beyblade in the search field and click 'Search', then note the count.",
91
+ "Open the filters, tick the Beyblade Burst category, and apply.",
92
+ "Read the count, the URL and the card titles.",
93
+ "Check the search field still holds the typed term.",
94
+ ],
95
+ inputs: { query: "beyblade", category: "Beyblade Burst" },
96
+ expectedBehaviour: "A search term and a facet apply together as an AND. Applying a filter must not clear the query — resetting the page to filter-only is a silent widening the user did not ask for.",
97
+ expectedUiState: "The URL carries both the search term and the category. The count is lower than the search-only count. Every card is a Burst item matching the term. The search field still shows 'beyblade'.",
98
+ endResult: "Read-only; nothing persists beyond the URL.",
99
+ },
100
+ "checklist-content-discovery-search-search-keeps-sort": {
101
+ roles: ["guest"],
102
+ startPage: "/products",
103
+ steps: [
104
+ "Open /products in a private window.",
105
+ "Type beyblade in the search field and click 'Search'.",
106
+ "Read the card order and note the sort dropdown's selection.",
107
+ "Change the sort to price, low to high.",
108
+ "Read the card order, the URL and the search field.",
109
+ "Reload the page and read all three again.",
110
+ ],
111
+ inputs: { query: "beyblade", sort: "Price: low to high" },
112
+ expectedBehaviour: "Changing the sort re-orders the current results and keeps the term. Both live in the URL, so a reload reproduces the same page — and the sort field must be one the query can actually sort on, since an unsortable field is dropped and the dropdown silently reorders nothing.",
113
+ expectedUiState: "Prices ascend down the page and the search field still holds 'beyblade'. The URL carries both. After the reload the order and the term are unchanged. A dropdown selection that changes no order at all is the dropped-sort failure.",
114
+ endResult: "Read-only; nothing persists beyond the URL.",
115
+ },
116
+ "checklist-content-discovery-search-search-keeps-facets": {
117
+ roles: ["guest"],
118
+ startPage: "/products",
119
+ steps: [
120
+ "Open /products in a private window.",
121
+ "Type beyblade in the search field and click 'Search', then note the count.",
122
+ "Open the filters, set the price range minimum to 500 and maximum to 1500, and apply.",
123
+ "Read the count and check every card's price is inside the range.",
124
+ "Open the filters again, tick a tag, and apply. Read the count.",
125
+ "Click the 'Sold & Ended' availability tab and read the count.",
126
+ ],
127
+ inputs: { query: "beyblade", priceMin: 500, priceMax: 1500 },
128
+ expectedBehaviour: "Price, tag and availability all narrow alongside the term. A facet that renders and counts toward the badge while changing nothing is inert — that happens when it emits a field the query allowlist does not carry, and nothing raises.",
129
+ expectedUiState: "Each facet visibly reduces the count and every card respects it. The availability tab changes which rows appear. A facet that leaves the count identical while the filter badge increments is the failure.",
130
+ expectedData: { inertFacetCount: 0 },
131
+ endResult: "Read-only; nothing persists beyond the URL.",
132
+ },
133
+ "checklist-content-discovery-search-search-case-and-accents": {
134
+ roles: ["guest"],
135
+ startPage: "/products",
136
+ steps: [
137
+ "Open /products in a private window.",
138
+ "Type dranzer in the search field, click 'Search', and note the result count.",
139
+ "Clear the field, type DRANZER, click 'Search', and note the count.",
140
+ "Clear the field, type Dranzer, click 'Search', and note the count.",
141
+ "Compare all three counts.",
142
+ ],
143
+ inputs: { lower: "dranzer", upper: "DRANZER", mixed: "Dranzer" },
144
+ expectedBehaviour: "The query is normalised before matching, so case makes no difference. The search field is a normalised token array precisely so a buyer's capitalisation is not a search term.",
145
+ expectedUiState: "All three queries return the same count and the same titles. A different count for the uppercase form means normalisation is applied when the record is written but not when the query is read.",
146
+ endResult: "Read-only; nothing persists beyond the URL.",
147
+ },
148
+ "checklist-content-discovery-search-search-single-char-narrows": {
149
+ roles: ["guest"],
150
+ startPage: "/products",
151
+ steps: [
152
+ "Open /products in a private window and note the unfiltered result count.",
153
+ "Type d in the search field and click 'Search'.",
154
+ "Read the count and the card titles.",
155
+ "Clear the field, type z, and click 'Search'.",
156
+ "Read the count.",
157
+ ],
158
+ inputs: { query1: "d", query2: "z" },
159
+ expectedBehaviour: "A one-character query is still a query. Ignoring short terms as noise means the box appears to accept input and returns the whole catalogue, which reads as 'nothing matched your filter' being impossible.",
160
+ expectedUiState: "'d' returns fewer rows than the unfiltered count, and every title contains a word starting with d. 'z' returns a different, smaller set. Either query returning the full unfiltered count is the failure.",
161
+ endResult: "Read-only; nothing persists beyond the URL.",
162
+ },
163
+ "checklist-content-discovery-search-search-faqs": {
164
+ roles: ["guest"],
165
+ startPage: "/faqs",
166
+ steps: [
167
+ "Open /faqs in a private window and note how many questions are listed.",
168
+ "Type shipping in the search box.",
169
+ "Read the questions that remain.",
170
+ "Clear the box and type zzzznope.",
171
+ "Read what is shown.",
172
+ "Clear the box and check the full list returns.",
173
+ ],
174
+ inputs: { query: "shipping", nonsenseQuery: "zzzznope" },
175
+ expectedBehaviour: "The FAQ list filters client-side against the loaded questions. This page renders admin-managed FAQs from the database rather than a static translation file, so the search operates on real content.",
176
+ expectedUiState: "'shipping' leaves only shipping-related questions. 'zzzznope' shows a named empty state, not every question. Clearing restores the full list.",
177
+ expectedData: { nonsenseResultCount: 0 },
178
+ endResult: "Read-only; nothing persists.",
179
+ },
180
+ "checklist-content-discovery-search-search-faq-category-page": {
181
+ roles: ["guest"],
182
+ startPage: "/faqs",
183
+ steps: [
184
+ "Open /faqs in a private window and read the category list.",
185
+ "Open the Shipping category page.",
186
+ "Read the questions listed and expand one to read its answer.",
187
+ "Read the address bar.",
188
+ "Open a second category page and read its questions.",
189
+ ],
190
+ expectedBehaviour: "Each category has its own page, keyed on the category's slug, rendering only its questions. Two category pages showing the same questions means the slug is not reaching the query.",
191
+ expectedUiState: "The Shipping page lists shipping questions and an expanded answer renders as formatted text, not as raw HTML shown as visible characters. The second category shows a different set.",
192
+ endResult: "Read-only; nothing persists.",
193
+ },
194
+ "checklist-content-discovery-search-search-scams-listing": {
195
+ roles: ["guest"],
196
+ startPage: "/scams",
197
+ steps: [
198
+ "Open /scams in a private window with no session.",
199
+ "Read the profiles listed and note how many there are.",
200
+ "Read each profile's status.",
201
+ "Open one profile and read its detail.",
202
+ ],
203
+ expectedBehaviour: "The public registry lists verified profiles. Status values shown must be ones the documents actually hold — the canonical field-name constants and the feature's own type file have disagreed before, one of them missing a real status the other had.",
204
+ expectedUiState: "Profiles are listed with their statuses and each opens a real detail page. The list is not empty and is not the full unfiltered set including removed profiles.",
205
+ endResult: "Read-only; nothing persists.",
206
+ },
207
+ "checklist-content-discovery-search-search-scam-partial-and-upi": {
208
+ roles: ["admin"],
209
+ startPage: "/admin/scammers",
210
+ steps: [
211
+ "Sign in as admin@letitrip.in / TempPass123!.",
212
+ "Open /admin/scammers and note the total row count.",
213
+ "Type Vikram in the search box and read the results.",
214
+ "Clear the box and type a UPI id belonging to one of the listed profiles.",
215
+ "Read the results.",
216
+ "Clear the box and type zzzznope, then read the results.",
217
+ ],
218
+ inputs: { partialName: "Vikram", nonsenseQuery: "zzzznope" },
219
+ expectedBehaviour: "The admin search matches a partial name and also matches on identifier fields such as a UPI id, so a report can be found by whatever the reporter had. Both are needed: a name-only search cannot find a profile reported by payment handle alone.",
220
+ expectedUiState: "'Vikram' returns the Vikram Mehta profile. The UPI id returns its own profile. 'zzzznope' returns zero rows rather than the full list.",
221
+ expectedData: { nonsenseResultCount: 0 },
222
+ endResult: "Read-only; nothing persists beyond the URL.",
223
+ },
224
+ "checklist-content-discovery-search-search-store-event-blog-review": {
225
+ roles: ["guest"],
226
+ startPage: "/stores",
227
+ steps: [
228
+ "Open /stores in a private window, search for arena, and read the results.",
229
+ "Open /events, search for beyblade, and read the results.",
230
+ "Open /blog, search for beyblade, and read the results.",
231
+ "Open a product page's reviews section, search for a word from a visible review, and read the results.",
232
+ "Repeat all four searches with zzzznope and read each result count.",
233
+ ],
234
+ inputs: { storeQuery: "arena", contentQuery: "beyblade", nonsenseQuery: "zzzznope" },
235
+ expectedBehaviour: "Every listing surface's search box filters its own collection. Each is a separate wiring — a search that renders on all four and works on three is the normal shape of this defect.",
236
+ expectedUiState: "Each real query returns matching rows. Each nonsense query returns zero on all four surfaces. A surface where the nonsense query returns everything has a search box that decorates rather than filters.",
237
+ expectedData: { surfacesWhereNonsenseReturnsAll: 0 },
238
+ endResult: "Read-only; nothing persists. Name each failing surface in the comment rather than answering for the group.",
239
+ },
240
+ "checklist-content-discovery-search-search-admin-exact-match": {
241
+ roles: ["admin"],
242
+ startPage: "/admin/reviews",
243
+ steps: [
244
+ "Sign in as admin@letitrip.in / TempPass123!.",
245
+ "Open /admin/reviews and read a reviewer's full name from any row.",
246
+ "Read the search box's placeholder or helper text.",
247
+ "Type that full name into the search box and read the results.",
248
+ "Clear the box, type only the first half of the same name, and read the results.",
249
+ "Clear the box and type zzzznope, then read the results.",
250
+ ],
251
+ expectedBehaviour: "Reviewer names are PII-encrypted at rest, so they can only be matched exactly through a blind index — a partial match is not possible, by design rather than by omission. The box must SAY so, because a partial search returning nothing otherwise reads as a broken search.",
252
+ expectedUiState: "The full name returns its rows. The partial name returns none. The box states that it is an exact match, in its placeholder or a note beside it — without that, this behaviour is indistinguishable from a bug.",
253
+ expectedData: { partialMatchCount: 0 },
254
+ endResult: "Read-only; nothing persists beyond the URL.",
255
+ },
256
+ "checklist-content-discovery-search-search-admin-degraded-sort": {
257
+ roles: ["admin"],
258
+ startPage: "/admin/payouts",
259
+ steps: [
260
+ "Sign in as admin@letitrip.in / TempPass123!.",
261
+ "Open /admin/payouts and note the sort dropdown's selection and the row order.",
262
+ "Type a seller name into the search box and submit it.",
263
+ "Read the rows and look for any notice about sorting.",
264
+ "Clear the search and read the row order again.",
265
+ ],
266
+ expectedBehaviour: "Search and sort cannot both be pushed into the query here, so while searching the results come back unsorted and the page says so. An unexplained order change reads as the sort control being broken.",
267
+ expectedUiState: "With a search active a visible notice states that results are not sorted while searching. Clearing the search restores the sorted order. A silently reordered list with no notice is the failure.",
268
+ endResult: "Read-only; nothing persists beyond the URL.",
269
+ },
270
+ "checklist-content-discovery-search-search-admin-team-filter-chip": {
271
+ roles: ["admin"],
272
+ startPage: "/admin/team",
273
+ steps: [
274
+ "Sign in as admin@letitrip.in / TempPass123!.",
275
+ "Open /admin/team and note how many employees are listed.",
276
+ "Click one filter chip and read the resulting rows.",
277
+ "Clear it, click a different chip, and read the rows.",
278
+ "Apply two chips together and read the rows.",
279
+ "Clear everything and check the original list returns.",
280
+ ],
281
+ expectedBehaviour: "Applying a filter chip narrows the list and still returns employees. A filter builder that CONCATENATES its clauses instead of joining them produces one malformed clause that matches nothing, so any chip empties the whole list — and the unit test for this route asserted against the correct behaviour rather than the real one, so it passed for as long as the bug existed.",
282
+ expectedUiState: "Every chip returns at least one employee, and two chips together return a subset rather than nothing. A chip that empties the list entirely is the exact failure.",
283
+ expectedData: { emptyChipCount: 0 },
284
+ endResult: "Read-only; nothing persists beyond the URL.",
285
+ },
286
+ "checklist-content-discovery-search-search-no-empty-toolbar-gap": {
287
+ roles: ["admin"],
288
+ startPage: "/admin/team",
289
+ steps: [
290
+ "Sign in as admin@letitrip.in / TempPass123!.",
291
+ "Open several admin listing pages in turn and look at each toolbar.",
292
+ "Note any toolbar with a visible empty gap where a control would sit.",
293
+ "Resize to 390 pixels wide and look at the same toolbars.",
294
+ ],
295
+ expectedBehaviour: "A listing whose search box was removed reflows its toolbar rather than leaving the space reserved. A collapsed control must collapse its layout too — hiding it by transform leaves its height and width behind.",
296
+ expectedUiState: "No toolbar shows an empty gap at either width. Remaining controls sit adjacent to one another rather than spaced around an invisible element.",
297
+ endResult: "Read-only; nothing persists. Restore the window width afterwards.",
298
+ },
299
+ "checklist-content-discovery-search-search-nonsense-term-returns-nothing": {
300
+ roles: ["guest", "admin"],
301
+ startPage: "/products",
302
+ steps: [
303
+ "Open /products in a private window, type zzzznope, click 'Search', and read the count.",
304
+ "Open /stores, search zzzznope, and read the count.",
305
+ "Open /blog, search zzzznope, and read the count.",
306
+ "Open /faqs, search zzzznope, and read what is shown.",
307
+ "Sign in as admin@letitrip.in / TempPass123! and repeat on /admin/products, /admin/orders and /admin/users.",
308
+ "Write down every surface that returned more than zero.",
309
+ ],
310
+ inputs: { nonsenseQuery: "zzzznope" },
311
+ expectedBehaviour: "This is the control for every other search case in the checklist. A search box that has stopped filtering returns plausible rows for any real term and is indistinguishable from a working one — only a term that cannot match anything tells them apart.",
312
+ expectedUiState: "Every surface returns zero results and a named empty state. Any surface returning its full unfiltered list has a search box that is not filtering, whatever it does for real terms.",
313
+ expectedData: { surfacesReturningRows: 0 },
314
+ endResult: "Read-only; nothing persists. List every failing surface — this one case invalidates the search cases on any surface it names.",
315
+ },
316
+ "checklist-content-discovery-search-search-finds-older-records": {
317
+ roles: ["admin"],
318
+ startPage: "/admin/products",
319
+ steps: [
320
+ "Sign in as admin@letitrip.in / TempPass123!.",
321
+ "Open /admin/products and sort by oldest first.",
322
+ "Read the title of the oldest listing.",
323
+ "Search for a distinctive word from that title.",
324
+ "Read whether that listing is returned.",
325
+ "Repeat with the newest listing's title as a comparison.",
326
+ ],
327
+ expectedBehaviour: "Search is backed by a normalised token field written on save. Records created before that field existed have no tokens, so they are unfindable — the fix is a backfill, and this case is what detects whether one is needed.",
328
+ expectedUiState: "Both the oldest and the newest listing are returned by a word from their own titles. The newest being findable while the oldest is not is the signature of missing tokens on older rows, not of a broken search.",
329
+ expectedData: { oldRecordFound: true },
330
+ endResult: "Read-only; nothing persists. Testing only recent records would pass this case while the backfill gap remains.",
331
+ },
332
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;
@@ -0,0 +1,53 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the cta-layout/checkout-bottom-bar page.
3
+ * WHAT: 2 case(s), keyed by full checklist id.
4
+ *
5
+ * Written by hand, case by case, against the label each one states. There is no
6
+ * generator: the authoring scripts were deleted once it was clear they were
7
+ * scaffolding around work that is simply writing.
8
+ *
9
+ * Both cases are layout checks with an explicit BEFORE in their own description,
10
+ * so the procedure names the pixel symptom rather than asking whether the bar
11
+ * "looks right". 320px is the narrowest viewport worth supporting and is where
12
+ * every squeeze shows up first.
13
+ *
14
+ * @tag domain:tester
15
+ * @tag layer:seed
16
+ * @tag pattern:none
17
+ * @tag access:server-only
18
+ * @tag consumers:seed-data/authored/index.ts
19
+ * @tag sideEffects:none
20
+ */
21
+ export const authored = {
22
+ "checklist-cta-layout-checkout-bottom-bar-back-not-squeezed": {
23
+ roles: ["buyer"],
24
+ startPage: "/checkout",
25
+ steps: [
26
+ "Resize the browser window to 320 pixels wide.",
27
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
28
+ "Open /products/product-tester-standard-1 and click 'Add to Cart'.",
29
+ "Open /checkout, select the first saved address, and continue to the Extras step.",
30
+ "Read the two buttons in the bottom action bar and compare their widths.",
31
+ ],
32
+ inputs: { viewportWidth: 320 },
33
+ expectedBehaviour: "Each button is sized by its own label rather than by a fixed share of the row, so the shorter label takes less space and the longer one takes more. A fixed split gives a two-letter button the same width as an eight-word one.",
34
+ expectedUiState: "'Back' reads in full — not clipped to 'Ba' inside a roughly 44px box. 'Continue to payment' also reads in full and is visibly the wider of the two. Neither shows an ellipsis or a cut-off word.",
35
+ endResult: "Layout-only; nothing persists. Restore the window width afterwards so later cases are not run at 320px by accident.",
36
+ },
37
+ "checklist-cta-layout-checkout-bottom-bar-no-truncation-anywhere": {
38
+ roles: ["buyer"],
39
+ startPage: "/checkout",
40
+ steps: [
41
+ "Resize the browser window to 320 pixels wide.",
42
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
43
+ "Open /products/product-tester-standard-1 and click 'Add to Cart'.",
44
+ "Open /checkout and continue through to the payment step.",
45
+ "Read the primary button's label in full.",
46
+ "Select each payment method in turn and read the primary label after each.",
47
+ ],
48
+ inputs: { viewportWidth: 320 },
49
+ expectedBehaviour: "A label too long for one line makes its button taller rather than truncating. Height is cheap in a bottom bar; a clipped verb is not, because the buyer cannot tell what the button will do.",
50
+ expectedUiState: "'Pay Online (Razorpay)' is shown complete, wrapping onto two lines if it needs to. An ellipsis anywhere in the bar is a failure, on any payment method.",
51
+ endResult: "Layout-only; nothing persists. Restore the window width afterwards.",
52
+ },
53
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;
@@ -0,0 +1,52 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the cta-layout/dialog-footers page.
3
+ * WHAT: 2 case(s), keyed by full checklist id.
4
+ *
5
+ * Written by hand, case by case, against the label each one states. There is no
6
+ * generator: the authoring scripts were deleted once it was clear they were
7
+ * scaffolding around work that is simply writing.
8
+ *
9
+ * These two pull in OPPOSITE directions on purpose — a dialog footer stays
10
+ * compact while a mobile bar stretches — and that is exactly why they are one
11
+ * page. A single rule applied to both is what makes one of them wrong.
12
+ *
13
+ * @tag domain:tester
14
+ * @tag layer:seed
15
+ * @tag pattern:none
16
+ * @tag access:server-only
17
+ * @tag consumers:seed-data/authored/index.ts
18
+ * @tag sideEffects:none
19
+ */
20
+ export const authored = {
21
+ "checklist-cta-layout-dialog-footers-modal-footer-stays-compact-on-desktop": {
22
+ roles: ["admin"],
23
+ startPage: "/admin/products",
24
+ steps: [
25
+ "Resize the browser window to 1280 pixels wide.",
26
+ "Sign in as admin@letitrip.in / TempPass123!.",
27
+ "Open /admin/products.",
28
+ "Open the row action menu on the first product and choose a destructive action such as Delete.",
29
+ "Read the dialog's footer buttons and where they sit horizontally.",
30
+ "Dismiss the dialog with Cancel rather than confirming.",
31
+ ],
32
+ inputs: { viewportWidth: 1280 },
33
+ expectedBehaviour: "A dialog footer packs its buttons to the right at content width. A destructive dialog also has to HAVE a confirmation to open at all — every danger-kind action carries its confirmation copy in the action registry, and one without it executes immediately with no warning.",
34
+ expectedUiState: "Cancel and the destructive button are each about as wide as their own label and sit together at the right edge of the dialog. They do not stretch edge to edge like banners. The dialog names what is about to be deleted rather than asking a generic 'Are you sure?'.",
35
+ endResult: "Cancel closes the dialog and nothing is deleted. The product is still in the list after a reload — dismissing must not be a silent confirm.",
36
+ },
37
+ "checklist-cta-layout-dialog-footers-filter-drawer-footer-stacks-when-narrow": {
38
+ roles: ["guest"],
39
+ startPage: "/products",
40
+ steps: [
41
+ "Resize the browser window to 320 pixels wide.",
42
+ "Open /products.",
43
+ "Click 'Filters' to open the drawer.",
44
+ "Scroll to the drawer's footer.",
45
+ "Read both buttons and note whether they sit side by side or one per line.",
46
+ ],
47
+ inputs: { viewportWidth: 320 },
48
+ expectedBehaviour: "Where a dialog footer stays compact, a drawer footer prefers legibility: if two buttons cannot both read at the available width they stack one per line rather than shrinking below their labels.",
49
+ expectedUiState: "'Reset all' and 'Apply' are both fully readable. If they cannot fit side by side at 320px they are stacked, one per line. Neither is crushed below its label and neither is truncated.",
50
+ endResult: "Layout-only; closing the drawer without applying changes nothing. Restore the window width afterwards.",
51
+ },
52
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;
@@ -0,0 +1,35 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the cta-layout/editor-action-bar page.
3
+ * WHAT: 1 case, keyed by full checklist id.
4
+ *
5
+ * Written by hand, case by case, against the label each one states. There is no
6
+ * generator: the authoring scripts were deleted once it was clear they were
7
+ * scaffolding around work that is simply writing.
8
+ *
9
+ * @tag domain:tester
10
+ * @tag layer:seed
11
+ * @tag pattern:none
12
+ * @tag access:server-only
13
+ * @tag consumers:seed-data/authored/index.ts
14
+ * @tag sideEffects:none
15
+ */
16
+ export const authored = {
17
+ "checklist-cta-layout-editor-action-bar-four-buttons-wrap-not-overflow": {
18
+ roles: ["seller"],
19
+ startPage: "/store/products/new",
20
+ steps: [
21
+ "Resize the browser window to 375 pixels wide.",
22
+ "Sign in as tyson@beybladearena.in / TempPass123!.",
23
+ "Open /store/products/new.",
24
+ "Type 'QA Product editor-action-bar' in the title field so the form becomes dirty and Discard appears.",
25
+ "Read the action bar and count how many buttons are visible.",
26
+ "Try to scroll the page sideways.",
27
+ "Read the right edge of the bar for any button that is partly off screen.",
28
+ ],
29
+ inputs: { viewportWidth: 375, title: "QA Product editor-action-bar" },
30
+ expectedBehaviour: "Four actions that cannot fit one row wrap onto a second. They used to be non-shrinking children of a non-wrapping row, which does not overflow gracefully — it simply runs off the right edge, taking the last button with it.",
31
+ expectedUiState: "All four of Discard, Preview, Save draft and Publish are fully visible, wrapping onto a second line as needed. Nothing is cut off at the right edge, and the page does not scroll sideways at all.",
32
+ expectedData: { visibleButtonCount: 4 },
33
+ endResult: "Leave the editor without saving, so no draft product is created. Restore the window width afterwards.",
34
+ },
35
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;
@@ -0,0 +1,141 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the cta-layout/navbar-ctas checklist page.
3
+ * WHAT: 8 case(s), keyed by full checklist id.
4
+ *
5
+ * The header is mounted once in a persistent shell and does NOT re-mount on
6
+ * client-side navigation. Everything below follows from that: a badge cannot
7
+ * correct itself by re-mounting, a signed-in state cannot appear by reloading,
8
+ * and an active-section marker has to be derived from the current path rather
9
+ * than set once on first render.
10
+ *
11
+ * @tag domain:tester
12
+ * @tag layer:seed
13
+ * @tag pattern:none
14
+ * @tag access:server-only
15
+ * @tag consumers:seed-data/authored/index.ts
16
+ * @tag sideEffects:none
17
+ */
18
+ export const authored = {
19
+ "checklist-cta-layout-navbar-ctas-header-ctas-all-navigate": {
20
+ roles: ["guest"],
21
+ startPage: "/",
22
+ steps: [
23
+ "Open the homepage signed out.",
24
+ "List every clickable control in the header, including the logo and any icon-only ones.",
25
+ "Click each in turn, noting where it lands and returning each time.",
26
+ "Record any that does nothing.",
27
+ "Record any that 404s.",
28
+ "Check the logo returns to the homepage.",
29
+ ],
30
+ expectedBehaviour: "Every header control goes somewhere real. An inert control is the harder half to notice — it looks like a slow page rather than a broken link, so the visitor waits and then clicks it again.",
31
+ expectedUiState: "Every control navigates to a real page and the logo returns home. Any control that does nothing, or 404s, is a finding named by its label or icon.",
32
+ expectedData: { deadHeaderControls: 0 },
33
+ endResult: "Read-only.",
34
+ },
35
+ "checklist-cta-layout-navbar-ctas-header-cart-badge-live": {
36
+ roles: ["buyer"],
37
+ startPage: "/",
38
+ steps: [
39
+ "Sign in as rehan.sheikh@gmail.com / TempPass123! with an empty cart.",
40
+ "Read the header's cart control and its badge.",
41
+ "Add a product from /products and read the badge without reloading.",
42
+ "Add a second and read it again.",
43
+ "Navigate to two other pages and read the badge on each.",
44
+ "Open /cart, remove an item, and read the badge.",
45
+ ],
46
+ expectedBehaviour: "The badge reads the same cart the pages read, so it tracks every change with no reload. The header never re-mounts across navigation, so a badge holding its own count cannot correct itself — it keeps a stale number for the rest of the session.",
47
+ expectedUiState: "The badge follows every add and removal immediately and stays correct across navigation. A count that lags or freezes is the finding.",
48
+ endResult: "Empty the cart afterwards.",
49
+ },
50
+ "checklist-cta-layout-navbar-ctas-header-signed-out-vs-in": {
51
+ roles: ["guest", "buyer"],
52
+ startPage: "/",
53
+ steps: [
54
+ "Open the homepage signed out and read the header's account area.",
55
+ "Check a sign-in affordance is offered.",
56
+ "Sign in as rehan.sheikh@gmail.com / TempPass123! from that control.",
57
+ "Read the header immediately after signing in, WITHOUT reloading.",
58
+ "Check it now shows an account menu.",
59
+ "Sign out and read the header again without reloading.",
60
+ ],
61
+ expectedBehaviour: "The header switches with the session and without a reload. The session resolves asynchronously on a hard load, so the header may briefly not know who the visitor is — but once it does, the change has to reach the persistent header rather than waiting for the next full page load.",
62
+ expectedUiState: "Signed out shows sign-in; signed in shows an account menu; each switch happens without a reload. A header still offering sign-in after a successful sign-in is the finding.",
63
+ endResult: "Signed out.",
64
+ },
65
+ "checklist-cta-layout-navbar-ctas-account-menu-links-resolve": {
66
+ roles: ["buyer", "seller", "admin"],
67
+ startPage: "/",
68
+ steps: [
69
+ "Sign in as rehan.sheikh@gmail.com / TempPass123! and open the account menu.",
70
+ "Click every item in it, noting where each lands and returning each time.",
71
+ "Record any 404 or unauthorised page.",
72
+ "Repeat signed in as tyson@beybladearena.in / TempPass123!.",
73
+ "Repeat signed in as admin@letitrip.in / TempPass123!.",
74
+ ],
75
+ expectedBehaviour: "Every account-menu item lands on a page that role can actually open. A menu entry pointing at a route with no page behind it is a dead link, and one pointing at a page the role cannot access bounces them to an unauthorised screen from their own menu.",
76
+ expectedUiState: "Every item resolves for its role. A 404 or an unauthorised redirect is a finding, named with the role and the item.",
77
+ expectedData: { deadMenuLinks: 0 },
78
+ endResult: "Read-only.",
79
+ },
80
+ "checklist-cta-layout-navbar-ctas-role-specific-nav-entries": {
81
+ roles: ["buyer", "seller", "admin"],
82
+ startPage: "/",
83
+ steps: [
84
+ "Sign in as rehan.sheikh@gmail.com / TempPass123! and write down every navigation entry offered.",
85
+ "Check no store or admin entry is among them.",
86
+ "Sign in as tyson@beybladearena.in / TempPass123! and write down the entries.",
87
+ "Check a store entry is present and no admin entry is.",
88
+ "Sign in as admin@letitrip.in / TempPass123! and check an admin entry is present.",
89
+ "Compare the three lists.",
90
+ ],
91
+ expectedBehaviour: "Navigation reflects the role. A role check written inline against a role string rather than through the shared predicate drifts from every other check in the product — and the visible symptom is a buyer offered a dashboard that will refuse them.",
92
+ expectedUiState: "The buyer sees neither store nor admin entries, the seller sees store and not admin, the admin sees admin. Any entry offered to a role that cannot use it is the finding.",
93
+ endResult: "Read-only.",
94
+ },
95
+ "checklist-cta-layout-navbar-ctas-mobile-nav-opens-and-closes": {
96
+ roles: ["guest"],
97
+ startPage: "/",
98
+ steps: [
99
+ "Resize the browser to 390 pixels wide and open the homepage.",
100
+ "Open the mobile navigation.",
101
+ "Check it covers the page and its items are readable.",
102
+ "Close it with its own control and check it closes.",
103
+ "Open it again and follow a link.",
104
+ "Check the navigation closed itself on the new page rather than staying over it.",
105
+ ],
106
+ inputs: { mobileWidth: 390 },
107
+ expectedBehaviour: "The mobile navigation closes on its own control AND after a link is followed. It lives in a shell that does not re-mount on navigation, so nothing closes it automatically — a menu left open sits over the page the visitor just asked for.",
108
+ expectedUiState: "It opens, closes on its control, and is closed on the destination page after a link. A menu still covering the new page is the finding.",
109
+ endResult: "Restore the window width.",
110
+ },
111
+ "checklist-cta-layout-navbar-ctas-nav-active-state-correct": {
112
+ roles: ["guest"],
113
+ startPage: "/",
114
+ steps: [
115
+ "Open the homepage and read which navigation entry is marked as current.",
116
+ "Navigate to /products and read which is marked.",
117
+ "Navigate to a product detail page and read which is marked.",
118
+ "Navigate to /events and read which is marked.",
119
+ "Use the browser's back button twice and read the marker each time.",
120
+ ],
121
+ expectedBehaviour: "The marker is derived from the current path, so it follows client-side navigation and the back button. Set once on first render, it would freeze on whichever section the visitor happened to land on first and stay there for the whole session.",
122
+ expectedUiState: "The correct entry is marked on every page including the detail page, and it follows the back button. A marker stuck on one section is the finding.",
123
+ endResult: "Read-only.",
124
+ },
125
+ "checklist-cta-layout-navbar-ctas-announcement-bar-message-renders": {
126
+ roles: ["admin", "guest"],
127
+ startPage: "/admin/site",
128
+ steps: [
129
+ "Sign in as admin@letitrip.in / TempPass123! and open Site Settings.",
130
+ "Find the announcement bar section and set its message to 'QA announcement probe — checklist case.'",
131
+ "Save.",
132
+ "Open the public homepage as a signed-out visitor.",
133
+ "Read whether the announcement appears and whether the text matches.",
134
+ "Return to Site Settings, clear the announcement, and check it leaves the homepage.",
135
+ ],
136
+ inputs: { message: "QA announcement probe — checklist case." },
137
+ expectedBehaviour: "An announcement an admin saves appears. The editor once wrote the copy under a key no renderer has ever read, so every announcement saved successfully and none of them appeared — a save that reports success while writing to a field with no reader is invisible from both ends.",
138
+ expectedUiState: "The exact text appears in the announcement bar on the public homepage, and clearing it removes the bar. A successful save with nothing on the homepage is the finding.",
139
+ endResult: "The announcement is cleared.",
140
+ },
141
+ };