@mohasinac/appkit 4.37.1 → 4.39.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/digital-code/CodeRevealPanel.d.ts +20 -1
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +21 -1
- package/dist/_internal/client/features/digital-code/DigitalContentPoolManager.d.ts +40 -0
- package/dist/_internal/client/features/digital-code/DigitalContentPoolManager.js +67 -0
- package/dist/_internal/server/features/bundles/og.d.ts +0 -1
- package/dist/_internal/server/features/bundles/og.js +2 -18
- package/dist/_internal/server/features/catalogue/og.d.ts +0 -1
- package/dist/_internal/server/features/catalogue/og.js +1 -9
- package/dist/_internal/server/features/checkout/actions.js +18 -0
- package/dist/_internal/server/features/classified/og.d.ts +0 -1
- package/dist/_internal/server/features/classified/og.js +1 -9
- package/dist/_internal/server/features/digital-code/download.d.ts +60 -0
- package/dist/_internal/server/features/digital-code/download.js +128 -0
- package/dist/_internal/server/features/digital-code/og.d.ts +0 -1
- package/dist/_internal/server/features/digital-code/og.js +1 -9
- package/dist/_internal/server/features/digital-code/pool.d.ts +101 -0
- package/dist/_internal/server/features/digital-code/pool.js +208 -0
- package/dist/_internal/server/features/digital-code/upload.d.ts +51 -0
- package/dist/_internal/server/features/digital-code/upload.js +144 -0
- package/dist/_internal/server/features/grouped/og.d.ts +7 -4
- package/dist/_internal/server/features/grouped/og.js +7 -6
- package/dist/_internal/server/features/item-requests/og.d.ts +0 -1
- package/dist/_internal/server/features/item-requests/og.js +2 -18
- package/dist/_internal/server/features/live/og.d.ts +0 -1
- package/dist/_internal/server/features/live/og.js +1 -9
- package/dist/_internal/server/features/prize-draws/og.js +5 -10
- package/dist/_internal/server/features/products/og.js +5 -2
- package/dist/_internal/server/features/seo/sitemap.js +10 -2
- package/dist/_internal/server/features/shared/listing-adapters.d.ts +1 -2
- package/dist/_internal/server/features/shared/listing-adapters.js +5 -3
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +40 -0
- package/dist/_internal/server/jobs/core/countersReconcile.js +153 -40
- package/dist/_internal/server/jobs/core/onCategoryWrite.js +33 -0
- package/dist/_internal/server/jobs/core/onProductWrite.js +93 -25
- package/dist/_internal/server/notifications/send-recorder.d.ts +79 -0
- package/dist/_internal/server/notifications/send-recorder.js +126 -0
- package/dist/_internal/shared/listing-types/_registry.d.ts +31 -4
- package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/art/config.js +2 -0
- package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/auction/config.js +3 -0
- package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/classified/config.js +3 -0
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/digital-code/config.js +3 -0
- package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/live/config.js +3 -0
- package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/pre-order/config.js +2 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +3 -0
- package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/standard/config.js +2 -0
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/stickers/config.js +2 -0
- package/dist/client/observability/reportClientError.js +11 -1
- package/dist/client.d.ts +6 -0
- package/dist/client.js +10 -0
- package/dist/core/hooks/useSyncManager.js +11 -1
- package/dist/features/account/hooks/useNotifications.js +25 -5
- package/dist/features/auctions/components/AuctionBottomActions.js +10 -2
- package/dist/features/auctions/components/AuctionDetailPageView.js +12 -3
- package/dist/features/auctions/components/LiveBidPrice.js +2 -2
- package/dist/features/auctions/components/LiveMinIncrement.d.ts +1 -1
- package/dist/features/auctions/components/LiveMinIncrement.js +8 -0
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -3
- package/dist/features/auctions/components/PlaceBidFormClient.js +16 -1
- package/dist/features/auctions/hooks/useAuctions.js +12 -1
- package/dist/features/auctions/hooks/useRealtimeBids.d.ts +3 -0
- package/dist/features/auctions/hooks/useRealtimeBids.js +138 -36
- package/dist/features/blog/components/BlogIndexPageView.js +10 -1
- package/dist/features/blog/repository/blog.repository.d.ts +14 -0
- package/dist/features/blog/repository/blog.repository.js +23 -1
- package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +2 -2
- package/dist/features/catalogue/components/PublicCatalogueView.js +2 -2
- package/dist/features/categories/components/BundleCollage.js +10 -5
- package/dist/features/categories/components/BundleDetailView.js +7 -3
- package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoryProductsListing.js +4 -1
- package/dist/features/categories/components/CategoryTree.js +1 -1
- package/dist/features/categories/repository/categories.repository.d.ts +34 -2
- package/dist/features/categories/repository/categories.repository.js +31 -9
- package/dist/features/classified/components/ClassifiedDetailPageView.js +2 -2
- package/dist/features/contact/email.js +36 -1
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +2 -2
- package/dist/features/homepage/components/FeaturedBundlesSection.js +4 -4
- package/dist/features/live/components/LiveItemDetailPageView.js +2 -2
- package/dist/features/orders/repository/orders.repository.d.ts +21 -1
- package/dist/features/orders/repository/orders.repository.js +26 -9
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -3
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +2 -2
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -2
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +4 -1
- package/dist/features/products/actions/product-actions.d.ts +9 -0
- package/dist/features/products/actions/product-actions.js +11 -0
- package/dist/features/products/columns/productTableColumns.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +4 -1
- package/dist/features/products/components/BidHistory.js +2 -2
- package/dist/features/products/components/CompareOverlay.js +2 -2
- package/dist/features/products/components/GroupMemberPicker.js +5 -5
- package/dist/features/products/components/ListingBottomActions.js +12 -3
- package/dist/features/products/components/MakeOfferButton.js +7 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +4 -4
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -2
- package/dist/features/products/components/PrizeDrawCollage.js +16 -5
- package/dist/features/products/components/PrizeDrawEntryActions.js +2 -2
- package/dist/features/products/components/PrizeDrawsIndexListing.js +4 -1
- package/dist/features/products/components/PrizeRevealModal.js +2 -2
- package/dist/features/products/components/ProductDetailActions.js +10 -3
- package/dist/features/products/components/ProductFilters.js +2 -2
- package/dist/features/products/components/ProductGrid.js +5 -2
- package/dist/features/products/components/ProductsIndexListing.js +12 -1
- package/dist/features/products/components/ProductsIndexPageView.js +26 -0
- package/dist/features/products/components/ShowGroupSection.js +2 -2
- package/dist/features/products/components/SublistingCarouselSection.js +2 -2
- package/dist/features/products/constants/listing-tabs.d.ts +36 -12
- package/dist/features/products/constants/listing-tabs.js +38 -14
- package/dist/features/products/constants/sieve.d.ts +14 -0
- package/dist/features/products/constants/sieve.js +39 -0
- package/dist/features/products/repository/products.repository.d.ts +35 -0
- package/dist/features/products/repository/products.repository.js +116 -3
- package/dist/features/products/schemas/firestore.d.ts +37 -0
- package/dist/features/seller/actions/seller-actions.js +4 -13
- package/dist/features/seller/components/SellerProductShell.d.ts +7 -1
- package/dist/features/seller/components/SellerProductShell.js +11 -2
- package/dist/features/stores/api/[storeSlug]/reviews/route.d.ts +6 -1
- package/dist/features/stores/api/[storeSlug]/reviews/route.js +89 -30
- package/dist/features/stores/components/StoresIndexPageView.js +17 -1
- package/dist/features/tester/seed-data/authored/admin__users-trust.js +1 -1
- package/dist/features/tester/seed-data/authored/buying__bidding.js +5 -4
- package/dist/features/tester/seed-data/authored/buying__browsing-search.js +85 -85
- package/dist/features/tester/seed-data/authored/buying__image-tile-layout.js +2 -2
- package/dist/features/tester/seed-data/authored/buying__offers.js +1 -1
- package/dist/features/tester/seed-data/authored/buying__product-detail.js +53 -15
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.js +6 -6
- package/dist/features/tester/seed-data/authored/content-discovery__search.js +6 -4
- package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.js +4 -4
- package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.js +2 -2
- package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.js +4 -4
- package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.js +8 -8
- package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.js +8 -8
- package/dist/features/tester/seed-data/authored/seo__canonical-and-host.js +16 -0
- package/dist/features/tester/seed-data/authored/seo__og-images.js +17 -0
- package/dist/features/tester/seed-data/stores-tester-seed-data.js +41 -2
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +36 -6
- package/dist/features/tester/utils/phases.js +78 -12
- package/dist/features/wishlist/components/WishlistPage.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -1
- package/dist/providers/db-firebase/rtdb-paths.d.ts +7 -0
- package/dist/providers/db-firebase/rtdb-paths.js +7 -0
- package/dist/react/contexts/SessionContext.js +40 -1
- package/dist/react/hooks/useCanSeePrices.d.ts +37 -0
- package/dist/react/hooks/useCanSeePrices.js +40 -0
- package/dist/seed/addresses-seed-data.js +36 -2
- package/dist/seed/users-seed-data.js +10 -2
- package/dist/seo/json-ld.d.ts +21 -0
- package/dist/seo/json-ld.js +45 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.js +12 -0
- package/dist/styles.css +41 -0
- package/dist/ui/components/FilePickerButton.d.ts +32 -0
- package/dist/ui/components/FilePickerButton.js +23 -0
- package/dist/ui/components/GatedPrice.d.ts +66 -0
- package/dist/ui/components/GatedPrice.js +80 -0
- package/dist/ui/components/GatedPrice.style.css +40 -0
- package/dist/ui/components/PriceDisplay.d.ts +12 -0
- package/dist/ui/components/PriceDisplay.js +17 -17
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +8 -0
- package/package.json +1 -1
|
@@ -49,14 +49,14 @@ export const authored = {
|
|
|
49
49
|
steps: [
|
|
50
50
|
"Open /bundles in a private window at 1280 pixels wide.",
|
|
51
51
|
"Look at each bundle card's discount badge and where it sits on the card.",
|
|
52
|
-
"Check the badge does not cover the bundle's title or price.",
|
|
52
|
+
"Check the badge does not cover the bundle's title or price row.",
|
|
53
53
|
"Read the badge's text against its background.",
|
|
54
54
|
"Resize to 390 pixels and look at the badges again.",
|
|
55
55
|
"Switch to dark mode and read them once more.",
|
|
56
56
|
],
|
|
57
57
|
inputs: { desktopWidth: 1280, mobileWidth: 390 },
|
|
58
58
|
expectedBehaviour: "The badge overlays the card image, so it takes the solid pairing — a fill with its own on-solid ink — rather than a pale tint. A tint over an arbitrary product photograph is unreadable regardless of theme, and a literal white ink against a theme-inverting background is invisible in exactly one of the two.",
|
|
59
|
-
expectedUiState: "Every badge is readable at both widths and in both themes, and none covers the title or price. A visible badge shape with unreadable text inside it is the failure.",
|
|
59
|
+
expectedUiState: "Every badge is readable at both widths and in both themes, and none covers the title or price row. A visible badge shape with unreadable text inside it is the failure.",
|
|
60
60
|
endResult: "Read-only; return the site to light mode and restore the width.",
|
|
61
61
|
},
|
|
62
62
|
"checklist-buying-image-tile-layout-bundle-tile-opens-lightbox": {
|
|
@@ -468,7 +468,7 @@ export const authored = {
|
|
|
468
468
|
},
|
|
469
469
|
"checklist-buying-offers-ticket-resolution-timestamp-stamped": {
|
|
470
470
|
roles: ["admin"],
|
|
471
|
-
startPage: "/admin/support",
|
|
471
|
+
startPage: "/admin/support-tickets",
|
|
472
472
|
steps: [
|
|
473
473
|
"Sign in as admin@letitrip.in / TempPass123!.",
|
|
474
474
|
"Open the admin support tickets surface and open an open ticket.",
|
|
@@ -27,11 +27,23 @@ export const authored = {
|
|
|
27
27
|
"Wait 3 seconds without touching anything.",
|
|
28
28
|
"Read the countdown again.",
|
|
29
29
|
],
|
|
30
|
-
expectedBehaviour: "The page renders a live auction whose countdown ticks client-side against the stored end date. Auction listings offer bidding, never Add to Cart — the capability is per listing type, not a styling choice.",
|
|
31
|
-
expectedUiState: "The heading names the sandbox auction. A countdown in the shape '47m 06s' or 'Xd Xh Xm Xs' sits next to 'Place a bid', and its seconds figure is lower after the 3-second wait — a frozen countdown is a fail even though the number looks plausible.
|
|
32
|
-
expectedData: { currentBid: 15000, minIncrement: 1000 },
|
|
30
|
+
expectedBehaviour: "The page renders a live auction whose countdown ticks client-side against the stored end date. Auction listings offer bidding, never Add to Cart — the capability is per listing type, not a styling choice. A signed-out visitor sees no bid figures at all: a current bid is a money amount like any other, and the bid panel is replaced rather than shown with the numbers blanked.",
|
|
31
|
+
expectedUiState: "BEFORE: 'Current bid ₹15,000.00' and 'minimum increment ₹1,000.00' were shown to anyone. AFTER: the current-bid line reads 'Sign in to see the current bid', the minimum-increment line is absent, and the bid panel reads 'Bidding is for members' with a 'Sign in to bid' link. The digits 15,000 and 1,000 appear nowhere on the page. The heading names the sandbox auction. A countdown in the shape '47m 06s' or 'Xd Xh Xm Xs' sits next to 'Place a bid', and its seconds figure is lower after the 3-second wait — a frozen countdown is a fail even though the number looks plausible. There is no 'Add to Cart' button anywhere on the page.",
|
|
33
32
|
endResult: "Nothing persists — bid state and end time are read from the server on each load. The seconds figure moving is the whole check.",
|
|
34
33
|
},
|
|
34
|
+
"checklist-buying-product-detail-auction-detail-bid-signed-in": {
|
|
35
|
+
roles: ["buyer"],
|
|
36
|
+
startPage: "/auctions/auction-tester-sandbox-cycle-1",
|
|
37
|
+
steps: [
|
|
38
|
+
"Sign in as a buyer.",
|
|
39
|
+
"Open /auctions/auction-tester-sandbox-cycle-1.",
|
|
40
|
+
"Read the current bid, the minimum increment and the bid panel.",
|
|
41
|
+
],
|
|
42
|
+
expectedBehaviour: "The twin of the guest case above — the bid figures and the working bid form are exactly what the gate must not cost a signed-in buyer.",
|
|
43
|
+
expectedUiState: "'Current bid ₹15,000.00' is shown, a minimum increment of ₹1,000.00 is stated, and the bid panel carries a real amount input and a submit button. Neither 'Sign in to see the current bid' nor 'Bidding is for members' appears anywhere on the page.",
|
|
44
|
+
expectedData: { currentBid: 15000, minIncrement: 1000 },
|
|
45
|
+
endResult: "Nothing persists unless a bid is actually submitted, which this case does not do.",
|
|
46
|
+
},
|
|
35
47
|
"checklist-buying-product-detail-bundle-purchase": {
|
|
36
48
|
roles: ["buyer"],
|
|
37
49
|
startPage: "/bundles/bundle-tester-sandbox",
|
|
@@ -167,12 +179,11 @@ export const authored = {
|
|
|
167
179
|
startPage: "/live/live-tester-sandbox-1",
|
|
168
180
|
steps: [
|
|
169
181
|
"Open /live/live-tester-sandbox-1.",
|
|
170
|
-
"Read the heading, the species line, the price and the delivery restrictions.",
|
|
182
|
+
"Read the heading, the species line, the price area and the delivery restrictions.",
|
|
171
183
|
"Look at the gallery thumbnail strip.",
|
|
172
184
|
],
|
|
173
185
|
expectedBehaviour: "A live listing renders its species-specific fields — species, breed, sex, age and the jurisdiction restrictions — which no other listing type carries, and offers a cart path once those restrictions are satisfied.",
|
|
174
|
-
expectedUiState: "Heading 'Test Live Item — Golden Retriever Puppy'. A species line in the shape 'Dog (Golden Retriever) · male · 6mo'.
|
|
175
|
-
expectedData: { price: 1500 },
|
|
186
|
+
expectedUiState: "Heading 'Test Live Item — Golden Retriever Puppy'. A species line in the shape 'Dog (Golden Retriever) · male · 6mo'. BEFORE: the price read '₹1,500.00'; AFTER it reads 'Sign in to see price' and the digits 1,500 appear nowhere, and the 'Handling:' fee on the transport line is absent too. Delivery restrictions are stated rather than blank. The thumbnail strip carries a 'View video' entry alongside 'View image 1'. An 'Add to Cart' button is present.",
|
|
176
187
|
endResult: "Nothing persists — read-only for a guest.",
|
|
177
188
|
},
|
|
178
189
|
"checklist-buying-product-detail-live-item-video-mandatory": {
|
|
@@ -206,12 +217,11 @@ export const authored = {
|
|
|
206
217
|
startPage: "/pre-orders/preorder-tester-sandbox-1",
|
|
207
218
|
steps: [
|
|
208
219
|
"Open /pre-orders/preorder-tester-sandbox-1.",
|
|
209
|
-
"Read the heading, the price, the status badge and the delivery line.",
|
|
220
|
+
"Read the heading, the price area, the status badge and the delivery line.",
|
|
210
221
|
"Read the note beside the 'Reserve Now' button.",
|
|
211
222
|
],
|
|
212
223
|
expectedBehaviour: "A pre-order shows an estimated delivery date and takes a deposit rather than the full price, which is what distinguishes it from a standard listing that happens to be out of stock.",
|
|
213
|
-
expectedUiState: "Heading 'Test Pre-order — Reserve Me!'.
|
|
214
|
-
expectedData: { price: 299, depositAmount: 74.75 },
|
|
224
|
+
expectedUiState: "Heading 'Test Pre-order — Reserve Me!'. BEFORE: the price read '₹299.00' with a 'Reserve with ₹74.75' note; AFTER the price reads 'Sign in to see price', the deposit note is absent entirely, and neither 299 nor 74.75 appears anywhere on the page. An 'Estimated delivery:' label with an actual date beside it, not an empty value or the word 'undefined'. A 'Reserve Now' button is still present. Status badge 'In Production'.",
|
|
215
225
|
endResult: "Nothing persists — read-only for a guest.",
|
|
216
226
|
},
|
|
217
227
|
"checklist-buying-product-detail-prizedraw-buy-reveal": {
|
|
@@ -259,7 +269,7 @@ export const authored = {
|
|
|
259
269
|
"Read each carousel heading and look at the cards inside it.",
|
|
260
270
|
],
|
|
261
271
|
expectedBehaviour: "Four independent related-items signals are rendered — same category, same brand, shared tags, same store — each capped and each filtered for items that are still available, so an ended auction or a sold-out listing does not appear as a suggestion.",
|
|
262
|
-
expectedUiState: "Four carousel sections, in the shape 'More in this category', 'More by Beyblade', 'You might also like' and 'More from Beyblade Arena'. Each holds at least one card carrying a real title, a rendered image tile and a price. A heading with an empty rail beneath it is a fail — the section should not render at all rather than render empty.",
|
|
272
|
+
expectedUiState: "Four carousel sections, in the shape 'More in this category', 'More by Beyblade', 'You might also like' and 'More from Beyblade Arena'. Each holds at least one card carrying a real title, a rendered image tile and a price row — signed out that row reads 'Sign in to see price'. A heading with an empty rail beneath it is a fail — the section should not render at all rather than render empty.",
|
|
263
273
|
expectedData: { carouselCount: 4 },
|
|
264
274
|
endResult: "Nothing persists — read-only page.",
|
|
265
275
|
},
|
|
@@ -279,16 +289,44 @@ export const authored = {
|
|
|
279
289
|
roles: ["guest"],
|
|
280
290
|
startPage: "/products/product-tester-standard-1",
|
|
281
291
|
steps: [
|
|
282
|
-
"Open /products/product-tester-standard-1.",
|
|
283
|
-
"Read the heading, price, stock badge and description.",
|
|
292
|
+
"Open /products/product-tester-standard-1 in a private window with no session.",
|
|
293
|
+
"Read the heading, the price area, the stock badge and the description.",
|
|
284
294
|
"Read the category and brand links below the heading.",
|
|
285
295
|
"Read the seller line at the bottom of the info panel.",
|
|
286
296
|
],
|
|
287
|
-
expectedBehaviour: "A standard listing renders every panel a buyer needs to decide, and the purchase actions are present but inert for a signed-out visitor rather than absent — a missing button reads as a broken page, a disabled one reads as a prompt to sign in.",
|
|
288
|
-
expectedUiState: "Heading 'Test Gadget — Standard Listing #1'.
|
|
289
|
-
expectedData: {
|
|
297
|
+
expectedBehaviour: "A standard listing renders every panel a buyer needs to decide, and the purchase actions are present but inert for a signed-out visitor rather than absent — a missing button reads as a broken page, a disabled one reads as a prompt to sign in. The PRICE is not shown to a signed-out visitor at all: the catalogue must not be readable at scale without an account.",
|
|
298
|
+
expectedUiState: "BEFORE: the price area read '₹199.00'. AFTER: it reads 'Sign in to see price' and is a link to /auth/login; the digits 199 appear nowhere on the page. Heading 'Test Gadget — Standard Listing #1'. Stock badge in the shape '✓ In Stock — only 10 left' (stock is not an amount and is still shown). 'Buy Now', 'Add to Cart' and 'Add to Wishlist' are visible and disabled. Category links 'Test Gadgets' and 'Tester Sandbox' and brand link 'TestBrand' appear below the heading. A description paragraph is present. 'Sold by Tester Sandbox Store' with a 'Visit Store →' link is shown.",
|
|
299
|
+
expectedData: { stockQuantity: 10 },
|
|
290
300
|
endResult: "Nothing persists — read-only for a guest.",
|
|
291
301
|
},
|
|
302
|
+
"checklist-buying-product-detail-price-does-not-flash-sign-in-prompt-on-hard-reload": {
|
|
303
|
+
roles: ["buyer"],
|
|
304
|
+
startPage: "/products/product-tester-standard-1",
|
|
305
|
+
steps: [
|
|
306
|
+
"Sign in as a buyer.",
|
|
307
|
+
"Open /products/product-tester-standard-1 and confirm the price reads ₹199.00.",
|
|
308
|
+
"Press Ctrl+Shift+R (hard reload) and watch the price area continuously from the moment the page starts painting.",
|
|
309
|
+
"Repeat the hard reload twice more, watching the same area.",
|
|
310
|
+
"Throttle the network to 'Slow 3G' in the browser's network panel and hard-reload once more, watching the price area throughout.",
|
|
311
|
+
],
|
|
312
|
+
expectedBehaviour: "While the session is still resolving the price area shows a neutral placeholder, never the sign-in prompt. The prompt means 'you are signed out', and the session provider starts every hard load with no user and resolves asynchronously — so a two-state gate tells a signed-in buyer they are signed out on every single page load. The throttled reload is the real test: at full speed the window can be too short to see.",
|
|
313
|
+
expectedUiState: "Across all four reloads the price area goes from blank-or-placeholder straight to '₹199.00'. The text 'Sign in to see price' NEVER appears, not even for one frame, and most visibly not on the throttled load. A flash of the prompt before the price settles is the failure — the end state being correct does not pass this case.",
|
|
314
|
+
expectedData: { promptFlashes: 0 },
|
|
315
|
+
endResult: "Read-only; restore the network throttle to 'No throttling' afterwards.",
|
|
316
|
+
},
|
|
317
|
+
"checklist-buying-product-detail-standard-detail-price-signed-in": {
|
|
318
|
+
roles: ["buyer"],
|
|
319
|
+
startPage: "/products/product-tester-standard-1",
|
|
320
|
+
steps: [
|
|
321
|
+
"Sign in as a buyer.",
|
|
322
|
+
"Open /products/product-tester-standard-1.",
|
|
323
|
+
"Read the price area.",
|
|
324
|
+
],
|
|
325
|
+
expectedBehaviour: "The twin of the guest case above. Gating the price must not lose coverage of the price itself — a signed-in buyer sees the real amount, formatted as currency, with no sign-in prompt anywhere on the page.",
|
|
326
|
+
expectedUiState: "The price area reads '₹199.00'. The text 'Sign in to see price' appears nowhere on the page.",
|
|
327
|
+
expectedData: { price: 199 },
|
|
328
|
+
endResult: "Nothing persists — read-only.",
|
|
329
|
+
},
|
|
292
330
|
"checklist-buying-product-detail-tester-fixtures-hidden-from-the-public": {
|
|
293
331
|
roles: ["guest", "buyer"],
|
|
294
332
|
startPage: "/products",
|
|
@@ -52,7 +52,7 @@ export const authored = {
|
|
|
52
52
|
},
|
|
53
53
|
"checklist-buying-user-dashboard-extras-catalogue-crud": {
|
|
54
54
|
roles: ["buyer"],
|
|
55
|
-
startPage: "/user",
|
|
55
|
+
startPage: "/user/catalogue",
|
|
56
56
|
steps: [
|
|
57
57
|
"Sign in as rehan.sheikh@gmail.com / TempPass123!.",
|
|
58
58
|
"Open the personal catalogue surface and read the existing items.",
|
|
@@ -90,7 +90,7 @@ export const authored = {
|
|
|
90
90
|
},
|
|
91
91
|
"checklist-buying-user-dashboard-extras-my-prize-draws": {
|
|
92
92
|
roles: ["buyer"],
|
|
93
|
-
startPage: "/user",
|
|
93
|
+
startPage: "/user/prize-draws",
|
|
94
94
|
steps: [
|
|
95
95
|
"Sign in as tester@letitrip.in / TempPass123!.",
|
|
96
96
|
"Open the buyer's prize-draws surface and read every row.",
|
|
@@ -106,7 +106,7 @@ export const authored = {
|
|
|
106
106
|
},
|
|
107
107
|
"checklist-buying-user-dashboard-extras-my-digital-codes": {
|
|
108
108
|
roles: ["buyer"],
|
|
109
|
-
startPage: "/user",
|
|
109
|
+
startPage: "/user/digital-codes",
|
|
110
110
|
steps: [
|
|
111
111
|
"Sign in as tester@letitrip.in / TempPass123!.",
|
|
112
112
|
"Open the buyer's digital-codes surface and read every row.",
|
|
@@ -232,7 +232,7 @@ export const authored = {
|
|
|
232
232
|
},
|
|
233
233
|
"checklist-buying-user-dashboard-extras-my-returns": {
|
|
234
234
|
roles: ["buyer"],
|
|
235
|
-
startPage: "/user",
|
|
235
|
+
startPage: "/user/returns",
|
|
236
236
|
steps: [
|
|
237
237
|
"Sign in as tester@letitrip.in / TempPass123!.",
|
|
238
238
|
"Open the buyer's returns surface and read every row.",
|
|
@@ -247,7 +247,7 @@ export const authored = {
|
|
|
247
247
|
},
|
|
248
248
|
"checklist-buying-user-dashboard-extras-my-reviews": {
|
|
249
249
|
roles: ["buyer"],
|
|
250
|
-
startPage: "/user",
|
|
250
|
+
startPage: "/user/reviews",
|
|
251
251
|
steps: [
|
|
252
252
|
"Sign in as rehan.sheikh@gmail.com / TempPass123!.",
|
|
253
253
|
"Open the buyer's reviews surface and read every row.",
|
|
@@ -264,7 +264,7 @@ export const authored = {
|
|
|
264
264
|
},
|
|
265
265
|
"checklist-buying-user-dashboard-extras-user-personal-listings-search-sort": {
|
|
266
266
|
roles: ["buyer"],
|
|
267
|
-
startPage: "/user",
|
|
267
|
+
startPage: "/user/digital-codes",
|
|
268
268
|
steps: [
|
|
269
269
|
"Sign in as rehan.sheikh@gmail.com / TempPass123!.",
|
|
270
270
|
"Open the personal catalogue surface and note the unfiltered item count.",
|
|
@@ -99,7 +99,8 @@ export const authored = {
|
|
|
99
99
|
roles: ["guest"],
|
|
100
100
|
startPage: "/products",
|
|
101
101
|
steps: [
|
|
102
|
-
"
|
|
102
|
+
"Sign in as a buyer. The price-range facet is hidden from signed-out visitors, so this case cannot run as a guest.",
|
|
103
|
+
"Open /products.",
|
|
103
104
|
"Type beyblade in the search field and click 'Search', then note the count.",
|
|
104
105
|
"Open the filters, tick the Beyblade Burst category, and apply.",
|
|
105
106
|
"Read the count, the URL and the card titles.",
|
|
@@ -111,14 +112,15 @@ export const authored = {
|
|
|
111
112
|
endResult: "Read-only; nothing persists beyond the URL.",
|
|
112
113
|
},
|
|
113
114
|
"checklist-content-discovery-search-search-keeps-sort": {
|
|
114
|
-
roles: ["
|
|
115
|
+
roles: ["buyer"],
|
|
115
116
|
startPage: "/products",
|
|
116
117
|
steps: [
|
|
117
118
|
// PRECONDITION FIRST. Without it a broken sort reads as "inconclusive"
|
|
118
119
|
// instead of "fail" — which is exactly what happened: a tester reported
|
|
119
120
|
// sorts=price and sorts=-price returning an IDENTICAL order with no
|
|
120
121
|
// search term at all, and had no way to record that as a verdict.
|
|
121
|
-
"
|
|
122
|
+
"Sign in as a buyer. Price sorts are not offered to signed-out visitors, so this case cannot run as a guest.",
|
|
123
|
+
"Open /products with NO search term.",
|
|
122
124
|
"Set the sort to 'Price: low to high' and read the first three prices in order.",
|
|
123
125
|
"Set the sort to 'Price: high to low' and read the first three prices again.",
|
|
124
126
|
"If those two orders are identical, STOP and answer NO — sort is broken before search is involved, and say so. Do not continue.",
|
|
@@ -135,7 +137,7 @@ export const authored = {
|
|
|
135
137
|
endResult: "Read-only; nothing persists beyond the URL.",
|
|
136
138
|
},
|
|
137
139
|
"checklist-content-discovery-search-search-keeps-facets": {
|
|
138
|
-
roles: ["
|
|
140
|
+
roles: ["buyer"],
|
|
139
141
|
startPage: "/products",
|
|
140
142
|
steps: [
|
|
141
143
|
"Open /products in a private window.",
|
|
@@ -25,12 +25,12 @@ export const authored = {
|
|
|
25
25
|
"Open / in a private window at 1280 pixels wide.",
|
|
26
26
|
"Scroll to a horizontal card carousel.",
|
|
27
27
|
"Look at the left and right arrows and what sits under each.",
|
|
28
|
-
"Read the title and price of the first and last visible cards.",
|
|
28
|
+
"Read the title and the price row (signed out that row reads 'Sign in to see price') of the first and last visible cards.",
|
|
29
29
|
"Try to click the first card's title without hitting an arrow.",
|
|
30
30
|
],
|
|
31
31
|
inputs: { viewportWidth: 1280 },
|
|
32
32
|
expectedBehaviour: "Arrows sit in reserved gutters beside the rail rather than floating over the first and last cards. An arrow on top of a card takes the click meant for the card, which reads as a card that does not open.",
|
|
33
|
-
expectedUiState: "Neither arrow overlaps a card's image, title or price. The first card is clickable across its whole area. An arrow covering the corner of the end card is the failure even when the card still opens from elsewhere.",
|
|
33
|
+
expectedUiState: "Neither arrow overlaps a card's image, title or price row. The first card is clickable across its whole area. An arrow covering the corner of the end card is the failure even when the card still opens from elsewhere.",
|
|
34
34
|
endResult: "Read-only; restore the window width afterwards.",
|
|
35
35
|
},
|
|
36
36
|
"checklist-design-ux-carousel-arrow-bounds-arrows-no-overlap-mid-scroll": {
|
|
@@ -68,12 +68,12 @@ export const authored = {
|
|
|
68
68
|
"Resize the browser window to 390 pixels wide and open / in a private window.",
|
|
69
69
|
"Scroll to a card carousel and look at the first card's left edge.",
|
|
70
70
|
"Look at the last card's right edge after swiping to the end.",
|
|
71
|
-
"Read each visible card's title and price in full.",
|
|
71
|
+
"Read each visible card's title and price row in full.",
|
|
72
72
|
"Try to scroll the page sideways rather than the rail.",
|
|
73
73
|
],
|
|
74
74
|
inputs: { mobileWidth: 390 },
|
|
75
75
|
expectedBehaviour: "Cards are fully readable at the rail's ends, with the container's own padding preserved. A rail that bleeds into the page's edge padding makes the whole page scroll sideways instead of the rail.",
|
|
76
|
-
expectedUiState: "No card is clipped at either end. Every visible title and price reads in full. The PAGE does not scroll sideways — only the rail does.",
|
|
76
|
+
expectedUiState: "No card is clipped at either end. Every visible title and price row reads in full. The PAGE does not scroll sideways — only the rail does.",
|
|
77
77
|
endResult: "Read-only; restore the window width afterwards.",
|
|
78
78
|
},
|
|
79
79
|
"checklist-design-ux-carousel-arrow-bounds-mobile-swipe-and-snap": {
|
|
@@ -114,12 +114,12 @@ export const authored = {
|
|
|
114
114
|
steps: [
|
|
115
115
|
"Open / in a private window at 1280 pixels wide.",
|
|
116
116
|
"Find each product-showcase section and read its heading.",
|
|
117
|
-
"Check each has cards beneath it with titles, images and
|
|
117
|
+
"Check each has cards beneath it with titles, images and a price row.",
|
|
118
118
|
"Write down any showcase heading whose rail is empty.",
|
|
119
119
|
"Click one card and confirm it opens that listing.",
|
|
120
120
|
],
|
|
121
121
|
expectedBehaviour: "A showcase section renders its own query's results. Because each section fails silently to nothing, an empty rail under a heading is the visible half of a section whose fetch returned nothing — the heading rendering at all means the section itself did not throw.",
|
|
122
|
-
expectedUiState: "Every showcase heading has populated cards beneath it, each with a real title, a rendered image and a price. A heading with an empty rail is the finding, named specifically.",
|
|
122
|
+
expectedUiState: "Every showcase heading has populated cards beneath it, each with a real title, a rendered image and a price row — which for a signed-out visitor reads 'Sign in to see price' rather than an amount. A heading with an empty rail is the finding, named specifically.",
|
|
123
123
|
expectedData: { emptyShowcaseRails: 0 },
|
|
124
124
|
endResult: "Read-only; nothing persists.",
|
|
125
125
|
},
|
|
@@ -28,8 +28,8 @@ export const authored = {
|
|
|
28
28
|
roles: ["guest"],
|
|
29
29
|
startPage: "/products",
|
|
30
30
|
steps: [
|
|
31
|
-
"Open /products in a private window in LIGHT mode.",
|
|
32
|
-
"
|
|
31
|
+
"Open /products in a private window in LIGHT mode and read the badges on the grid: Classified, Digital Code, Live Item.",
|
|
32
|
+
"Open /auctions and read the Auction badge; /pre-orders for Pre-Order; /prize-draws for Prize Draw; /art for Art Print and Sticker Sheet.",
|
|
33
33
|
"Read each badge's text against its own background.",
|
|
34
34
|
"Write down any badge whose text cannot be read.",
|
|
35
35
|
],
|
|
@@ -43,7 +43,7 @@ export const authored = {
|
|
|
43
43
|
startPage: "/products",
|
|
44
44
|
steps: [
|
|
45
45
|
"Open /products in a private window and switch to DARK mode.",
|
|
46
|
-
"
|
|
46
|
+
"Read the Classified, Digital Code and Live Item badges on the grid, then visit /auctions, /pre-orders, /prize-draws and /art for the remaining five badges.",
|
|
47
47
|
"Compare each against how it read in light mode.",
|
|
48
48
|
"Write down any badge readable in one theme and not the other.",
|
|
49
49
|
],
|
|
@@ -58,7 +58,7 @@ export const authored = {
|
|
|
58
58
|
steps: [
|
|
59
59
|
"Open /products in a private window and find a Live Item card.",
|
|
60
60
|
"Look at its badge and check whether it has a filled background at all.",
|
|
61
|
-
"Compare it against the
|
|
61
|
+
"Compare it against the Classified and Digital Code badges beside it, then against the Auction badge on /auctions.",
|
|
62
62
|
"Switch to dark mode and look again.",
|
|
63
63
|
"Open /live/live-tester-sandbox-1 signed in as tester@letitrip.in / TempPass123! and look at the badge there.",
|
|
64
64
|
],
|
|
@@ -43,12 +43,12 @@ export const authored = {
|
|
|
43
43
|
steps: [
|
|
44
44
|
"Open /products/product-beyblade-original-dranzer-s in a private window at 1280 pixels wide.",
|
|
45
45
|
"Scroll down slowly and note the point at which the sticky bar appears.",
|
|
46
|
-
"Read what the bar contains — the price, the title, the actions.",
|
|
46
|
+
"Read what the bar contains — the price area, the title, the actions.",
|
|
47
47
|
"Compare its actions against the in-page purchase panel's actions.",
|
|
48
48
|
],
|
|
49
49
|
inputs: { viewportWidth: 1280, revealScrollPx: 400 },
|
|
50
50
|
expectedBehaviour: "The bar appears around 400 pixels of scroll and carries the same actions as the panel it stands in for. Offering fewer actions than the panel makes the bar a downgrade the user has to scroll back up to escape.",
|
|
51
|
-
expectedUiState: "The bar appears once past roughly 400 pixels, showing the
|
|
51
|
+
expectedUiState: "The bar appears once past roughly 400 pixels, showing the same purchase actions as the in-page panel and the same price treatment — which for a signed-out visitor means the gate, not an amount. It does not appear and disappear repeatedly while scrolling steadily in one direction.",
|
|
52
52
|
endResult: "Read-only; restore the window width afterwards.",
|
|
53
53
|
},
|
|
54
54
|
"checklist-design-ux-sticky-cta-bar-desktop-hides-scrolling-back-up": {
|
|
@@ -118,12 +118,12 @@ export const authored = {
|
|
|
118
118
|
steps: [
|
|
119
119
|
"Open /auctions/auction-beyblade-x-shark-edge in a private window at 1280 pixels wide.",
|
|
120
120
|
"Scroll until the sticky bar appears.",
|
|
121
|
-
"Read the bar's contents — the current
|
|
121
|
+
"Read the bar's contents — the current-bid area, the countdown and the action.",
|
|
122
122
|
"Wait 3 seconds and read the countdown again.",
|
|
123
123
|
"Check the bar offers bidding and not 'Add to Cart'.",
|
|
124
124
|
],
|
|
125
125
|
expectedBehaviour: "An auction's bar carries the live countdown and a bidding action, because auctions are capability-blocked from the cart. A bar offering Add to Cart here means it is publishing the default rather than the type's own.",
|
|
126
|
-
expectedUiState: "
|
|
126
|
+
expectedUiState: "BEFORE: the bar read '₹15,000.00 · 1 bid' to anyone. AFTER, signed out: it reads 'Sign in to see the bid · 1 bid' — the bid COUNT is not an amount and stays. A ticking countdown whose seconds figure is lower after 3 seconds sits beside it. Its action is 'Place a bid' or Buy Now — never 'Add to Cart'. A frozen countdown is a fail even though the number looks right.",
|
|
127
127
|
endResult: "Read-only; restore the window width afterwards.",
|
|
128
128
|
},
|
|
129
129
|
"checklist-design-ux-sticky-cta-bar-ended-auction-no-bar": {
|
|
@@ -147,12 +147,12 @@ export const authored = {
|
|
|
147
147
|
steps: [
|
|
148
148
|
"Open /pre-orders/preorder-beyblade-x-bx-08-wave in a private window at 1280 pixels wide.",
|
|
149
149
|
"Scroll until the sticky bar appears.",
|
|
150
|
-
"Read its action label and any
|
|
150
|
+
"Read its action label and whether any deposit figure is stated.",
|
|
151
151
|
"Compare the label against the in-page purchase panel's.",
|
|
152
152
|
"Open /pre-orders/preorder-beyblade-x-bx-11-sold-out and scroll the same way.",
|
|
153
153
|
],
|
|
154
154
|
expectedBehaviour: "A pre-order's bar uses its own vocabulary — reserving against a deposit rather than buying outright — and a sold-out pre-order offers no purchase action. Generic 'Add to Cart' copy here misdescribes what the buyer is agreeing to.",
|
|
155
|
-
expectedUiState: "The live pre-order's bar reads as a reservation and
|
|
155
|
+
expectedUiState: "The live pre-order's bar reads as a reservation, and matches the in-page panel's price treatment — signed out that is 'Sign in to see price' with NO deposit figure anywhere, since a deposit is an amount. The sold-out one shows no purchase bar, or one with no active purchase control.",
|
|
156
156
|
endResult: "Read-only; restore the window width afterwards.",
|
|
157
157
|
},
|
|
158
158
|
"checklist-design-ux-sticky-cta-bar-prize-draw-bar-label": {
|
|
@@ -162,11 +162,11 @@ export const authored = {
|
|
|
162
162
|
"Open /prize-draws/prizedraw-beyblade-mystery-box in a private window at 1280 pixels wide.",
|
|
163
163
|
"Scroll until the sticky bar appears.",
|
|
164
164
|
"Read its action label and its price.",
|
|
165
|
-
"Check whether the
|
|
165
|
+
"Check whether the charge is described as an entry rather than as the item's price.",
|
|
166
166
|
"Compare the label against the in-page purchase panel's.",
|
|
167
167
|
],
|
|
168
168
|
expectedBehaviour: "A prize draw sells ENTRIES, not the prize, and the bar has to say so. A label reading 'Buy now' beside a price is a misrepresentation of what the money buys, which matters more here than anywhere else on this page.",
|
|
169
|
-
expectedUiState: "The bar names an entry
|
|
169
|
+
expectedUiState: "The bar names an entry, matching the in-page panel. Signed out its amount is gated: it reads 'Sign in to see the entry price' rather than a per-entry figure. It does not read as buying the prize outright.",
|
|
170
170
|
endResult: "Read-only; restore the window width afterwards.",
|
|
171
171
|
},
|
|
172
172
|
"checklist-design-ux-sticky-cta-bar-closed-prize-draw-no-bar": {
|
|
@@ -115,15 +115,15 @@ export const authored = {
|
|
|
115
115
|
steps: [
|
|
116
116
|
"Open /products in a private window with no session.",
|
|
117
117
|
"Read the total result count and the availability tab bar.",
|
|
118
|
-
"
|
|
118
|
+
"Click 'Filters' and read every checkbox under the 'Listing type' heading.",
|
|
119
119
|
"Read every card title on the first page, looking for anything containing 'Tester' or 'Test'.",
|
|
120
|
-
"
|
|
121
|
-
"Tick
|
|
120
|
+
"Read every badge on the first page of cards.",
|
|
121
|
+
"Tick 'Classifieds' and 'Digital Codes', click Apply, and read the sort dropdown.",
|
|
122
122
|
],
|
|
123
|
-
expectedBehaviour: "/products spans
|
|
124
|
-
expectedUiState: "
|
|
125
|
-
expectedData: { listingTypeChipCount:
|
|
126
|
-
endResult: "Read-only; nothing persists.
|
|
123
|
+
expectedBehaviour: "/products is the GENERAL catalogue, not an index of everything. It spans the four listing types that have no entry of their own in the main nav — Standard, Classifieds, Digital Codes, Live Items — so each of those is still reachable from somewhere. Auctions, Pre-Orders, Prize Draws, Art and Stickers each own a dedicated page linked from the main nav and no longer appear here, so no item is reachable from two places with two different chromes. The sort dropdown narrows to the options valid for every selected type.",
|
|
124
|
+
expectedUiState: "BEFORE (the behaviour this replaced): nine type checkboxes, and the grid mixed cards badged 'Auction', 'Pre-Order' and 'Sticker Sheet' in among ordinary products. AFTER: exactly four checkboxes — Standard, Classifieds, Digital Codes, Live Items — and NO card on any page carries an 'Auction', 'Pre-Order', 'Prize Draw', 'Art Print' or 'Sticker Sheet' badge. The Available / Sold & Ended / All tabs are present with Available selected. No card title contains 'Tester' or 'Test' for a signed-out visitor.",
|
|
125
|
+
expectedData: { listingTypeChipCount: 4 },
|
|
126
|
+
endResult: "Read-only; nothing persists. An 'Auction' or 'Pre-Order' badge appearing in this grid is the specific regression this case exists for — those types belong on /auctions and /pre-orders.",
|
|
127
127
|
},
|
|
128
128
|
"checklist-public-pages-core-listing-pages-auctions-listing-page": {
|
|
129
129
|
roles: ["guest"],
|
|
@@ -166,7 +166,7 @@ export const authored = {
|
|
|
166
166
|
],
|
|
167
167
|
inputs: { bundlePrice: 199, memberTotal: 348 },
|
|
168
168
|
expectedBehaviour: "A bundle is a category row with a locked price, deliberately below the sum of its members, and the discount badge is computed from the two. Its members are mirrored onto the bundle for index-friendly reads, and a reader that trusts only the mirror shows an empty bundle whenever a write path forgot to update it.",
|
|
169
|
-
expectedUiState: "Each card shows a price and a discount percentage.
|
|
169
|
+
expectedUiState: "Each card shows a price row and, when signed in, a discount percentage. Signed out the price row reads 'Sign in to see the bundle price' and NO discount percentage is shown — the percentage is derived from the bundle price and discloses it. Signed in, the sandbox bundle shows ₹199 against a members' total of ₹348. Its detail page lists both members with titles and images rather than reading '0 items'. No sandbox bundle is visible to a signed-out visitor.",
|
|
170
170
|
expectedData: { sandboxBundleVisibleToGuest: false },
|
|
171
171
|
endResult: "Read-only; nothing persists. A bundle rendering as empty is the mirror-drift failure, not a missing bundle.",
|
|
172
172
|
},
|
|
@@ -17,6 +17,22 @@
|
|
|
17
17
|
* @tag sideEffects:none
|
|
18
18
|
*/
|
|
19
19
|
export const authored = {
|
|
20
|
+
"checklist-seo-canonical-and-host-gated-price-is-declared-in-structured-data": {
|
|
21
|
+
roles: ["guest"],
|
|
22
|
+
startPage: "/products/product-beyblade-burst-valkyrie",
|
|
23
|
+
steps: [
|
|
24
|
+
"Open /products/product-beyblade-burst-valkyrie in a private window and view the page source.",
|
|
25
|
+
"Find every <script type=\"application/ld+json\"> block and read them.",
|
|
26
|
+
"In the Product block, read the offers object and confirm it still carries a price and a priceCurrency.",
|
|
27
|
+
"Find the WebPage block and read its isAccessibleForFree value and its hasPart.cssSelector value.",
|
|
28
|
+
"Search the rendered HTML for that exact selector's class name and confirm at least one element carries it.",
|
|
29
|
+
"Repeat all of the above for /auctions/auction-beyblade-metal-lightning-l-drago.",
|
|
30
|
+
],
|
|
31
|
+
expectedBehaviour: "The structured data keeps the price on purpose, so search engines still see it — and declares the on-page gate alongside it, so the richer markup is not an undeclared mismatch. Both halves are required: the price alone is a mismatch, and the declaration alone throws away the search value the decision was made to keep.",
|
|
32
|
+
expectedUiState: "The Product block's offers object contains a numeric price and priceCurrency 'INR'. A separate WebPage block is present carrying isAccessibleForFree: false and hasPart.cssSelector '.appkit-gated-price'. Searching the HTML for 'appkit-gated-price' finds at least one element. On the auction page the same two blocks are present, the offer price being the current bid. A page with offers.price and NO WebPage block is the failure; so is a cssSelector that matches no element in the HTML.",
|
|
33
|
+
expectedData: { webPageBlocksWithGateDeclared: 2, selectorMatchesElement: true },
|
|
34
|
+
endResult: "Read-only; nothing persists.",
|
|
35
|
+
},
|
|
20
36
|
"checklist-seo-canonical-and-host-apex-redirects-to-www": {
|
|
21
37
|
roles: ["guest"],
|
|
22
38
|
startPage: "/",
|
|
@@ -44,6 +44,23 @@ export const authored = {
|
|
|
44
44
|
expectedUiState: "The card shows the product's own title and its own photo. A generic card is the finding.",
|
|
45
45
|
endResult: "Read-only.",
|
|
46
46
|
},
|
|
47
|
+
"checklist-seo-og-images-og-image-carries-no-price": {
|
|
48
|
+
roles: ["guest"],
|
|
49
|
+
startPage: "/products/product-beyblade-burst-valkyrie",
|
|
50
|
+
steps: [
|
|
51
|
+
"Open /products/product-beyblade-burst-valkyrie, view source, find the og:image tag and open its URL in a fresh tab.",
|
|
52
|
+
"Read every figure printed on the card.",
|
|
53
|
+
"Repeat for /bundles/bundle-every-generation-starter-pack.",
|
|
54
|
+
"Repeat for /classified/classified-beyblade-stadium-set.",
|
|
55
|
+
"Repeat for /digital-codes/digitalcode-beyblade-x-app-starter-pack.",
|
|
56
|
+
"Repeat for /live/live-golden-retriever-puppy.",
|
|
57
|
+
"Repeat for /prize-draws/prizedraw-tester-sandbox-1.",
|
|
58
|
+
],
|
|
59
|
+
expectedBehaviour: "None of these cards prints a money amount. The card is a public image URL with its contents burned into the pixels, so a price there survives every gate on the page and is fetchable by anyone who has the listing URL. A prize draw that is genuinely free may still say 'Free entry' — that is a fact about the draw, not a disclosed amount.",
|
|
60
|
+
expectedUiState: "BEFORE: the product card showed '₹1,299', the bundle card its bundle price, the classified/digital-code/live/catalogue cards their own prices, and the prize-draw card '₹X / entry'. AFTER: no '₹' character appears on any of the six cards. The auction and pre-order cards are unchanged — they show an end date and a release date respectively and never carried a price.",
|
|
61
|
+
expectedData: { cardsShowingRupee: 0 },
|
|
62
|
+
endResult: "Read-only. A ₹ figure on any of these cards is the regression this case exists for.",
|
|
63
|
+
},
|
|
47
64
|
"checklist-seo-og-images-og-image-brand-logo-present": {
|
|
48
65
|
roles: ["guest"],
|
|
49
66
|
startPage: "/brands/brand-takara-tomy",
|
|
@@ -2,10 +2,30 @@
|
|
|
2
2
|
* WHY: Shared tester sandbox — one auto-approved test store testers browse/buy from and
|
|
3
3
|
* use as a reference when creating their own listings. Auto-expires after 7 days
|
|
4
4
|
* (testerSandboxCleanup) and is invisible to non-testers (application-layer filter).
|
|
5
|
-
* WHAT: Exports
|
|
5
|
+
* WHAT: Exports 2 StoreDocument partials tagged isTestData:true — the shared sandbox
|
|
6
|
+
* (owned by admin) and the automated runner's OWN store.
|
|
7
|
+
*
|
|
8
|
+
* 🛑 TWO STORES, TWO OWNERS, AND THE SPLIT IS LOAD-BEARING.
|
|
9
|
+
*
|
|
10
|
+
* `store-tester-sandbox` stays owned by `user-admin-letitrip`. Several authored cases
|
|
11
|
+
* name that owner explicitly — buying__bidding.ts:211 says "Sign in as admin@letitrip.in,
|
|
12
|
+
* the owner of store-tester-sandbox", and :228 warns that signing in as anyone else
|
|
13
|
+
* "gives a 403 that reads like a permissions bug and is not one". Repointing it would
|
|
14
|
+
* turn those cases into false failures.
|
|
15
|
+
*
|
|
16
|
+
* `store-claude-tester` exists because `user-claude-tester` owned NO store while its user
|
|
17
|
+
* document carried `storeId: "store-tester-qa-seller"` — a store whose `ownerId` is
|
|
18
|
+
* `user-tester-qa`. The app resolves sellers by `ownerId`, so every /api/store/* call for
|
|
19
|
+
* the runner returned 403 "No store found for this account" while the full Store Panel
|
|
20
|
+
* rendered over it. That one-way pointer blocked 36 checklist cases (measured, run
|
|
21
|
+
* 1789300124915). Root Cause #42's denormalised-mirror shape on the user<->store axis.
|
|
22
|
+
*
|
|
23
|
+
* It is deliberately EMPTY of listings. The seller cases it unblocks are create/CRUD
|
|
24
|
+
* flows (listing-lifecycle, coupons, bundles, classifieds), which want a clean store;
|
|
25
|
+
* cases that need pre-existing stock still use the shared sandbox.
|
|
6
26
|
*
|
|
7
27
|
* EXPORTS:
|
|
8
|
-
* storesTesterSeedData — Array of
|
|
28
|
+
* storesTesterSeedData — Array of 2 Partial<StoreDocument> for the seed runner
|
|
9
29
|
*
|
|
10
30
|
* @tag domain:stores,tester
|
|
11
31
|
* @tag layer:seed
|
|
@@ -37,4 +57,23 @@ export const storesTesterSeedData = [
|
|
|
37
57
|
createdAt: new Date(),
|
|
38
58
|
updatedAt: new Date(),
|
|
39
59
|
},
|
|
60
|
+
{
|
|
61
|
+
id: "store-claude-tester",
|
|
62
|
+
storeSlug: "store-claude-tester",
|
|
63
|
+
ownerId: "user-claude-tester",
|
|
64
|
+
storeName: "Claude Tester Store",
|
|
65
|
+
storeDescription: "The automated checklist runner's own store. Exists so seller-side create/edit flows can be exercised against a store the runner actually owns. Disposable test data.",
|
|
66
|
+
storeCategory: "category-tester-sandbox",
|
|
67
|
+
storeLogoURL: seedPhoto("store-logo-claude-tester-20260101", 400, 400),
|
|
68
|
+
storeBannerURL: seedPhoto("store-banner-claude-tester-20260101", 1600, 400),
|
|
69
|
+
status: STORE_FIELDS.STATUS_VALUES.ACTIVE,
|
|
70
|
+
isPublic: true,
|
|
71
|
+
bio: "Automated tester's store. Everything in it is disposable test data.",
|
|
72
|
+
returnPolicy: "N/A — test data.",
|
|
73
|
+
shippingPolicy: "N/A — test data.",
|
|
74
|
+
isTestData: true,
|
|
75
|
+
testDataExpiresAt: testDataExpiresAt(),
|
|
76
|
+
createdAt: new Date(),
|
|
77
|
+
updatedAt: new Date(),
|
|
78
|
+
},
|
|
40
79
|
];
|