@mohasinac/appkit 4.34.0 → 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 (248) hide show
  1. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +32 -2
  2. package/dist/_internal/server/features/seo/sitemap.js +2 -2
  3. package/dist/_internal/server/functions/scheduled.d.ts +1 -2
  4. package/dist/_internal/server/functions/scheduled.js +8 -9
  5. package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +15 -0
  6. package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +15 -6
  7. package/dist/_internal/server/jobs/handlers/index.d.ts +0 -1
  8. package/dist/_internal/server/jobs/handlers/index.js +0 -1
  9. package/dist/features/auth/schemas/firestore.d.ts +1 -0
  10. package/dist/features/tester/components/TesterChecklistStepRow.d.ts +9 -1
  11. package/dist/features/tester/components/TesterChecklistStepRow.js +31 -2
  12. package/dist/features/tester/components/TesterHubView.js +8 -0
  13. package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +16 -1
  14. package/dist/features/tester/repository/tester-checklist-item.repository.js +32 -6
  15. package/dist/features/tester/schemas/firestore.d.ts +109 -0
  16. package/dist/features/tester/schemas/firestore.js +14 -0
  17. package/dist/features/tester/seed-data/_money-flows.d.ts +23 -0
  18. package/dist/features/tester/seed-data/_money-flows.js +430 -0
  19. package/dist/features/tester/seed-data/authored/_types.d.ts +33 -0
  20. package/dist/features/tester/seed-data/authored/_types.js +35 -0
  21. package/dist/features/tester/seed-data/authored/account-auth__profile-settings.d.ts +2 -0
  22. package/dist/features/tester/seed-data/authored/account-auth__profile-settings.js +207 -0
  23. package/dist/features/tester/seed-data/authored/account-auth__signup-login.d.ts +2 -0
  24. package/dist/features/tester/seed-data/authored/account-auth__signup-login.js +298 -0
  25. package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.d.ts +2 -0
  26. package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.js +33 -0
  27. package/dist/features/tester/seed-data/authored/account-auth__testing-program.d.ts +2 -0
  28. package/dist/features/tester/seed-data/authored/account-auth__testing-program.js +138 -0
  29. package/dist/features/tester/seed-data/authored/addresses__address-filters.d.ts +2 -0
  30. package/dist/features/tester/seed-data/authored/addresses__address-filters.js +36 -0
  31. package/dist/features/tester/seed-data/authored/addresses__postal-lookup.d.ts +2 -0
  32. package/dist/features/tester/seed-data/authored/addresses__postal-lookup.js +75 -0
  33. package/dist/features/tester/seed-data/authored/addresses__postal-validation.d.ts +2 -0
  34. package/dist/features/tester/seed-data/authored/addresses__postal-validation.js +72 -0
  35. package/dist/features/tester/seed-data/authored/addresses__state-picker.d.ts +2 -0
  36. package/dist/features/tester/seed-data/authored/addresses__state-picker.js +54 -0
  37. package/dist/features/tester/seed-data/authored/addresses__unban-request.d.ts +2 -0
  38. package/dist/features/tester/seed-data/authored/addresses__unban-request.js +39 -0
  39. package/dist/features/tester/seed-data/authored/admin__bans-and-trust.d.ts +2 -0
  40. package/dist/features/tester/seed-data/authored/admin__bans-and-trust.js +226 -0
  41. package/dist/features/tester/seed-data/authored/admin__blog-faqs.d.ts +2 -0
  42. package/dist/features/tester/seed-data/authored/admin__blog-faqs.js +82 -0
  43. package/dist/features/tester/seed-data/authored/admin__bulk-actions.d.ts +2 -0
  44. package/dist/features/tester/seed-data/authored/admin__bulk-actions.js +177 -0
  45. package/dist/features/tester/seed-data/authored/admin__bundles.d.ts +2 -0
  46. package/dist/features/tester/seed-data/authored/admin__bundles.js +97 -0
  47. package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.d.ts +2 -0
  48. package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.js +232 -0
  49. package/dist/features/tester/seed-data/authored/admin__catalog-listings.d.ts +2 -0
  50. package/dist/features/tester/seed-data/authored/admin__catalog-listings.js +306 -0
  51. package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.d.ts +2 -0
  52. package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.js +158 -0
  53. package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.d.ts +2 -0
  54. package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.js +78 -0
  55. package/dist/features/tester/seed-data/authored/admin__content-deletes.d.ts +2 -0
  56. package/dist/features/tester/seed-data/authored/admin__content-deletes.js +261 -0
  57. package/dist/features/tester/seed-data/authored/admin__content-marketing.d.ts +2 -0
  58. package/dist/features/tester/seed-data/authored/admin__content-marketing.js +151 -0
  59. package/dist/features/tester/seed-data/authored/admin__coupons.d.ts +2 -0
  60. package/dist/features/tester/seed-data/authored/admin__coupons.js +214 -0
  61. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.d.ts +2 -0
  62. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +160 -0
  63. package/dist/features/tester/seed-data/authored/admin__media-watermark.d.ts +2 -0
  64. package/dist/features/tester/seed-data/authored/admin__media-watermark.js +104 -0
  65. package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.d.ts +2 -0
  66. package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.js +350 -0
  67. package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.d.ts +2 -0
  68. package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.js +105 -0
  69. package/dist/features/tester/seed-data/authored/admin__site-system.d.ts +2 -0
  70. package/dist/features/tester/seed-data/authored/admin__site-system.js +590 -0
  71. package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.d.ts +2 -0
  72. package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.js +235 -0
  73. package/dist/features/tester/seed-data/authored/admin__users-trust.d.ts +2 -0
  74. package/dist/features/tester/seed-data/authored/admin__users-trust.js +569 -0
  75. package/dist/features/tester/seed-data/authored/buying__bidding.d.ts +2 -0
  76. package/dist/features/tester/seed-data/authored/buying__bidding.js +417 -0
  77. package/dist/features/tester/seed-data/authored/buying__browsing-search.d.ts +2 -0
  78. package/dist/features/tester/seed-data/authored/buying__browsing-search.js +653 -0
  79. package/dist/features/tester/seed-data/authored/buying__buying-checkout.d.ts +2 -0
  80. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +533 -0
  81. package/dist/features/tester/seed-data/authored/buying__buying-coupons.d.ts +2 -0
  82. package/dist/features/tester/seed-data/authored/buying__buying-coupons.js +379 -0
  83. package/dist/features/tester/seed-data/authored/buying__cart.d.ts +2 -0
  84. package/dist/features/tester/seed-data/authored/buying__cart.js +1171 -0
  85. package/dist/features/tester/seed-data/authored/buying__image-tile-layout.d.ts +2 -0
  86. package/dist/features/tester/seed-data/authored/buying__image-tile-layout.js +140 -0
  87. package/dist/features/tester/seed-data/authored/buying__my-orders.d.ts +2 -0
  88. package/dist/features/tester/seed-data/authored/buying__my-orders.js +257 -0
  89. package/dist/features/tester/seed-data/authored/buying__offers.d.ts +2 -0
  90. package/dist/features/tester/seed-data/authored/buying__offers.js +1111 -0
  91. package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.d.ts +2 -0
  92. package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.js +252 -0
  93. package/dist/features/tester/seed-data/authored/buying__product-detail.d.ts +2 -0
  94. package/dist/features/tester/seed-data/authored/buying__product-detail.js +387 -0
  95. package/dist/features/tester/seed-data/authored/buying__return-request.d.ts +2 -0
  96. package/dist/features/tester/seed-data/authored/buying__return-request.js +152 -0
  97. package/dist/features/tester/seed-data/authored/buying__reviews-pagination.d.ts +2 -0
  98. package/dist/features/tester/seed-data/authored/buying__reviews-pagination.js +242 -0
  99. package/dist/features/tester/seed-data/authored/buying__reviews.d.ts +2 -0
  100. package/dist/features/tester/seed-data/authored/buying__reviews.js +113 -0
  101. package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.d.ts +2 -0
  102. package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.js +283 -0
  103. package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.d.ts +2 -0
  104. package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.js +167 -0
  105. package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.d.ts +2 -0
  106. package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.js +90 -0
  107. package/dist/features/tester/seed-data/authored/buying__wishlist-history.d.ts +2 -0
  108. package/dist/features/tester/seed-data/authored/buying__wishlist-history.js +344 -0
  109. package/dist/features/tester/seed-data/authored/community-support__public-profile.d.ts +2 -0
  110. package/dist/features/tester/seed-data/authored/community-support__public-profile.js +53 -0
  111. package/dist/features/tester/seed-data/authored/community-support__support-tickets.d.ts +2 -0
  112. package/dist/features/tester/seed-data/authored/community-support__support-tickets.js +76 -0
  113. package/dist/features/tester/seed-data/authored/content-discovery__blog.d.ts +2 -0
  114. package/dist/features/tester/seed-data/authored/content-discovery__blog.js +93 -0
  115. package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.d.ts +2 -0
  116. package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.js +149 -0
  117. package/dist/features/tester/seed-data/authored/content-discovery__coupons.d.ts +2 -0
  118. package/dist/features/tester/seed-data/authored/content-discovery__coupons.js +121 -0
  119. package/dist/features/tester/seed-data/authored/content-discovery__event-participation.d.ts +2 -0
  120. package/dist/features/tester/seed-data/authored/content-discovery__event-participation.js +207 -0
  121. package/dist/features/tester/seed-data/authored/content-discovery__events.d.ts +2 -0
  122. package/dist/features/tester/seed-data/authored/content-discovery__events.js +318 -0
  123. package/dist/features/tester/seed-data/authored/content-discovery__faq-help.d.ts +2 -0
  124. package/dist/features/tester/seed-data/authored/content-discovery__faq-help.js +65 -0
  125. package/dist/features/tester/seed-data/authored/content-discovery__notifications.d.ts +2 -0
  126. package/dist/features/tester/seed-data/authored/content-discovery__notifications.js +147 -0
  127. package/dist/features/tester/seed-data/authored/content-discovery__search.d.ts +2 -0
  128. package/dist/features/tester/seed-data/authored/content-discovery__search.js +332 -0
  129. package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.d.ts +2 -0
  130. package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.js +53 -0
  131. package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.d.ts +2 -0
  132. package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.js +52 -0
  133. package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.d.ts +2 -0
  134. package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.js +35 -0
  135. package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.d.ts +2 -0
  136. package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.js +141 -0
  137. package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.d.ts +2 -0
  138. package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.js +35 -0
  139. package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.d.ts +2 -0
  140. package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.js +95 -0
  141. package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.d.ts +2 -0
  142. package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.js +191 -0
  143. package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.d.ts +2 -0
  144. package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.js +158 -0
  145. package/dist/features/tester/seed-data/authored/design-ux__footer-theme.d.ts +2 -0
  146. package/dist/features/tester/seed-data/authored/design-ux__footer-theme.js +106 -0
  147. package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.d.ts +2 -0
  148. package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.js +88 -0
  149. package/dist/features/tester/seed-data/authored/design-ux__general-design.d.ts +2 -0
  150. package/dist/features/tester/seed-data/authored/design-ux__general-design.js +204 -0
  151. package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.d.ts +2 -0
  152. package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.js +301 -0
  153. package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.d.ts +2 -0
  154. package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.js +407 -0
  155. package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.d.ts +2 -0
  156. package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.js +214 -0
  157. package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.d.ts +2 -0
  158. package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.js +275 -0
  159. package/dist/features/tester/seed-data/authored/index.d.ts +2 -0
  160. package/dist/features/tester/seed-data/authored/index.js +237 -0
  161. package/dist/features/tester/seed-data/authored/page-wiring__data-loss.d.ts +2 -0
  162. package/dist/features/tester/seed-data/authored/page-wiring__data-loss.js +102 -0
  163. package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.d.ts +2 -0
  164. package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.js +50 -0
  165. package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.d.ts +2 -0
  166. package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.js +66 -0
  167. package/dist/features/tester/seed-data/authored/page-wiring__reachability.d.ts +2 -0
  168. package/dist/features/tester/seed-data/authored/page-wiring__reachability.js +115 -0
  169. package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.d.ts +2 -0
  170. package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.js +136 -0
  171. package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.d.ts +2 -0
  172. package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.js +69 -0
  173. package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.d.ts +2 -0
  174. package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.js +263 -0
  175. package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.d.ts +2 -0
  176. package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.js +102 -0
  177. package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.d.ts +2 -0
  178. package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.js +234 -0
  179. package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.d.ts +2 -0
  180. package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.js +126 -0
  181. package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.d.ts +2 -0
  182. package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.js +255 -0
  183. package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.d.ts +2 -0
  184. package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.js +59 -0
  185. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +2 -0
  186. package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +88 -0
  187. package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.d.ts +2 -0
  188. package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.js +51 -0
  189. package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.d.ts +2 -0
  190. package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.js +35 -0
  191. package/dist/features/tester/seed-data/authored/selling__become-seller.d.ts +2 -0
  192. package/dist/features/tester/seed-data/authored/selling__become-seller.js +94 -0
  193. package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.d.ts +2 -0
  194. package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.js +107 -0
  195. package/dist/features/tester/seed-data/authored/selling__listing-a-product.d.ts +2 -0
  196. package/dist/features/tester/seed-data/authored/selling__listing-a-product.js +285 -0
  197. package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.d.ts +2 -0
  198. package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.js +326 -0
  199. package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.d.ts +2 -0
  200. package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.js +136 -0
  201. package/dist/features/tester/seed-data/authored/selling__media-limits.d.ts +2 -0
  202. package/dist/features/tester/seed-data/authored/selling__media-limits.js +128 -0
  203. package/dist/features/tester/seed-data/authored/selling__sectionised-forms.d.ts +2 -0
  204. package/dist/features/tester/seed-data/authored/selling__sectionised-forms.js +167 -0
  205. package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.d.ts +2 -0
  206. package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.js +117 -0
  207. package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.d.ts +2 -0
  208. package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.js +88 -0
  209. package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.d.ts +2 -0
  210. package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.js +151 -0
  211. package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.d.ts +2 -0
  212. package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.js +105 -0
  213. package/dist/features/tester/seed-data/authored/selling__seller-guide.d.ts +2 -0
  214. package/dist/features/tester/seed-data/authored/selling__seller-guide.js +33 -0
  215. package/dist/features/tester/seed-data/authored/selling__seller-listing-types.d.ts +2 -0
  216. package/dist/features/tester/seed-data/authored/selling__seller-listing-types.js +347 -0
  217. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.d.ts +2 -0
  218. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +166 -0
  219. package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.d.ts +2 -0
  220. package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.js +89 -0
  221. package/dist/features/tester/seed-data/authored/selling__seller-orders.d.ts +2 -0
  222. package/dist/features/tester/seed-data/authored/selling__seller-orders.js +195 -0
  223. package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.d.ts +2 -0
  224. package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.js +180 -0
  225. package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.d.ts +2 -0
  226. package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.js +164 -0
  227. package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.d.ts +2 -0
  228. package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.js +116 -0
  229. package/dist/features/tester/seed-data/authored/seo__canonical-and-host.d.ts +2 -0
  230. package/dist/features/tester/seed-data/authored/seo__canonical-and-host.js +111 -0
  231. package/dist/features/tester/seed-data/authored/seo__og-images.d.ts +2 -0
  232. package/dist/features/tester/seed-data/authored/seo__og-images.js +91 -0
  233. package/dist/features/tester/seed-data/authored/seo__page-metadata.d.ts +2 -0
  234. package/dist/features/tester/seed-data/authored/seo__page-metadata.js +122 -0
  235. package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.d.ts +2 -0
  236. package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.js +105 -0
  237. package/dist/features/tester/seed-data/events-tester-seed-data.js +77 -5
  238. package/dist/features/tester/seed-data/offers-tester-seed-data.js +23 -9
  239. package/dist/features/tester/seed-data/products-tester-seed-data.js +65 -49
  240. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +744 -1
  241. package/dist/features/tester/seed-data/tester-window.d.ts +25 -0
  242. package/dist/features/tester/seed-data/tester-window.js +66 -0
  243. package/dist/seed/carousel-slides-seed-data.js +1 -1
  244. package/dist/seed/products-standard-seed-data.js +2 -2
  245. package/dist/seed/reviews-seed-data.js +6 -1
  246. package/dist/seed/users-seed-data.js +107 -4
  247. package/package.json +1 -1
  248. package/scripts/seed-cli.mjs +6 -0
@@ -0,0 +1,207 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the account-auth/profile-settings checklist page.
3
+ * WHAT: 9 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
+ * 🛑 ONE CASE HERE CHANGES A PASSWORD. `password-change-reset-link` uses
10
+ * karthik.new@gmail.com and nothing else does, deliberately: `seed-cli` sets
11
+ * `TempPass123!` only when it CREATES an Auth record and never resets an existing
12
+ * one, so a persona whose password this case changed would stay changed through
13
+ * every future re-seed and every later case that signs in as them would fail for a
14
+ * reason that is not a bug. Its last step puts the password back.
15
+ *
16
+ * @tag domain:tester
17
+ * @tag layer:seed
18
+ * @tag pattern:none
19
+ * @tag access:server-only
20
+ * @tag consumers:seed-data/authored/index.ts
21
+ * @tag sideEffects:none
22
+ */
23
+ export const authored = {
24
+ "checklist-account-auth-profile-settings-avatar-upload": {
25
+ roles: ["buyer"],
26
+ startPage: "/user/profile",
27
+ steps: [
28
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
29
+ "Open /user/profile.",
30
+ "Click 'Profile Details' to expand the section.",
31
+ "Click 'Edit Profile'.",
32
+ "Click 'Choose image'.",
33
+ "Select the file public/test-media/sample-image.png (561 bytes, image/png) from the checkout of this repo.",
34
+ "Click 'Save changes'.",
35
+ "Reload the page.",
36
+ "Click 'Profile Details' to expand the section.",
37
+ ],
38
+ inputs: { avatarFile: "public/test-media/sample-image.png", avatarMimeType: "image/png" },
39
+ expectedBehaviour: "The file uploads through the signed-URL flow and is stored as the user's avatar. The stored URL is a /media/… proxy path, never a raw storage-bucket URL — the proxy is what applies the watermark and keeps the bucket private. After reload the avatar renders from that stored image rather than the initial-letter placeholder.",
40
+ expectedUiState: "After reload, the Profile Details section shows the uploaded image where the round initial-letter placeholder ('R' for Rehan) previously was. The image renders — not a broken-image icon and not the grey placeholder glyph.",
41
+ expectedData: { avatarUrlPrefix: "/media/" },
42
+ endResult: "After reload the uploaded avatar is still displayed, and it also appears in the header account menu. The upload survived the reload.",
43
+ },
44
+ "checklist-account-auth-profile-settings-edit-profile": {
45
+ roles: ["buyer"],
46
+ startPage: "/user/profile",
47
+ steps: [
48
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
49
+ "Open /user/profile.",
50
+ "Click 'Profile Details' to expand the section.",
51
+ "Click 'Edit Profile'.",
52
+ "Clear the 'Display name' field and type 'QA Profile account-auth-profile-settings-edit-profile'.",
53
+ "Clear the 'Bio' field and type 'Tester bio update for QA.'.",
54
+ "Click 'Save changes'.",
55
+ "Reload the page.",
56
+ "Click 'Profile Details' to expand the section.",
57
+ ],
58
+ inputs: {
59
+ displayName: "QA Profile account-auth-profile-settings-edit-profile",
60
+ bio: "Tester bio update for QA.",
61
+ },
62
+ expectedBehaviour: "The save succeeds and both fields are written to the user document. The header account menu picks up the new display name too, since it reads the same field.",
63
+ expectedUiState: "After reload, Profile Details shows the display name 'QA Profile account-auth-profile-settings-edit-profile' and the bio 'Tester bio update for QA.'. Neither field has reverted to 'Rehan Sheikh' or to an empty bio.",
64
+ expectedData: {
65
+ displayName: "QA Profile account-auth-profile-settings-edit-profile",
66
+ bio: "Tester bio update for QA.",
67
+ },
68
+ endResult: "After reload the edited display name and bio are still present. A save that 200s and reverts on reload is the failure this case exists to catch.",
69
+ },
70
+ "checklist-account-auth-profile-settings-hand-mode-persists-reload": {
71
+ roles: ["buyer"],
72
+ startPage: "/user/settings",
73
+ steps: [
74
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
75
+ "Open /user/settings.",
76
+ "Click the 'Appearance' tab.",
77
+ "Set the 'Left-hand mode' switch to on.",
78
+ "Reload the page.",
79
+ "Click the 'Appearance' tab.",
80
+ "Sign out.",
81
+ "Sign back in as rehan.sheikh@gmail.com / TempPass123!.",
82
+ "Open /user/settings.",
83
+ "Click the 'Appearance' tab.",
84
+ ],
85
+ inputs: { leftHandMode: true },
86
+ expectedBehaviour: "Left-hand mode is stored on the user's record, not only in browser storage. It therefore survives both a reload and a full sign-out/sign-in cycle, which a localStorage-only preference would not.",
87
+ expectedUiState: "After reload: the 'Left-hand mode' switch is still on, and the sidebar/drawers are still on the left. After sign-out and sign back in: still on. At no point does it silently reset to off.",
88
+ expectedData: { leftHandMode: true },
89
+ endResult: "After a sign-out and sign back in, Left-hand mode is still enabled. Reset it to off afterwards so later cases start from the default layout.",
90
+ },
91
+ "checklist-account-auth-profile-settings-hand-mode-toggle-exists": {
92
+ roles: ["buyer"],
93
+ startPage: "/user/settings",
94
+ steps: [
95
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
96
+ "Open /user/settings.",
97
+ "Click the 'Appearance' tab.",
98
+ "Set the 'Left-hand mode' switch to on.",
99
+ "Open /user/profile.",
100
+ "Scroll to the 'Left-hand mode' toggle below the 'Profile Details' section.",
101
+ "Set the same switch to off.",
102
+ ],
103
+ inputs: { leftHandMode: false },
104
+ expectedBehaviour: "The toggle exists in both places and each writes the same single preference. Switching it takes effect immediately — the drawers and floating buttons move side without a full page load.",
105
+ expectedUiState: "On the /user/settings Appearance tab a 'Left-hand mode' switch sits under the Layout heading. On /user/profile the same switch appears with the description 'Move drawers, sidebars, and floating buttons to the left side of the screen'. Flipping either one moves the sidebar immediately; the browser does not navigate or re-render the whole page.",
106
+ endResult: "The switch is present in both places and the page did not reload when it was flipped. The preference is left off, which is the default.",
107
+ },
108
+ "checklist-account-auth-profile-settings-notification-prefs": {
109
+ roles: ["buyer"],
110
+ startPage: "/user/settings",
111
+ steps: [
112
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
113
+ "Open /user/settings.",
114
+ "Click the 'Notifications' tab.",
115
+ "Set the 'Email' switch to off.",
116
+ "Set the 'Promotions' switch to off.",
117
+ "Click 'Save preferences'.",
118
+ "Reload the page.",
119
+ "Click the 'Notifications' tab.",
120
+ ],
121
+ inputs: { emailNotifications: false, promotions: false },
122
+ expectedBehaviour: "Both changed switches are persisted, and the ones that were not touched keep their prior values. A save that writes the whole preference object from a partly-populated form — resetting untouched switches to their defaults — is the failure to watch for.",
123
+ expectedUiState: "After reload the Notifications tab shows 'Email' off and 'Promotions' off. Every other switch is exactly as it was before the edit, not reset.",
124
+ expectedData: { emailNotifications: false, promotions: false },
125
+ endResult: "After reload the two switches are still off. Turn them back on afterwards so later notification cases are not silently suppressed.",
126
+ },
127
+ "checklist-account-auth-profile-settings-own-public-profile-quick-links": {
128
+ roles: ["buyer"],
129
+ startPage: "/user",
130
+ steps: [
131
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
132
+ "Open /user.",
133
+ "Click the 'View public profile' link in the dashboard header.",
134
+ "Note the URL, then go back to /user.",
135
+ "Click the 'My Public Profile' tile in the quick-links grid.",
136
+ "Note the URL, then go back.",
137
+ "Open /user/profile.",
138
+ "Click 'Profile Details' to expand the section.",
139
+ "Click 'View Public Profile', beside 'Manage Addresses'.",
140
+ "Note the URL.",
141
+ "Click 'Edit Profile', expand 'Visibility', set profile visibility to Private and click 'Save changes'.",
142
+ "Open /profile/user-yugi-muto.",
143
+ ],
144
+ inputs: { profileVisibility: "Private" },
145
+ expectedBehaviour: "All three entry points — dashboard header, quick-links tile, and the /user/profile link next to 'Manage Addresses' — resolve to the SAME public profile URL, /profile/user-yugi-muto. None of them lands on the edit-profile page. With visibility set to Private the page still loads for its owner, even though another signed-in user would get a 404.",
146
+ expectedUiState: "Each of the three clicks puts /profile/user-yugi-muto in the address bar and renders the public profile — a display name, avatar and public tabs — with no 'Display name' input, no 'Save changes' button, and no /user/profile chrome. After switching to Private, /profile/user-yugi-muto still renders for the owner rather than a 'Not found' page.",
147
+ expectedData: { publicProfileUrl: "/profile/user-yugi-muto" },
148
+ endResult: "All three links reach the same page. Set profile visibility back to Public afterwards, since other cases read this profile as another user.",
149
+ },
150
+ "checklist-account-auth-profile-settings-password-change-reset-link": {
151
+ roles: ["buyer"],
152
+ startPage: "/user/settings",
153
+ steps: [
154
+ "Sign in as karthik.new@gmail.com / TempPass123!.",
155
+ "Open /user/settings.",
156
+ "Expand the 'Change Password' section.",
157
+ "Read the section without submitting anything, looking for a 'New password' or 'Confirm password' field.",
158
+ "Click 'Update Password'.",
159
+ "Open the inbox for karthik.new@gmail.com.",
160
+ "Open the password-reset email from LetItRip and click the reset link.",
161
+ "Type QaReset456! as the new password on the reset page and submit it.",
162
+ "Sign out of LetItRip.",
163
+ "Sign in as karthik.new@gmail.com / QaReset456!.",
164
+ "Open /user/settings, expand 'Change Password', click 'Update Password' again, open the new email, follow the link and set the password back to TempPass123!.",
165
+ ],
166
+ inputs: { email: "karthik.new@gmail.com", newPassword: "QaReset456!", restoredPassword: "TempPass123!" },
167
+ expectedBehaviour: "'Update Password' sends a Firebase password-reset email to the account's own address and changes nothing by itself. Identity is proved by reaching that inbox, so a stolen session cookie alone cannot change the password. The new password only becomes active once the emailed link is completed.",
168
+ expectedUiState: "The 'Change Password' section offers no new-password field at all — only a button that sends the link. After clicking it a confirmation names karthik.new@gmail.com. The email arrives; its link opens the reset page; after submitting, signing in with QaReset456! succeeds and lands on the account dashboard, while the old password is refused.",
169
+ expectedData: { passwordFieldsOnSettingsPage: 0 },
170
+ endResult: "The password is back at TempPass123! by the last step. That restore is not optional: the seeder never resets an existing password, so skipping it leaves this account permanently unusable by every other case.",
171
+ },
172
+ "checklist-account-auth-profile-settings-public-profile-toggle": {
173
+ roles: ["buyer"],
174
+ startPage: "/user/profile",
175
+ steps: [
176
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
177
+ "Open /user/profile.",
178
+ "Click 'Profile Details' to expand the section.",
179
+ "Click 'Edit Profile'.",
180
+ "Click 'Visibility' to expand it.",
181
+ "Set profile visibility to Private.",
182
+ "Click 'Save changes'.",
183
+ "Reload the page.",
184
+ "Click 'Profile Details' to expand the section.",
185
+ "Click 'Edit Profile', expand 'Visibility', set profile visibility back to Public and click 'Save changes'.",
186
+ ],
187
+ inputs: { profileVisibility: "Private" },
188
+ expectedBehaviour: "The visibility value is saved without a full page load, and the saved value is what the profile read path uses — not the value the form happened to be showing.",
189
+ expectedUiState: "After reload, the 'Profile visibility' line in Profile Details reads 'Private'. It has not reverted to 'Public', and the page did not navigate away when Save was clicked.",
190
+ expectedData: { profileVisibility: "Private" },
191
+ endResult: "The Private setting survived a reload. Visibility is returned to Public in the final step, because other cases open this profile as a different user.",
192
+ },
193
+ "checklist-account-auth-profile-settings-user-pages-signed-out-redirect": {
194
+ roles: ["guest"],
195
+ startPage: "/user/profile",
196
+ steps: [
197
+ "Open a private/incognito browser window with no active session.",
198
+ "Open /user/profile and watch the page for 5 seconds.",
199
+ "Open /user/orders and watch the page for 5 seconds.",
200
+ "Open /user/bids and watch the page for 5 seconds.",
201
+ ],
202
+ expectedBehaviour: "Each route serves a prerendered static shell carrying no session data, then hydrates, finds no user, and redirects to /auth/login. Because the shell is static it is the SAME bytes for every visitor, so it cannot contain anyone's uid, email, display name, order or store id.",
203
+ expectedUiState: "For each URL: site chrome plus a brief loading state, then the address bar becomes /auth/login. At no point does a real name, email address, order number or store name appear. No spinner is still turning after 5 seconds. Record in the comment whether the flash before the redirect feels acceptable — that tradeoff is what this case is evaluating.",
204
+ expectedData: { redirectTarget: "/auth/login" },
205
+ endResult: "All three navigations end on /auth/login with no account data shown. Any trace of a real account is a serious leak and fails this case immediately, separately from the spinner question.",
206
+ },
207
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;
@@ -0,0 +1,298 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the account-auth/signup-login checklist page.
3
+ * WHAT: 15 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
+ * 🛑 TWO CASES HERE CHANGE A PASSWORD, and each owns a persona nothing else uses —
10
+ * `password-reset` has neha.op@gmail.com, `auth-email-links-single-use` has
11
+ * divya.funko@gmail.com. `seed-cli` sets `TempPass123!` only when it CREATES an
12
+ * Auth record and never resets an existing one, so a changed password outlives
13
+ * every future re-seed. Both cases restore it in their last step. They used to
14
+ * point at vivaan.kapoor@gmail.com, which four other authored pages sign in as.
15
+ *
16
+ * 🛑 THE GOOGLE CASES NEED REAL GOOGLE CREDENTIALS and cannot be seeded — a
17
+ * provider link lives in Firebase Auth, not Firestore. They are NOT flagged
18
+ * `needsReview`: their intent is perfectly clear, and a case that cannot be
19
+ * reached is a `null` verdict at run time, not an authoring doubt. Confusing the
20
+ * two hides the unwritten cases inside the unanswerable ones.
21
+ *
22
+ * @tag domain:tester
23
+ * @tag layer:seed
24
+ * @tag pattern:none
25
+ * @tag access:server-only
26
+ * @tag consumers:seed-data/authored/index.ts
27
+ * @tag sideEffects:none
28
+ */
29
+ export const authored = {
30
+ "checklist-account-auth-signup-login-auth-email-links-single-use": {
31
+ roles: ["guest"],
32
+ startPage: "/auth/forgot-password",
33
+ steps: [
34
+ "Open /auth/forgot-password.",
35
+ "Type divya.funko@gmail.com in the 'Email address' field.",
36
+ "Click 'Send reset link'.",
37
+ "Open the inbox for divya.funko@gmail.com and copy the reset link URL out of the email before opening it.",
38
+ "Open the copied URL, type QaSingleUse789! as the new password, confirm it, and submit.",
39
+ "Open the same copied URL a second time.",
40
+ "Register a fresh account at /auth/register using an inbox you can open, then open its verification link once, and then open that same link a second time.",
41
+ "Open /auth/forgot-password, request a link for divya.funko@gmail.com again, and use it to set the password back to TempPass123!.",
42
+ ],
43
+ inputs: {
44
+ email: "divya.funko@gmail.com",
45
+ newPassword: "QaSingleUse789!",
46
+ restoredPassword: "TempPass123!",
47
+ },
48
+ expectedBehaviour: "The action code in each link is one-time. The second open is refused by Firebase and the site turns that refusal into readable English with a way to get a fresh link. No second password change is applied and no second verification is recorded.",
49
+ expectedUiState: "On the second open of the reset link: a message in the shape of 'This link has already been used or has expired', plus a control to request a new one. Not a blank page, not a raw 'auth/invalid-action-code', not a stack trace, and not a working password form. The second open of the verification link reads the same way.",
50
+ expectedData: { passwordChangesApplied: 1 },
51
+ endResult: "Account state after the second click is identical to after the first. divya.funko@gmail.com is back on TempPass123! by the final step — skipping that restore leaves the account unusable by every later case, since the seeder never resets an existing password.",
52
+ },
53
+ "checklist-account-auth-signup-login-auth-emails-sender-identity-and-inbox": {
54
+ roles: ["guest"],
55
+ startPage: "/auth/register",
56
+ steps: [
57
+ "Open /auth/register.",
58
+ "Type QA Sender Test in 'Full name', a real Gmail address you can open in 'Email address', TestPass123! in both password fields, tick the terms checkbox, and click 'Create account'.",
59
+ "Open that Gmail inbox, checking the Spam and Promotions tabs as well, and find the verification email.",
60
+ "Read its From name and From address, and open the link inside it.",
61
+ "Open /auth/forgot-password, type the same Gmail address, and click 'Send reset link'.",
62
+ "Open the Gmail inbox again, find the password-reset email, and read its From name and From address.",
63
+ "Repeat both flows with a non-Gmail address if one is available, and check that inbox the same way.",
64
+ ],
65
+ inputs: { fullName: "QA Sender Test", password: "TestPass123!" },
66
+ expectedBehaviour: "Both emails are delivered to the inbox within a few minutes, from the site's own configured sender. The links inside resolve to the live site and complete their flows rather than 404ing or landing on a Firebase-hosted page the site does not control.",
67
+ expectedUiState: "The From display name is spelled 'LetItRip' exactly — not 'Letitrip', not 'LetiTrip', not 'letitrip.in'. Both messages sit in the Primary inbox, not Spam or Promotions. Clicking through opens letitrip.in and the flow finishes.",
68
+ expectedData: { senderDisplayName: "LetItRip" },
69
+ endResult: "Verification marks the new account verified and the reset link changes its password. If Gmail and non-Gmail were both tried, note in the comment whether delivery differed — that difference is the point of testing two providers.",
70
+ },
71
+ "checklist-account-auth-signup-login-email-signup": {
72
+ roles: ["guest"],
73
+ startPage: "/auth/register",
74
+ steps: [
75
+ "Open /auth/register.",
76
+ "Type QA Signup Tester in the 'Full name' field.",
77
+ "Type qa-signup-1@mailnull.com in the 'Email address' field — if that address already has an account from a previous run, increment the number and use qa-signup-2@mailnull.com, and so on.",
78
+ "Type TestPass123! in the 'Password' field.",
79
+ "Type TestPass123! in the 'Confirm password' field.",
80
+ "Tick the 'I accept the terms' checkbox.",
81
+ "Click 'Create account'.",
82
+ "Open /user.",
83
+ ],
84
+ inputs: {
85
+ fullName: "QA Signup Tester",
86
+ email: "qa-signup-1@mailnull.com",
87
+ password: "TestPass123!",
88
+ },
89
+ expectedBehaviour: "A Firebase Auth record and a matching Firestore user document are created, keyed on the Auth uid rather than on a generated user-* slug. A verification email is dispatched. The browser is signed in and moved off /auth/register.",
90
+ expectedUiState: "The address bar leaves /auth/register for / or /user, and the header shows a signed-in avatar with no 'Sign in' link. Submitting the same address a second time is refused with a readable 'email already in use' message, not a duplicate account.",
91
+ expectedData: { displayName: "QA Signup Tester" },
92
+ endResult: "Reloading /user shows 'QA Signup Tester' and the address used. The account persists — this case creates a real row that a later teardown does not remove, which is why the address is numbered rather than fixed.",
93
+ },
94
+ "checklist-account-auth-signup-login-email-verify": {
95
+ roles: ["guest"],
96
+ startPage: "/auth/register",
97
+ steps: [
98
+ "Open /auth/register and create an account with an inbox you can open, using TestPass123! as the password.",
99
+ "Open the inbox and find the verification email from Firebase.",
100
+ "Open the verification link in the email.",
101
+ "Open /auth/login and sign in with that account.",
102
+ "Open /user.",
103
+ ],
104
+ inputs: { password: "TestPass123!" },
105
+ expectedBehaviour: "Following the link flips the account's emailVerified flag in Firebase Auth, and the site reads that flag rather than a separate copy of its own. The verified state survives sign-out and sign-in.",
106
+ expectedUiState: "The link lands on a confirmation page. After signing in, /user carries no 'Your email is not verified' banner and no prompt to resend the verification email.",
107
+ expectedData: { emailVerified: true },
108
+ endResult: "Reloading /user still shows no verification warning. An account that reads as unverified after a successful link click is the failure this case catches.",
109
+ },
110
+ "checklist-account-auth-signup-login-forgot-password-no-account-enumeration": {
111
+ roles: ["guest"],
112
+ startPage: "/auth/forgot-password",
113
+ steps: [
114
+ "Open /auth/forgot-password.",
115
+ "Type nobody-here-12345@example.com in the 'Email address' field.",
116
+ "Click 'Send reset link'.",
117
+ "Read the resulting message and note its exact wording.",
118
+ "Reload /auth/forgot-password, type rehan.sheikh@gmail.com, and click 'Send reset link'.",
119
+ "Read that message and compare the two word for word.",
120
+ ],
121
+ inputs: { unknownEmail: "nobody-here-12345@example.com", knownEmail: "rehan.sheikh@gmail.com" },
122
+ expectedBehaviour: "The browser calls Firebase directly, so it is the client that must swallow auth/user-not-found. Both submissions produce the identical generic response; nothing in the message, the timing or an error toast distinguishes an address that has an account from one that does not.",
123
+ expectedUiState: "Both attempts show the same text — 'If an account exists for that email, a reset link is on its way.' or equivalent. The unknown address produces no red toast, no 'user not found', no field-level error, and no different button state.",
124
+ endResult: "No email arrives for nobody-here-12345@example.com. The two on-screen responses were indistinguishable, which is the whole point — a difference of any kind is an account-enumeration leak.",
125
+ },
126
+ "checklist-account-auth-signup-login-google-link-confirmation-shown": {
127
+ roles: ["buyer"],
128
+ startPage: "/user",
129
+ steps: [
130
+ "Sign in as an account that already has Google linked — or link one first through /user/settings > 'Linked Accounts' > 'Connect Google'.",
131
+ "Open /user.",
132
+ "Read the alert area near the top of the dashboard.",
133
+ "Reload the page.",
134
+ ],
135
+ expectedBehaviour: "The dashboard handles the linked case explicitly, not just by omitting the unlinked prompt. Before this was fixed the whole alert block disappeared once linked, so a user had no confirmation on /user at all — only Settings showed a Connected badge.",
136
+ expectedUiState: "A green confirmation alert reading 'Google account connected', carrying a Connected badge and the linked Google email address. The blue 'Connect your Google account' prompt is absent. An empty space where the alert used to be is a fail, not a pass.",
137
+ endResult: "After reload the green confirmation is still there and the blue prompt has not returned. Needs a Google account to reach — answer null with that reason rather than guessing if none is available.",
138
+ },
139
+ "checklist-account-auth-signup-login-google-link-conflict-rejected": {
140
+ roles: ["buyer"],
141
+ startPage: "/user/settings",
142
+ steps: [
143
+ "Sign in as rehan.sheikh@gmail.com / TempPass123!.",
144
+ "Open /user/settings, expand 'Linked Accounts', click 'Connect Google', and complete the popup with a Google account G.",
145
+ "Sign out.",
146
+ "Sign in as vivaan.kapoor@gmail.com / TempPass123!.",
147
+ "Open /user/settings.",
148
+ "Expand the 'Linked Accounts' accordion.",
149
+ "Click 'Connect Google'.",
150
+ "Select the same Google account G in the popup and complete the flow.",
151
+ "Reload /user/settings and expand 'Linked Accounts'.",
152
+ ],
153
+ inputs: { accountA: "vivaan.kapoor@gmail.com", accountB: "rehan.sheikh@gmail.com" },
154
+ expectedBehaviour: "The second link is refused because G already belongs to rehan.sheikh@gmail.com. Neither account is modified: the two are not merged, and G's email is not moved from one to the other. A silent merge here would join two people's orders, addresses and wishlists.",
155
+ expectedUiState: "A readable error in the shape of 'This Google account is already linked to another account'. vivaan.kapoor@gmail.com still shows a 'Connect Google' button, not a Connected badge.",
156
+ endResult: "After reload vivaan.kapoor@gmail.com has no Google link and rehan.sheikh@gmail.com still has G. Unlink G from rehan.sheikh@gmail.com afterwards. Needs a real Google account — answer null if none is available.",
157
+ },
158
+ "checklist-account-auth-signup-login-google-link-different-email": {
159
+ roles: ["buyer"],
160
+ startPage: "/user/settings",
161
+ steps: [
162
+ "Sign in as vivaan.kapoor@gmail.com / TempPass123!.",
163
+ "Open /user/settings.",
164
+ "Expand the 'Linked Accounts' accordion.",
165
+ "Click 'Connect Google'.",
166
+ "Select a Google account whose email is NOT vivaan.kapoor@gmail.com, and complete the popup.",
167
+ "Reload /user/settings and expand 'Linked Accounts'.",
168
+ "Sign out, open /auth/login, and click 'Sign in with Google' choosing that same Google account.",
169
+ ],
170
+ inputs: { primaryEmail: "vivaan.kapoor@gmail.com" },
171
+ expectedBehaviour: "Linking a differently-addressed Google account requires this explicit button press — it never happens as a side effect of merely signing in with Google. One account now answers to two emails; a second account is not created. The primary login email is unchanged.",
172
+ expectedUiState: "'Linked Accounts' shows Google as Connected and displays the OTHER email. The account's own email elsewhere in Settings still reads vivaan.kapoor@gmail.com. Signing in with that Google account afterwards lands in this same account, with its existing orders and wishlist.",
173
+ expectedData: { primaryEmail: "vivaan.kapoor@gmail.com" },
174
+ endResult: "After reload the link persists and the primary email is still vivaan.kapoor@gmail.com. Unlink afterwards. Needs a second Google account — answer null if none is available.",
175
+ },
176
+ "checklist-account-auth-signup-login-google-link-existing": {
177
+ roles: ["guest"],
178
+ startPage: "/auth/register",
179
+ steps: [
180
+ "Open /auth/register.",
181
+ "Type QA Google Merge in 'Full name', the email address of a Google account you control in 'Email address', TestPass123! in both password fields, tick the terms checkbox, and click 'Create account'.",
182
+ "Add any product to the wishlist so the account has something identifying in it.",
183
+ "Sign out.",
184
+ "Open /auth/login.",
185
+ "Click 'Sign in with Google'.",
186
+ "Select that same Google account in the popup and complete it.",
187
+ "Open /wishlist.",
188
+ "Open /user/settings and expand 'Linked Accounts'.",
189
+ ],
190
+ inputs: { fullName: "QA Google Merge", password: "TestPass123!" },
191
+ expectedBehaviour: "Because the Google email matches an existing password account exactly, the sign-in resolves to that same account automatically — no duplicate, and no explicit linking step asked of the user. Google is recorded as connected as a side effect.",
192
+ expectedUiState: "No 'create account' step appears after the popup. The header shows 'QA Google Merge', and /wishlist still holds the item added before signing out — the proof it is the same account and not a fresh one wearing the same email. 'Linked Accounts' shows Google Connected.",
193
+ expectedData: { displayName: "QA Google Merge" },
194
+ endResult: "One account exists for that email, not two, and it kept its wishlist. Needs a Google account whose address you can also register with — answer null if none is available.",
195
+ },
196
+ "checklist-account-auth-signup-login-google-oauth": {
197
+ roles: ["guest"],
198
+ startPage: "/auth/login",
199
+ steps: [
200
+ "Open /auth/login.",
201
+ "Click 'Sign in with Google'.",
202
+ "Complete the Google popup by choosing an account.",
203
+ "Wait for the popup to close and the site to respond.",
204
+ "Open /user.",
205
+ ],
206
+ expectedBehaviour: "The popup opens, Google authenticates, the popup closes, and the site establishes its own session cookie from the returned credential. An account is created if the email is new, or signed into if it already exists.",
207
+ expectedUiState: "The address bar leaves /auth/login. The header shows a signed-in avatar and no 'Sign in' link. No error toast, and no popup left hanging open after authentication.",
208
+ endResult: "Reloading /user keeps the session. Needs a Google account — answer null with that reason if none is available.",
209
+ },
210
+ "checklist-account-auth-signup-login-google-popup-blocked-fallback": {
211
+ roles: ["guest"],
212
+ startPage: "/auth/login",
213
+ steps: [
214
+ "Set the browser to block popups for letitrip.in.",
215
+ "Open /auth/login.",
216
+ "Click 'Sign in with Google'.",
217
+ "Leave the blocked-popup notification alone without unblocking it.",
218
+ "Wait up to 30 seconds and watch the page.",
219
+ "Open /user.",
220
+ ],
221
+ expectedBehaviour: "The site notices the popup never opened and falls back — either to a full-page redirect flow, or to the RTDB signal plus postMessage path — and completes sign-in without asking the user to change browser settings.",
222
+ expectedUiState: "Within 30 seconds the page reaches a signed-in state: avatar in the header, no 'Sign in' link. What must NOT happen is a button stuck in a loading state forever, or an error toast telling the user to allow popups and nothing else.",
223
+ endResult: "Reloading /user keeps the session. Needs a Google account plus popup blocking — answer null if either is unavailable.",
224
+ },
225
+ "checklist-account-auth-signup-login-login": {
226
+ roles: ["guest"],
227
+ startPage: "/auth/login",
228
+ steps: [
229
+ "Open /auth/login.",
230
+ "Type vivaan.kapoor@gmail.com in the 'Email address' field.",
231
+ "Type TempPass123! in the 'Password' field.",
232
+ "Click 'Sign in'.",
233
+ "Open /user.",
234
+ ],
235
+ inputs: { email: "vivaan.kapoor@gmail.com", password: "TempPass123!" },
236
+ expectedBehaviour: "Firebase validates the credential, the site exchanges it for its own __session cookie, and the browser is moved off /auth/login. A wrong password is refused with a readable message rather than a raw Firebase code.",
237
+ expectedUiState: "The address bar leaves /auth/login for / or /user, and the header shows the avatar for Vivaan Kapoor. No error toast.",
238
+ expectedData: { signedInUid: "user-seto-kaiba" },
239
+ endResult: "Reloading /user keeps the session as user-seto-kaiba. Every seeded account uses TempPass123!, so no separate credential lookup is needed.",
240
+ },
241
+ "checklist-account-auth-signup-login-logout": {
242
+ roles: ["buyer"],
243
+ startPage: "/user",
244
+ steps: [
245
+ "Sign in as vivaan.kapoor@gmail.com / TempPass123!.",
246
+ "Open /user.",
247
+ "Click 'Log out' in the sidebar.",
248
+ "Open /user again.",
249
+ ],
250
+ expectedBehaviour: "Both halves of the session end: the server __session cookie is cleared and the Firebase client session is revoked. Clearing only one leaves the browser able to re-mint a session on the next request, which is what makes the second navigation the real check.",
251
+ expectedUiState: "After Log out the page redirects and the header shows the signed-out state. Opening /user afterwards redirects to /auth/login rather than rendering the dashboard, even briefly with real data in it.",
252
+ expectedData: { redirectTarget: "/auth/login" },
253
+ endResult: "Navigating to /user lands on /auth/login and no data for Vivaan Kapoor is rendered at any point. A back-button press does not restore the dashboard.",
254
+ },
255
+ "checklist-account-auth-signup-login-password-reset": {
256
+ roles: ["guest"],
257
+ startPage: "/auth/login",
258
+ steps: [
259
+ "Open /auth/login.",
260
+ "Click 'Forgot password?'.",
261
+ "Type neha.op@gmail.com in the 'Email address' field.",
262
+ "Click 'Send reset link'.",
263
+ "Open the inbox for neha.op@gmail.com and open the reset link.",
264
+ "Type QaReset321! as the new password, confirm it, and submit.",
265
+ "Open /auth/login, type neha.op@gmail.com and TempPass123!, and click 'Sign in'.",
266
+ "Type neha.op@gmail.com and QaReset321! instead, and click 'Sign in'.",
267
+ "Request another reset link for neha.op@gmail.com and use it to set the password back to TempPass123!.",
268
+ ],
269
+ inputs: {
270
+ email: "neha.op@gmail.com",
271
+ newPassword: "QaReset321!",
272
+ restoredPassword: "TempPass123!",
273
+ },
274
+ expectedBehaviour: "The reset email arrives, its link opens a set-password form, and the submitted password replaces the old one in Firebase Auth. The old password stops working at that moment — a reset that leaves both passwords valid is the failure worth catching.",
275
+ expectedUiState: "'Send reset link' produces the generic 'If an account exists for that email…' message. Signing in with TempPass123! after the reset is refused with a readable error; signing in with QaReset321! succeeds and lands on the dashboard.",
276
+ endResult: "The password is back at TempPass123! by the final step. That restore is mandatory: the seeder never resets an existing password, so skipping it leaves this account permanently signed out of every later case.",
277
+ },
278
+ "checklist-account-auth-signup-login-signup-verification-email-arrives": {
279
+ roles: ["guest"],
280
+ startPage: "/auth/register",
281
+ steps: [
282
+ "Open /auth/register.",
283
+ "Type QA Verify Tester in the 'Full name' field.",
284
+ "Type a real inbox address you can open in the 'Email address' field.",
285
+ "Type TestPass123! in the 'Password' field.",
286
+ "Type TestPass123! in the 'Confirm password' field.",
287
+ "Tick the 'I accept the terms' checkbox.",
288
+ "Click 'Create account'.",
289
+ "Open that inbox, checking Spam as well, and wait up to five minutes.",
290
+ "Open the verification link in the email.",
291
+ ],
292
+ inputs: { fullName: "QA Verify Tester", password: "TestPass123!" },
293
+ expectedBehaviour: "Firebase's client SDK sends the verification mail directly, so it carries Firebase's own template and sender rather than the branded LetItRip one. The link resolves to the live site and marks the account verified. The on-screen 'check your email' message is not the thing being tested — the arrival is.",
294
+ expectedUiState: "An email is present in the inbox within a few minutes. It looks like Firebase's default template, and that difference from the branded Resend emails is expected here, not a defect. Its link opens letitrip.in and reports success.",
295
+ expectedData: { emailVerified: true },
296
+ endResult: "Signing in and reloading /user shows no 'email not verified' warning. A 'check your email' screen with no email ever arriving is exactly the failure this case exists to separate from success.",
297
+ },
298
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;
@@ -0,0 +1,33 @@
1
+ /*
2
+ * WHY: Authored six-part procedures for the account-auth/testing-program checklist page.
3
+ * WHAT: 1 case(s), keyed by full checklist id.
4
+ *
5
+ * Generated by `node tester/scripts/merge-authored.mjs --page account-auth/testing-program`, then
6
+ * reviewed by a human before merge — the review is the gate, not the generation.
7
+ * Hand edits are safe and expected: re-running the merge for this page replaces
8
+ * the file, so re-author only when you mean to discard them.
9
+ *
10
+ * @tag domain:tester
11
+ * @tag layer:seed
12
+ * @tag pattern:none
13
+ * @tag access:server-only
14
+ * @tag consumers:seed-data/authored/index.ts
15
+ * @tag sideEffects:none
16
+ */
17
+ export const authored = {
18
+ "checklist-account-auth-testing-program-admin-testing-section": {
19
+ roles: ["admin"],
20
+ startPage: "/admin/dashboard",
21
+ steps: [
22
+ "Sign in as admin@letitrip.in.",
23
+ "Open /admin/dashboard.",
24
+ "Locate the 'Admin Panel' sidebar on the right side of the page.",
25
+ "Click the 'Testing' section heading in the sidebar to expand it.",
26
+ "Locate the 'Test Cases' link in the Testing section.",
27
+ "Locate the 'Results' link in the Testing section.",
28
+ ],
29
+ expectedBehaviour: "The admin sidebar renders a 'Testing' collapsible section containing at least two links: 'Test Cases' (pointing to /admin/tester-checklist) and 'Results' (pointing to /admin/tester-feedback). Both links are clickable and navigate to their respective pages.",
30
+ expectedUiState: "The Testing section is visible in the Admin Panel sidebar. It contains a 'Test Cases' link and a 'Results' link. Both links are present and labelled exactly 'Test Cases' and 'Results'.",
31
+ endResult: "After reload, the sidebar still shows the Testing section with both links. No data is persisted by this case — it is a read-only navigation check.",
32
+ },
33
+ };
@@ -0,0 +1,2 @@
1
+ import type { AuthoredCase } from "./_types";
2
+ export declare const authored: Record<string, AuthoredCase>;