@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.
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +32 -2
- package/dist/features/tester/components/TesterChecklistStepRow.d.ts +9 -1
- package/dist/features/tester/components/TesterChecklistStepRow.js +31 -2
- package/dist/features/tester/components/TesterHubView.js +8 -0
- package/dist/features/tester/schemas/firestore.d.ts +109 -0
- package/dist/features/tester/schemas/firestore.js +14 -0
- package/dist/features/tester/seed-data/_money-flows.d.ts +23 -0
- package/dist/features/tester/seed-data/_money-flows.js +430 -0
- package/dist/features/tester/seed-data/authored/_types.d.ts +33 -0
- package/dist/features/tester/seed-data/authored/_types.js +35 -0
- package/dist/features/tester/seed-data/authored/account-auth__profile-settings.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/account-auth__profile-settings.js +207 -0
- package/dist/features/tester/seed-data/authored/account-auth__signup-login.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/account-auth__signup-login.js +298 -0
- package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/account-auth__testing-program--admin.js +33 -0
- package/dist/features/tester/seed-data/authored/account-auth__testing-program.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/account-auth__testing-program.js +138 -0
- package/dist/features/tester/seed-data/authored/addresses__address-filters.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__address-filters.js +36 -0
- package/dist/features/tester/seed-data/authored/addresses__postal-lookup.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__postal-lookup.js +75 -0
- package/dist/features/tester/seed-data/authored/addresses__postal-validation.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__postal-validation.js +72 -0
- package/dist/features/tester/seed-data/authored/addresses__state-picker.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__state-picker.js +54 -0
- package/dist/features/tester/seed-data/authored/addresses__unban-request.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/addresses__unban-request.js +39 -0
- package/dist/features/tester/seed-data/authored/admin__bans-and-trust.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__bans-and-trust.js +226 -0
- package/dist/features/tester/seed-data/authored/admin__blog-faqs.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__blog-faqs.js +82 -0
- package/dist/features/tester/seed-data/authored/admin__bulk-actions.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__bulk-actions.js +177 -0
- package/dist/features/tester/seed-data/authored/admin__bundles.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__bundles.js +97 -0
- package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.js +232 -0
- package/dist/features/tester/seed-data/authored/admin__catalog-listings.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__catalog-listings.js +306 -0
- package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.js +158 -0
- package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.js +78 -0
- package/dist/features/tester/seed-data/authored/admin__content-deletes.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__content-deletes.js +261 -0
- package/dist/features/tester/seed-data/authored/admin__content-marketing.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__content-marketing.js +151 -0
- package/dist/features/tester/seed-data/authored/admin__coupons.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__coupons.js +214 -0
- package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +160 -0
- package/dist/features/tester/seed-data/authored/admin__media-watermark.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__media-watermark.js +104 -0
- package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.js +350 -0
- package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.js +105 -0
- package/dist/features/tester/seed-data/authored/admin__site-system.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__site-system.js +590 -0
- package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.js +235 -0
- package/dist/features/tester/seed-data/authored/admin__users-trust.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/admin__users-trust.js +569 -0
- package/dist/features/tester/seed-data/authored/buying__bidding.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__bidding.js +417 -0
- package/dist/features/tester/seed-data/authored/buying__browsing-search.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__browsing-search.js +653 -0
- package/dist/features/tester/seed-data/authored/buying__buying-checkout.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +533 -0
- package/dist/features/tester/seed-data/authored/buying__buying-coupons.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__buying-coupons.js +379 -0
- package/dist/features/tester/seed-data/authored/buying__cart.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__cart.js +1171 -0
- package/dist/features/tester/seed-data/authored/buying__image-tile-layout.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__image-tile-layout.js +140 -0
- package/dist/features/tester/seed-data/authored/buying__my-orders.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__my-orders.js +257 -0
- package/dist/features/tester/seed-data/authored/buying__offers.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__offers.js +1111 -0
- package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.js +252 -0
- package/dist/features/tester/seed-data/authored/buying__product-detail.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__product-detail.js +387 -0
- package/dist/features/tester/seed-data/authored/buying__return-request.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__return-request.js +152 -0
- package/dist/features/tester/seed-data/authored/buying__reviews-pagination.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__reviews-pagination.js +242 -0
- package/dist/features/tester/seed-data/authored/buying__reviews.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__reviews.js +113 -0
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.js +283 -0
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.js +167 -0
- package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.js +90 -0
- package/dist/features/tester/seed-data/authored/buying__wishlist-history.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__wishlist-history.js +344 -0
- package/dist/features/tester/seed-data/authored/community-support__public-profile.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/community-support__public-profile.js +53 -0
- package/dist/features/tester/seed-data/authored/community-support__support-tickets.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/community-support__support-tickets.js +76 -0
- package/dist/features/tester/seed-data/authored/content-discovery__blog.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__blog.js +93 -0
- package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.js +149 -0
- package/dist/features/tester/seed-data/authored/content-discovery__coupons.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__coupons.js +121 -0
- package/dist/features/tester/seed-data/authored/content-discovery__event-participation.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__event-participation.js +207 -0
- package/dist/features/tester/seed-data/authored/content-discovery__events.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__events.js +318 -0
- package/dist/features/tester/seed-data/authored/content-discovery__faq-help.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__faq-help.js +65 -0
- package/dist/features/tester/seed-data/authored/content-discovery__notifications.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__notifications.js +147 -0
- package/dist/features/tester/seed-data/authored/content-discovery__search.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__search.js +332 -0
- package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.js +53 -0
- package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.js +52 -0
- package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.js +35 -0
- package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.js +141 -0
- package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.js +35 -0
- package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.js +95 -0
- package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.js +191 -0
- package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.js +158 -0
- package/dist/features/tester/seed-data/authored/design-ux__footer-theme.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__footer-theme.js +106 -0
- package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.js +88 -0
- package/dist/features/tester/seed-data/authored/design-ux__general-design.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__general-design.js +204 -0
- package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.js +301 -0
- package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.js +407 -0
- package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.js +214 -0
- package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.js +275 -0
- package/dist/features/tester/seed-data/authored/index.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/index.js +237 -0
- package/dist/features/tester/seed-data/authored/page-wiring__data-loss.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/page-wiring__data-loss.js +102 -0
- package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.js +50 -0
- package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.js +66 -0
- package/dist/features/tester/seed-data/authored/page-wiring__reachability.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/page-wiring__reachability.js +115 -0
- package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.js +136 -0
- package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.js +69 -0
- package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.js +263 -0
- package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.js +102 -0
- package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.js +234 -0
- package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.js +126 -0
- package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.js +255 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.js +59 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +88 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.js +51 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.js +35 -0
- package/dist/features/tester/seed-data/authored/selling__become-seller.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__become-seller.js +94 -0
- package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.js +107 -0
- package/dist/features/tester/seed-data/authored/selling__listing-a-product.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__listing-a-product.js +285 -0
- package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.js +326 -0
- package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.js +136 -0
- package/dist/features/tester/seed-data/authored/selling__media-limits.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__media-limits.js +128 -0
- package/dist/features/tester/seed-data/authored/selling__sectionised-forms.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__sectionised-forms.js +167 -0
- package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.js +117 -0
- package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.js +88 -0
- package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.js +151 -0
- package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.js +105 -0
- package/dist/features/tester/seed-data/authored/selling__seller-guide.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-guide.js +33 -0
- package/dist/features/tester/seed-data/authored/selling__seller-listing-types.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-listing-types.js +347 -0
- package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +166 -0
- package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.js +89 -0
- package/dist/features/tester/seed-data/authored/selling__seller-orders.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-orders.js +195 -0
- package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.js +180 -0
- package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.js +164 -0
- package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.js +116 -0
- package/dist/features/tester/seed-data/authored/seo__canonical-and-host.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/seo__canonical-and-host.js +111 -0
- package/dist/features/tester/seed-data/authored/seo__og-images.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/seo__og-images.js +91 -0
- package/dist/features/tester/seed-data/authored/seo__page-metadata.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/seo__page-metadata.js +122 -0
- package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.js +105 -0
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +744 -1
- package/dist/seed/carousel-slides-seed-data.js +1 -1
- package/dist/seed/products-standard-seed-data.js +2 -2
- package/dist/seed/reviews-seed-data.js +6 -1
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +6 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the public-pages/legal-policy-pages page.
|
|
3
|
+
* WHAT: 7 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
|
+
* All six policy pages share one renderer, so most of these cases are really
|
|
10
|
+
* about the ONE thing that differs per page: which content the renderer is
|
|
11
|
+
* handed, and which related links it derives.
|
|
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-public-pages-legal-policy-pages-shipping-refund-policy": {
|
|
22
|
+
roles: ["guest"],
|
|
23
|
+
startPage: "/shipping-policy",
|
|
24
|
+
steps: [
|
|
25
|
+
"Open /shipping-policy in a private window with no session.",
|
|
26
|
+
"Read the headings and body content.",
|
|
27
|
+
"Open /refund-policy and read the headings and body content.",
|
|
28
|
+
"Compare the two — they must not be the same text.",
|
|
29
|
+
],
|
|
30
|
+
expectedBehaviour: "Each policy page renders its own copy through the shared renderer. Two policy pages showing identical text means the page key is not reaching the content lookup and one of them is displaying the other's terms.",
|
|
31
|
+
expectedUiState: "Both pages show headings and paragraphs specific to their subject. Neither is blank, neither 404s, and the two bodies are visibly different documents.",
|
|
32
|
+
endResult: "Read-only; nothing persists.",
|
|
33
|
+
},
|
|
34
|
+
"checklist-public-pages-legal-policy-pages-refund-policy-not-raw-json": {
|
|
35
|
+
roles: ["guest"],
|
|
36
|
+
startPage: "/refund-policy",
|
|
37
|
+
steps: [
|
|
38
|
+
"Open /refund-policy in a private window with no session.",
|
|
39
|
+
"Read the first line of the page body.",
|
|
40
|
+
"Search the page for the characters {\"type\":\"doc\".",
|
|
41
|
+
"Search the page for the words 'content', 'attrs' and 'paragraph' appearing as visible text rather than as prose.",
|
|
42
|
+
],
|
|
43
|
+
expectedBehaviour: "The renderer injects its content as HTML, so whatever is stored must BE html. A rich-text editor document stored as JSON in that field is rendered as its own source — the page returns 200, the layout is intact, and the body is a wall of braces.",
|
|
44
|
+
expectedUiState: "The body reads as English policy prose. It does not begin with {\"type\":\"doc\", and none of 'content', 'attrs' or 'paragraph' appears as visible page text.",
|
|
45
|
+
endResult: "Read-only. Re-seed before running this: the fix was to set the seeded override to an empty string so the page falls back to its own copy, and a stale database still holds the JSON.",
|
|
46
|
+
},
|
|
47
|
+
"checklist-public-pages-legal-policy-pages-privacy-cookies-security": {
|
|
48
|
+
roles: ["guest"],
|
|
49
|
+
startPage: "/privacy",
|
|
50
|
+
steps: [
|
|
51
|
+
"Open /privacy in a private window with no session and read the body.",
|
|
52
|
+
"Open /cookies and read the body.",
|
|
53
|
+
"Open /security and read the body.",
|
|
54
|
+
"Compare all three — none may repeat another's text.",
|
|
55
|
+
],
|
|
56
|
+
expectedBehaviour: "Three distinct policies render three distinct documents through the shared renderer.",
|
|
57
|
+
expectedUiState: "Each page shows its own headings and paragraphs. None is blank, none 404s, and no two are the same document.",
|
|
58
|
+
endResult: "Read-only; nothing persists.",
|
|
59
|
+
},
|
|
60
|
+
"checklist-public-pages-legal-policy-pages-ethics-page-loads": {
|
|
61
|
+
roles: ["guest"],
|
|
62
|
+
startPage: "/ethics",
|
|
63
|
+
steps: [
|
|
64
|
+
"Open /ethics in a private window with no session.",
|
|
65
|
+
"Find the section covering live animals and plants.",
|
|
66
|
+
"Read it for vendor verification, a lawful-destination check, CITES paperwork and specialist transport.",
|
|
67
|
+
"Open / and find the Ethics link in the footer's Support column.",
|
|
68
|
+
"Open /about and find the 'How we hold ourselves to this →' link in the Values section.",
|
|
69
|
+
],
|
|
70
|
+
expectedBehaviour: "The page exists, states the live-item commitments specifically, and is reachable from both the footer and the About page. A page nobody can navigate to is as unfinished as one that does not render.",
|
|
71
|
+
expectedUiState: "The live-animal section names all four commitments — vendor verification, lawful destination, CITES paperwork, specialist transport — rather than gesturing at 'responsible sourcing'. Both links reach /ethics.",
|
|
72
|
+
expectedData: { liveItemCommitmentCount: 4 },
|
|
73
|
+
endResult: "Read-only; nothing persists.",
|
|
74
|
+
},
|
|
75
|
+
"checklist-public-pages-legal-policy-pages-code-of-conduct-loads": {
|
|
76
|
+
roles: ["guest"],
|
|
77
|
+
startPage: "/code-of-conduct",
|
|
78
|
+
steps: [
|
|
79
|
+
"Open /code-of-conduct in a private window with no session.",
|
|
80
|
+
"Read the page for sections on listing honestly, bidding in good faith and review integrity.",
|
|
81
|
+
"Read it for the enforcement and appeal ladder.",
|
|
82
|
+
"Open / and find the Code of Conduct link in the footer's Legal column.",
|
|
83
|
+
],
|
|
84
|
+
expectedBehaviour: "The page covers all four topics and is reachable from the footer's Legal column. The appeal ladder matters most — a code that states rules without stating how to contest an enforcement is half a document.",
|
|
85
|
+
expectedUiState: "Sections on listing honestly, bidding in good faith, review integrity and the enforcement/appeal ladder are all present. The footer link reaches the page.",
|
|
86
|
+
expectedData: { topicCount: 4 },
|
|
87
|
+
endResult: "Read-only; nothing persists.",
|
|
88
|
+
},
|
|
89
|
+
"checklist-public-pages-legal-policy-pages-policy-related-links-exclude-self": {
|
|
90
|
+
roles: ["guest"],
|
|
91
|
+
startPage: "/ethics",
|
|
92
|
+
steps: [
|
|
93
|
+
"Open /terms in a private window and read the Related Policies list at the foot of the page.",
|
|
94
|
+
"Count the links and check whether Terms itself is among them.",
|
|
95
|
+
"Repeat on /privacy, reading and counting the same list.",
|
|
96
|
+
"Repeat on /cookies.",
|
|
97
|
+
"Repeat on /refund-policy.",
|
|
98
|
+
"Repeat on /ethics.",
|
|
99
|
+
"Repeat on /code-of-conduct.",
|
|
100
|
+
],
|
|
101
|
+
expectedBehaviour: "The related-links list is derived from one registry with the current page filtered out, so every page offers exactly the other five. A self-link is the tell that the filter is missing — it reads as a working link and goes nowhere new.",
|
|
102
|
+
expectedUiState: "All six pages show exactly five related links, and on none of them is the current page one of them. Four links means the registry is short; six means the self-filter is not running.",
|
|
103
|
+
expectedData: { relatedLinkCount: 5 },
|
|
104
|
+
endResult: "Read-only; nothing persists. Checking all six is the case — the filter can be right on one page and wrong on another only if the list is hand-written per page, which is what this rules out.",
|
|
105
|
+
},
|
|
106
|
+
"checklist-public-pages-legal-policy-pages-policy-admin-html-override": {
|
|
107
|
+
roles: ["admin", "guest"],
|
|
108
|
+
startPage: "/admin/site",
|
|
109
|
+
steps: [
|
|
110
|
+
"Open /ethics in a private window and read the first paragraph.",
|
|
111
|
+
"Sign in as admin@letitrip.in / TempPass123! in a normal window.",
|
|
112
|
+
"Open /admin/site?tab=legal and find the 'Our Ethics' textarea.",
|
|
113
|
+
"Type <p>QA Ethics policy-admin-html-override</p> into it.",
|
|
114
|
+
"Save.",
|
|
115
|
+
"Return to the private window and reload /ethics immediately.",
|
|
116
|
+
"Read the first paragraph.",
|
|
117
|
+
"Go back to the admin textarea, clear it completely, and save again.",
|
|
118
|
+
"Reload /ethics in the private window once more.",
|
|
119
|
+
],
|
|
120
|
+
inputs: { override: "<p>QA Ethics policy-admin-html-override</p>" },
|
|
121
|
+
expectedBehaviour: "The whole chain runs on save: admin textarea, stored override, renderer read, and a cache bust. These pages are cached for an hour, so without the revalidation the admin's change would be invisible for up to sixty minutes and would look like a save that failed.",
|
|
122
|
+
expectedUiState: "/ethics shows the typed sentence immediately after saving — not after a wait. After the textarea is cleared and saved, the page reverts to its default copy on the next reload.",
|
|
123
|
+
expectedData: { revalidatedImmediately: true },
|
|
124
|
+
endResult: "The textarea is empty again and /ethics shows its default content. Leaving the override in place would break the ethics-page-loads case above, which reads the real copy.",
|
|
125
|
+
},
|
|
126
|
+
};
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the public-pages/stores-sellers-directories page.
|
|
3
|
+
* WHAT: 16 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
|
+
* 🛑 SEVERAL CASES HERE HINGE ON A DISTINCTION THAT IS EASY TO LOSE: a tab's URL
|
|
10
|
+
* segment and a listing type are DIFFERENT id spaces. Tab bars key on the URL
|
|
11
|
+
* segment, filter chips key on the listing type, and conflating them either
|
|
12
|
+
* breaks live URLs or silently returns zero rows. That is why the store tab cases
|
|
13
|
+
* name the tab by its visible label and the URL by its path, never interchangeably.
|
|
14
|
+
*
|
|
15
|
+
* @tag domain:tester
|
|
16
|
+
* @tag layer:seed
|
|
17
|
+
* @tag pattern:none
|
|
18
|
+
* @tag access:server-only
|
|
19
|
+
* @tag consumers:seed-data/authored/index.ts
|
|
20
|
+
* @tag sideEffects:none
|
|
21
|
+
*/
|
|
22
|
+
export const authored = {
|
|
23
|
+
"checklist-public-pages-stores-sellers-directories-store-directory": {
|
|
24
|
+
roles: ["guest"],
|
|
25
|
+
startPage: "/stores",
|
|
26
|
+
steps: [
|
|
27
|
+
"Open /stores in a private window with no session.",
|
|
28
|
+
"Read every store card — name, logo, verified badge and any rating.",
|
|
29
|
+
"Note whether any card names a tester sandbox store.",
|
|
30
|
+
"Use the status filter if one is offered, selecting each value in turn and reading the results.",
|
|
31
|
+
"Click into 'Beyblade Arena'.",
|
|
32
|
+
],
|
|
33
|
+
expectedBehaviour: "The directory lists public stores through a projection that names every field it emits. Sandbox stores are filtered out for signed-out visitors in the application layer — never by a Firestore inequality, which would exclude every document lacking the flag, i.e. all the real ones, and return only test data.",
|
|
34
|
+
expectedUiState: "Real stores are listed with names, logos and verified badges. No card names a sandbox store. Any status filter offered changes which stores appear — the seed carries a pending and a suspended store precisely so those chips are not permanently empty.",
|
|
35
|
+
expectedData: { sandboxStoresVisibleToGuest: 0 },
|
|
36
|
+
endResult: "Read-only; nothing persists.",
|
|
37
|
+
},
|
|
38
|
+
"checklist-public-pages-stores-sellers-directories-store-detail-tabs": {
|
|
39
|
+
roles: ["guest"],
|
|
40
|
+
startPage: "/stores/store-beyblade-arena",
|
|
41
|
+
steps: [
|
|
42
|
+
"Open /stores/store-beyblade-arena in a private window with no session.",
|
|
43
|
+
"Read the store header and the tab bar.",
|
|
44
|
+
"Click each tab in turn and read the URL and the content.",
|
|
45
|
+
"Open the browser's View Source and search for accessToken, wabaId, catalogId, adminNotes and customCommissionRate.",
|
|
46
|
+
],
|
|
47
|
+
inputs: { storeId: "store-beyblade-arena" },
|
|
48
|
+
expectedBehaviour: "Each tab is a real route whose URL segment is stable and bookmarkable. The page is built from a store projection, not from the raw document — four pages once passed the whole document into a client component behind a cast that has no runtime effect, publishing a decrypted WhatsApp token into the page HTML.",
|
|
49
|
+
expectedUiState: "Every tab navigates to its own URL and renders content. None of the five secret field names appears anywhere in the page source, including the data payload embedded at the bottom of the HTML.",
|
|
50
|
+
expectedData: { secretFieldsInHtml: 0 },
|
|
51
|
+
endResult: "Read-only; nothing persists. A hit on any of those names is a leak regardless of how the page renders.",
|
|
52
|
+
},
|
|
53
|
+
"checklist-public-pages-stores-sellers-directories-category-tabs-every-type-renders": {
|
|
54
|
+
roles: ["guest"],
|
|
55
|
+
startPage: "/categories/category-beyblade-burst",
|
|
56
|
+
steps: [
|
|
57
|
+
"Open /categories/category-beyblade-burst in a private window with no session.",
|
|
58
|
+
"Read every tab offered and write the list down.",
|
|
59
|
+
"Click each tab in turn and read what renders beneath it.",
|
|
60
|
+
"Write down any tab that opens to a blank panel.",
|
|
61
|
+
],
|
|
62
|
+
expectedBehaviour: "Every tab that is OFFERED has a render branch behind it. The tab array and the panel that renders each type are two lists, and when one grows and the other does not, the extra tabs are clickable and open to nothing.",
|
|
63
|
+
expectedUiState: "Each tab opens to either real content or a named empty state. Not one opens to a blank panel with no message. A tab that is silently dropped from the panel switch is the failure, and it looks exactly like a slow load.",
|
|
64
|
+
expectedData: { blankPanelCount: 0 },
|
|
65
|
+
endResult: "Read-only; nothing persists.",
|
|
66
|
+
},
|
|
67
|
+
"checklist-public-pages-stores-sellers-directories-brand-tabs-every-type-offered": {
|
|
68
|
+
roles: ["guest"],
|
|
69
|
+
startPage: "/brands/brand-beyblade",
|
|
70
|
+
steps: [
|
|
71
|
+
"Open /categories/category-beyblade-burst in a private window and write down every tab it offers.",
|
|
72
|
+
"Open /brands/brand-beyblade and write down every tab it offers.",
|
|
73
|
+
"Compare the two lists, ignoring the Stores tab which categories have and brands do not.",
|
|
74
|
+
"Look specifically for Classifieds, Digital Codes, Live Items and Art & Stickers on the brand page.",
|
|
75
|
+
],
|
|
76
|
+
expectedBehaviour: "A brand page offers the same listing-type tabs as a category page minus Stores. The two components are deliberate near-duplicates with different scoping, and four types were silently missing from one of them while present in the other.",
|
|
77
|
+
expectedUiState: "Apart from Stores, the two tab lists match. Classifieds, Digital Codes, Live Items and Art & Stickers are all present on the brand page rather than quietly absent.",
|
|
78
|
+
endResult: "Read-only; nothing persists. A missing tab is invisible unless the two pages are compared side by side, which is why both lists are written down.",
|
|
79
|
+
},
|
|
80
|
+
"checklist-public-pages-stores-sellers-directories-category-brand-tab-counts-match": {
|
|
81
|
+
roles: ["guest"],
|
|
82
|
+
startPage: "/categories/category-beyblade-burst",
|
|
83
|
+
steps: [
|
|
84
|
+
"Open /categories/category-beyblade-burst in a private window.",
|
|
85
|
+
"Write down the count badge on every tab.",
|
|
86
|
+
"Open each tab in turn and count the items it actually shows, paging to the end.",
|
|
87
|
+
"Compare each pair.",
|
|
88
|
+
"Repeat on /brands/brand-beyblade.",
|
|
89
|
+
],
|
|
90
|
+
expectedBehaviour: "Counts come from one derivation over the same tab array, so a badge cannot describe a tab that no longer exists or miss one that does. A count that fails must come back as unknown rather than zero — failing to zero would hide a tab holding real stock on a transient error.",
|
|
91
|
+
expectedUiState: "Every badge matches the number of items in its tab. A badge of zero on a tab that has items, or a populated badge over an empty tab, are both failures.",
|
|
92
|
+
expectedData: { mismatchedBadgeCount: 0 },
|
|
93
|
+
endResult: "Read-only; nothing persists.",
|
|
94
|
+
},
|
|
95
|
+
"checklist-public-pages-stores-sellers-directories-empty-tabs-hidden": {
|
|
96
|
+
roles: ["guest"],
|
|
97
|
+
startPage: "/stores/store-tester-qa-seller",
|
|
98
|
+
steps: [
|
|
99
|
+
"Sign in as tester@letitrip.in / TempPass123! so sandbox content is visible.",
|
|
100
|
+
"Open /stores/store-tester-qa-seller and write down every tab offered.",
|
|
101
|
+
"Open each tab and note which are empty.",
|
|
102
|
+
"Open /stores/store-beyblade-arena and write down its tabs.",
|
|
103
|
+
"Compare the two stores' tab lists.",
|
|
104
|
+
],
|
|
105
|
+
expectedBehaviour: "A tab is hidden when its count is genuinely zero, and shown when the count could not be computed. That distinction is the whole rule: a count map that does not cover an option returns undefined, which reads as unknown and keeps the tab — so an uncovered option is structurally unhideable while a covered one vanishes correctly.",
|
|
106
|
+
expectedUiState: "Neither store shows a tab for a listing type it has none of. The two stores offer different tab sets, which is the proof that hiding is happening at all — identical tab bars on stores with different catalogues means nothing is being hidden.",
|
|
107
|
+
endResult: "Read-only; nothing persists.",
|
|
108
|
+
},
|
|
109
|
+
"checklist-public-pages-stores-sellers-directories-store-art-stickers-tab-shows-items": {
|
|
110
|
+
roles: ["guest"],
|
|
111
|
+
startPage: "/stores/store-beyblade-arena/art",
|
|
112
|
+
steps: [
|
|
113
|
+
"Open /stores/store-beyblade-arena/art in a private window with no session.",
|
|
114
|
+
"Read the grid and every card title.",
|
|
115
|
+
"Check whether the items are art prints and sticker sheets rather than ordinary products.",
|
|
116
|
+
"Read the availability tabs and click the middle one.",
|
|
117
|
+
],
|
|
118
|
+
expectedBehaviour: "Art and stickers are real listing types with their own filter value. Adding a type to the union and to the plugin registry is not enough — it must also be in the repository's filter-alias map, and a type missing there makes the alias return an empty string that is then dropped, so the query runs with NO listing-type filter and returns everything.",
|
|
119
|
+
expectedUiState: "The grid holds art prints and sticker sheets — 'Dranzer Phoenix Rising — Fan Art Poster' and similar — and not ordinary Beyblade products. It is not an empty grid. The middle availability tab shows the sold-out art fixture.",
|
|
120
|
+
expectedData: { ordinaryProductsInArtTab: 0 },
|
|
121
|
+
endResult: "Read-only; nothing persists. A grid full of ordinary products is the dropped-filter failure; an empty grid is a different one.",
|
|
122
|
+
},
|
|
123
|
+
"checklist-public-pages-stores-sellers-directories-store-tab-counts-match-contents": {
|
|
124
|
+
roles: ["guest"],
|
|
125
|
+
startPage: "/stores/store-beyblade-arena",
|
|
126
|
+
steps: [
|
|
127
|
+
"Open /stores/store-beyblade-arena in a private window.",
|
|
128
|
+
"Write down the count badge on each of Products, Auctions, Pre-Orders, Prize Draws, Classifieds, Digital Codes, Live Items and Art & Stickers.",
|
|
129
|
+
"Open each of those tabs and count the items, paging to the end of each.",
|
|
130
|
+
"Compare each pair and note any mismatch.",
|
|
131
|
+
],
|
|
132
|
+
expectedBehaviour: "Each badge is computed from the same query its tab runs, under the same availability scope. A badge counted without the availability filter over-reports by every sold or ended row.",
|
|
133
|
+
expectedUiState: "All eight badges match their tab contents. A badge that counts sold-out items the Available tab then hides is the most likely mismatch and is still a mismatch.",
|
|
134
|
+
expectedData: { mismatchedBadgeCount: 0 },
|
|
135
|
+
endResult: "Read-only; nothing persists.",
|
|
136
|
+
},
|
|
137
|
+
"checklist-public-pages-stores-sellers-directories-store-tab-sort-survives-reload": {
|
|
138
|
+
roles: ["guest"],
|
|
139
|
+
startPage: "/stores/store-beyblade-arena/auctions",
|
|
140
|
+
steps: [
|
|
141
|
+
"Open /stores/store-beyblade-arena/auctions in a private window.",
|
|
142
|
+
"Read the sort dropdown's selection and the order of the cards.",
|
|
143
|
+
"Change the sort to a different option.",
|
|
144
|
+
"Read the new card order and the URL.",
|
|
145
|
+
"Reload the page.",
|
|
146
|
+
"Read the sort dropdown's selection and the card order again, before touching anything.",
|
|
147
|
+
],
|
|
148
|
+
expectedBehaviour: "Sort lives in the URL, so the server's first paint and the dropdown agree. When the server renders a default the client does not share, the first paint shows one order and the dropdown claims another — and because the client caches the server's data indefinitely, the disagreement never resolves itself.",
|
|
149
|
+
expectedUiState: "After the reload the dropdown shows the chosen sort AND the cards are in that order on first paint — not the default order that then re-sorts a moment later.",
|
|
150
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
151
|
+
},
|
|
152
|
+
"checklist-public-pages-stores-sellers-directories-store-preorders-tab-default-sort": {
|
|
153
|
+
roles: ["guest"],
|
|
154
|
+
startPage: "/stores/store-beyblade-arena/pre-orders",
|
|
155
|
+
steps: [
|
|
156
|
+
"Open /pre-orders in a private window and read the sort dropdown's default selection.",
|
|
157
|
+
"Open /stores/store-beyblade-arena/pre-orders and read its sort dropdown's default selection.",
|
|
158
|
+
"Compare the two.",
|
|
159
|
+
"Read the delivery dates on the store tab's cards from the top down.",
|
|
160
|
+
],
|
|
161
|
+
expectedBehaviour: "Both surfaces derive their sort options and default from the listing type's own plugin, so they cannot disagree. Store tabs once carried local shadow copies of the sort array which had drifted in both labels and default, so the same data opened newest-first in one place and earliest-delivery-first in the other.",
|
|
162
|
+
expectedUiState: "Both dropdowns show earliest-delivery-first. The store tab's dates ascend down the page. Two different defaults for the same listing type is the failure.",
|
|
163
|
+
endResult: "Read-only; nothing persists.",
|
|
164
|
+
},
|
|
165
|
+
"checklist-public-pages-stores-sellers-directories-store-classified-live-facets-filter": {
|
|
166
|
+
roles: ["guest"],
|
|
167
|
+
startPage: "/stores/store-beyblade-arena/classified",
|
|
168
|
+
steps: [
|
|
169
|
+
"Open /stores/store-beyblade-arena/classified in a private window and read the result count.",
|
|
170
|
+
"Open the filters and select the city Mumbai, then apply.",
|
|
171
|
+
"Read the result count and each card's city.",
|
|
172
|
+
"Clear that, tick 'negotiable', apply, and read the count.",
|
|
173
|
+
"Clear that, tick 'accepts shipping', apply, and read the count.",
|
|
174
|
+
"Open the store's Live Items tab and repeat with the species, sex and jurisdiction facets.",
|
|
175
|
+
],
|
|
176
|
+
inputs: { city: "Mumbai" },
|
|
177
|
+
expectedBehaviour: "Per-type facets reach the query. A facet can render, count toward the filter badge and change nothing at all — that happens when it emits a field the query allowlist does not carry, or carries a field the document does not have, and neither failure raises anything.",
|
|
178
|
+
expectedUiState: "Every facet visibly changes the result count and the cards shown. Selecting Mumbai leaves only Mumbai listings. A facet that leaves the count identical while the filter badge increments is the exact failure.",
|
|
179
|
+
expectedData: { inertFacetCount: 0 },
|
|
180
|
+
endResult: "Read-only; nothing persists beyond the URL.",
|
|
181
|
+
},
|
|
182
|
+
"checklist-public-pages-stores-sellers-directories-store-tab-empty-state-not-error": {
|
|
183
|
+
roles: ["guest"],
|
|
184
|
+
startPage: "/stores/store-vintage-vault-co",
|
|
185
|
+
steps: [
|
|
186
|
+
"Open /stores/store-vintage-vault-co in a private window with no session.",
|
|
187
|
+
"Open every tab offered and find one that is genuinely empty.",
|
|
188
|
+
"Read exactly what is shown in that empty tab.",
|
|
189
|
+
"Wait 10 seconds and read it again.",
|
|
190
|
+
"Check for any error toast anywhere on the page.",
|
|
191
|
+
],
|
|
192
|
+
expectedBehaviour: "An empty tab shows a named empty state. The two failure modes to separate are a spinner that never resolves — which is what a data fetch that neither succeeds nor reports failure looks like — and a missing-index error surfaced as a toast, which is a real backend fault dressed as a UI hiccup.",
|
|
193
|
+
expectedUiState: "The empty tab shows a friendly message inside the normal layout. Not a blank white area, not a spinner still turning after 10 seconds, and no toast mentioning an index or a failed precondition.",
|
|
194
|
+
endResult: "Read-only; nothing persists.",
|
|
195
|
+
},
|
|
196
|
+
"checklist-public-pages-stores-sellers-directories-sellers-directory": {
|
|
197
|
+
roles: ["guest"],
|
|
198
|
+
startPage: "/sellers",
|
|
199
|
+
steps: [
|
|
200
|
+
"Open /sellers in a private window with no session.",
|
|
201
|
+
"Read every seller card — name, avatar and any stats.",
|
|
202
|
+
"Search the page source for an email address and for a phone number.",
|
|
203
|
+
"Click into one seller and read where it lands.",
|
|
204
|
+
],
|
|
205
|
+
expectedBehaviour: "The directory lists sellers with public-facing detail only. Email and phone are PII-encrypted at rest and have no place on a public directory in any form.",
|
|
206
|
+
expectedUiState: "Cards render with names and avatars. Neither the rendered page nor its source contains an email address or a phone number. Each card links to a real seller page rather than a 404.",
|
|
207
|
+
expectedData: { piiInSource: 0 },
|
|
208
|
+
endResult: "Read-only; nothing persists.",
|
|
209
|
+
},
|
|
210
|
+
"checklist-public-pages-stores-sellers-directories-seller-detail-page": {
|
|
211
|
+
roles: ["guest"],
|
|
212
|
+
startPage: "/stores/store-tester-qa-seller",
|
|
213
|
+
steps: [
|
|
214
|
+
"Sign in as tester@letitrip.in / TempPass123! so sandbox content is visible.",
|
|
215
|
+
"Open /stores/store-tester-qa-seller.",
|
|
216
|
+
"Read the header, the tabs and the listings.",
|
|
217
|
+
"Open the store's own listing-type dropdown, if it offers one, and select each option in turn.",
|
|
218
|
+
"Note any option that returns nothing.",
|
|
219
|
+
],
|
|
220
|
+
inputs: { storeId: "store-tester-qa-seller" },
|
|
221
|
+
expectedBehaviour: "This store backs the tester programme and carries at least one fixture of every listing type — the art and stickers pair were added specifically so the type dropdown has real data on every option rather than several that silently return nothing.",
|
|
222
|
+
expectedUiState: "The page renders with its header and tabs. Every option in the listing-type dropdown returns at least one item. An option that returns nothing means either the fixture is missing or that type is being dropped from the query.",
|
|
223
|
+
expectedData: { emptyTypeOptionCount: 0 },
|
|
224
|
+
endResult: "Read-only; nothing persists.",
|
|
225
|
+
},
|
|
226
|
+
"checklist-public-pages-stores-sellers-directories-scams-registry": {
|
|
227
|
+
roles: ["guest"],
|
|
228
|
+
startPage: "/scams",
|
|
229
|
+
steps: [
|
|
230
|
+
"Open /scams in a private window with no session.",
|
|
231
|
+
"Read the list and the filters offered.",
|
|
232
|
+
"Select each status filter value in turn and read the results.",
|
|
233
|
+
"Open one scammer profile and read its fields.",
|
|
234
|
+
"Search that page's source for any unmasked full phone number or email.",
|
|
235
|
+
],
|
|
236
|
+
expectedBehaviour: "The registry lists reported profiles with filters whose values match the real stored status set. A filter chip whose value is not a real stored status returns zero rows forever with no error — the comparison is byte-exact, so a wrong word or wrong case is a permanently empty chip.",
|
|
237
|
+
expectedUiState: "Every status filter value returns rows or a named empty state, and at least one returns rows. The profile page shows the report detail. Identifiers are masked rather than published in full.",
|
|
238
|
+
endResult: "Read-only; nothing persists.",
|
|
239
|
+
},
|
|
240
|
+
"checklist-public-pages-stores-sellers-directories-scam-related-profiles-sections": {
|
|
241
|
+
roles: ["guest"],
|
|
242
|
+
startPage: "/scams",
|
|
243
|
+
steps: [
|
|
244
|
+
"Open /scams in a private window and open a scammer profile that has cross-links.",
|
|
245
|
+
"Find the 'Related Profiles' section and read its entries.",
|
|
246
|
+
"Find the separately-labelled 'Similar Scam Reports' section and read its entries.",
|
|
247
|
+
"Check that the two sections are distinct and separately headed.",
|
|
248
|
+
"Check whether the current profile appears in either.",
|
|
249
|
+
],
|
|
250
|
+
expectedBehaviour: "Same-identity cross-links and same-pattern matches are two different claims and must never be merged. 'Related Profiles' asserts these are the same person; 'Similar Scam Reports' asserts only that the reports share a scam type. Presenting the second as the first accuses someone of being a person they are not.",
|
|
251
|
+
expectedUiState: "Two sections with distinct headings. Related Profiles holds only explicit cross-links; Similar Scam Reports holds same-type matches. Neither includes the profile currently open.",
|
|
252
|
+
expectedData: { selfLinkCount: 0 },
|
|
253
|
+
endResult: "Read-only; nothing persists. One merged section is the failure even if every entry in it is individually correct.",
|
|
254
|
+
},
|
|
255
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the search-and-nav/employee-permissions 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
|
+
* 🛑 THE SEED ALREADY HAS BOTH EMPLOYEE PERSONAS — user-employee-blog carries the
|
|
10
|
+
* blog_poster permission and user-employee-trust carries trust_and_safety. Neither
|
|
11
|
+
* case needs to invite anyone; signing in as them is the whole setup. The `users`
|
|
12
|
+
* collection is PRESERVED by a tester run, so they survive teardown, but a fresh
|
|
13
|
+
* project needs `npx appkit-seed load --collections users` once before they exist.
|
|
14
|
+
*
|
|
15
|
+
* @tag domain:tester
|
|
16
|
+
* @tag layer:seed
|
|
17
|
+
* @tag pattern:none
|
|
18
|
+
* @tag access:server-only
|
|
19
|
+
* @tag consumers:seed-data/authored/index.ts
|
|
20
|
+
* @tag sideEffects:none
|
|
21
|
+
*/
|
|
22
|
+
export const authored = {
|
|
23
|
+
"checklist-search-and-nav-employee-permissions-employee-sees-only-their-permissions": {
|
|
24
|
+
roles: ["employee", "admin"],
|
|
25
|
+
startPage: "/admin",
|
|
26
|
+
steps: [
|
|
27
|
+
"Sign in as employee-blog@letitrip.in / TempPass123!.",
|
|
28
|
+
"Open /admin and count every entry in the sidebar.",
|
|
29
|
+
"Read every group heading that is present.",
|
|
30
|
+
"Look specifically for Finance, Procurement, Catalog, Testing, Site, Events, Trust & Safety, System and Maintenance.",
|
|
31
|
+
"Sign out and sign in as employee-trust@letitrip.in / TempPass123!.",
|
|
32
|
+
"Open /admin and count the sidebar entries again.",
|
|
33
|
+
"Sign out and sign in as admin@letitrip.in / TempPass123!, then open /admin and count the entries.",
|
|
34
|
+
],
|
|
35
|
+
inputs: { blogEmployee: "employee-blog@letitrip.in", trustEmployee: "employee-trust@letitrip.in" },
|
|
36
|
+
expectedBehaviour: "Nav filtering keys on each item's own id to look up its required permission. The filter short-circuits when an item has no id, and for a long time no item had one — so all 91 entries passed for everybody and every requiredPermission in the config was decorative. A group left with no visible children is removed entirely rather than rendering an empty heading.",
|
|
37
|
+
expectedUiState: "The blog employee sees roughly five entries, not 91. Finance, Procurement, Catalog, Testing, Site, Events, Trust & Safety, System and Maintenance are absent as headings, not present-and-empty. The trust employee sees a different set, roughly 24. The admin sees everything. Three genuinely different counts is the pass; three identical counts is the exact bug.",
|
|
38
|
+
expectedData: { blogEntriesApprox: 5, trustEntriesApprox: 24 },
|
|
39
|
+
endResult: "Read-only; nothing persists. Comparing two presets against each other AND against admin is what distinguishes real filtering from a filter that happens to hide the same fixed set from everyone.",
|
|
40
|
+
},
|
|
41
|
+
"checklist-search-and-nav-employee-permissions-employee-sidebar-never-empty": {
|
|
42
|
+
roles: ["admin", "employee"],
|
|
43
|
+
startPage: "/admin/team",
|
|
44
|
+
steps: [
|
|
45
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
46
|
+
"Open /admin/team and open the editor for employee-blog@letitrip.in.",
|
|
47
|
+
"Read every permission preset the editor offers and write the list down.",
|
|
48
|
+
"Set the account to the first preset and save.",
|
|
49
|
+
"Sign out, sign in as employee-blog@letitrip.in / TempPass123!, open /admin and count the sidebar entries.",
|
|
50
|
+
"Repeat for every remaining preset: set it as admin, then sign in as the employee and count.",
|
|
51
|
+
"Set the account back to the blog poster preset as the last step.",
|
|
52
|
+
],
|
|
53
|
+
inputs: { employee: "employee-blog@letitrip.in" },
|
|
54
|
+
expectedBehaviour: "No preset produces a completely blank sidebar. At minimum every employee reaches the dashboard itself, so the portal is navigable from the moment they sign in.",
|
|
55
|
+
expectedUiState: "For every preset, at least one entry is visible in the sidebar. A blank sidebar is the failure — an employee cannot tell it from a broken account and will report it as one, which is a support ticket the permission system caused rather than prevented.",
|
|
56
|
+
expectedData: { minimumVisibleEntries: 1 },
|
|
57
|
+
endResult: "The account is back on the blog poster preset, which the case above depends on. Leaving it on another preset silently breaks that case's expected count of roughly five.",
|
|
58
|
+
},
|
|
59
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the search-and-nav/header-search page.
|
|
3
|
+
* WHAT: 4 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 one of these searches for a word that does NOT appear in the label of
|
|
10
|
+
* what it should find. That is the point of the whole page: matching labels is
|
|
11
|
+
* the behaviour being replaced, so a query whose answer is in its own label
|
|
12
|
+
* cannot tell the two apart.
|
|
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-search-and-nav-header-search-search-finds-maintenance-toggle": {
|
|
23
|
+
roles: ["admin"],
|
|
24
|
+
startPage: "/",
|
|
25
|
+
steps: [
|
|
26
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
27
|
+
"Open / and click into the header search.",
|
|
28
|
+
"Type maintenance.",
|
|
29
|
+
"Read the results.",
|
|
30
|
+
"Click the maintenance quick link.",
|
|
31
|
+
"Read which tab of Site Settings is open and what is on screen.",
|
|
32
|
+
],
|
|
33
|
+
inputs: { query: "maintenance" },
|
|
34
|
+
expectedBehaviour: "Search reaches individual SETTINGS, not just screens. No nav item is called Maintenance, so a label-matching search returns nothing for this word — and the toggle lives on tab one of nineteen with no way to find it but hunting.",
|
|
35
|
+
expectedUiState: "A quick link for maintenance appears in the results. Clicking it opens Site Settings on the Branding tab with the Maintenance mode toggle scrolled into view. Landing on Site Settings' first tab with the toggle somewhere off screen is a FAIL, not a partial pass.",
|
|
36
|
+
expectedData: { resultCount: 1 },
|
|
37
|
+
endResult: "Read-only; do not flip the toggle. Turning on maintenance mode would take the site down for every other case in the run.",
|
|
38
|
+
},
|
|
39
|
+
"checklist-search-and-nav-header-search-search-finds-by-what-it-does": {
|
|
40
|
+
roles: ["admin"],
|
|
41
|
+
startPage: "/",
|
|
42
|
+
steps: [
|
|
43
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
44
|
+
"Open / and click into the header search.",
|
|
45
|
+
"Type refund and read the results.",
|
|
46
|
+
"Clear the box, type postcode and read the results.",
|
|
47
|
+
"Clear the box, type cod and read the results.",
|
|
48
|
+
"Clear the box, type zzzznope and read the results.",
|
|
49
|
+
],
|
|
50
|
+
inputs: { query1: "refund", query2: "postcode", query3: "cod", nonsenseQuery: "zzzznope" },
|
|
51
|
+
expectedBehaviour: "Entries carry a description and keywords, so a user who knows what they want to DO finds the screen without knowing what it is called. None of these three words appears in the label of what it finds.",
|
|
52
|
+
expectedUiState: "'refund' returns Payouts. 'postcode' returns Addresses. 'cod' returns the Cash on delivery toggle. 'zzzznope' returns an empty state — the control that proves the box is matching rather than listing everything.",
|
|
53
|
+
expectedData: { nonsenseResultCount: 0 },
|
|
54
|
+
endResult: "Read-only; nothing persists.",
|
|
55
|
+
},
|
|
56
|
+
"checklist-search-and-nav-header-search-search-ranks-exact-first": {
|
|
57
|
+
roles: ["admin"],
|
|
58
|
+
startPage: "/",
|
|
59
|
+
steps: [
|
|
60
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
61
|
+
"Open / and click into the header search.",
|
|
62
|
+
"Type orders.",
|
|
63
|
+
"Read the results in order from the top.",
|
|
64
|
+
],
|
|
65
|
+
inputs: { query: "orders" },
|
|
66
|
+
expectedBehaviour: "An exact label match outranks an entry that merely mentions the word in its description. With no ranking at all the results fall into alphabetical order and the thing actually called Orders can land ninth.",
|
|
67
|
+
expectedUiState: "The entry named Orders is first. Guides and settings whose descriptions mention orders appear below it. Orders appearing anywhere but first is the failure, even though it is present.",
|
|
68
|
+
expectedData: { exactMatchPosition: 1 },
|
|
69
|
+
endResult: "Read-only; nothing persists.",
|
|
70
|
+
},
|
|
71
|
+
"checklist-search-and-nav-header-search-search-never-shows-what-you-cannot-reach": {
|
|
72
|
+
roles: ["buyer"],
|
|
73
|
+
startPage: "/",
|
|
74
|
+
steps: [
|
|
75
|
+
"Sign in as rehan.sheikh@gmail.com / TempPass123!, an ordinary buyer.",
|
|
76
|
+
"Open / and click into the header search.",
|
|
77
|
+
"Type users and read every result.",
|
|
78
|
+
"Clear the box, type payouts and read every result.",
|
|
79
|
+
"Clear the box, type maintenance and read every result.",
|
|
80
|
+
"Clear the box, type orders and read every result.",
|
|
81
|
+
],
|
|
82
|
+
inputs: { query1: "users", query2: "payouts", query3: "maintenance", query4: "orders" },
|
|
83
|
+
expectedBehaviour: "Results are filtered by what this viewer may actually reach. The labels alone are a site map of the admin panel, so an entry a buyer cannot open is one they must not be shown — hiding the destination behind a 403 is not enough.",
|
|
84
|
+
expectedUiState: "'users', 'payouts' and 'maintenance' return no admin entries at all — not greyed out, not present-but-unclickable, absent. 'orders' still returns the buyer's OWN orders page, which proves the filter is scoping rather than simply returning nothing.",
|
|
85
|
+
expectedData: { adminResultsForBuyer: 0 },
|
|
86
|
+
endResult: "Read-only; nothing persists. The fourth query is the control — a search that returned nothing for everything would pass the first three for the wrong reason.",
|
|
87
|
+
},
|
|
88
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Authored six-part procedures for the search-and-nav/settings-deep-links 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
|
+
* @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-search-and-nav-settings-deep-links-tab-query-param-opens-that-tab": {
|
|
18
|
+
roles: ["admin"],
|
|
19
|
+
startPage: "/admin/site",
|
|
20
|
+
steps: [
|
|
21
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
22
|
+
"Open /admin/site?tab=fees directly in the address bar.",
|
|
23
|
+
"Read which tab is selected.",
|
|
24
|
+
"Open /admin/site?tab=themes directly.",
|
|
25
|
+
"Read which tab is selected.",
|
|
26
|
+
"Open /admin/site with no query parameter.",
|
|
27
|
+
"Read which tab is selected.",
|
|
28
|
+
],
|
|
29
|
+
inputs: { tab1: "fees", tab2: "themes" },
|
|
30
|
+
expectedBehaviour: "The open tab is read from the URL, so a deep link — from search, from a guide, from a colleague's message — lands where it says it will. A page that hard-codes its default ignores the URL entirely and every such link arrives on tab one.",
|
|
31
|
+
expectedUiState: "?tab=fees opens the Fees tab with its fields on screen. ?tab=themes opens Themes. With no parameter the page opens on Branding. Two different parameters producing the same tab means the URL is not being read.",
|
|
32
|
+
expectedData: { defaultTab: "branding" },
|
|
33
|
+
endResult: "Read-only; do not save anything. Nothing persists from opening a tab.",
|
|
34
|
+
},
|
|
35
|
+
"checklist-search-and-nav-settings-deep-links-unknown-tab-falls-back-quietly": {
|
|
36
|
+
roles: ["admin"],
|
|
37
|
+
startPage: "/admin/site",
|
|
38
|
+
steps: [
|
|
39
|
+
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
40
|
+
"Open /admin/site?tab=nonsense directly in the address bar.",
|
|
41
|
+
"Read which tab is selected and look for any error.",
|
|
42
|
+
"Open /admin/site?tab= with an empty value.",
|
|
43
|
+
"Read which tab is selected.",
|
|
44
|
+
],
|
|
45
|
+
inputs: { unknownTab: "nonsense" },
|
|
46
|
+
expectedBehaviour: "An unrecognised tab value falls back to the default without complaint. The realistic cause is a stale bookmark from a tab that has since been renamed, and that is not an error condition — it is a page whose shape changed.",
|
|
47
|
+
expectedUiState: "Both URLs open Branding. No error banner, no toast, no empty tab strip and no blank panel. A rejected value must not look like a broken page.",
|
|
48
|
+
expectedData: { fallbackTab: "branding" },
|
|
49
|
+
endResult: "Read-only; nothing persists.",
|
|
50
|
+
},
|
|
51
|
+
};
|