import { expect, test, type Page } from '@playwright/test'; const PNG_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAF/gL+Xw0YAAAAAElFTkSuQmCC'; async function stubStorefront( page: Page ) { await page.addInitScript( ( avatar ) => { localStorage.setItem( 'aisthetix_tryon_consent', '1' ); localStorage.setItem( 'aisthetix-avatar', JSON.stringify( { imageData: `data:image/png;base64,${ avatar }`, createdAt: '2026-08-29T00:00:00Z', } ) ); }, PNG_BASE64 ); await page.route( '**/garment.png', ( route ) => route.fulfill( { contentType: 'image/png', body: Buffer.from( PNG_BASE64, 'base64' ), } ) ); await page.route( '**/api/storefront/tryon', ( route ) => route.fulfill( { contentType: 'application/json', body: JSON.stringify( { image: PNG_BASE64, cached: false } ), } ) ); await page.route( '**/api/storefront/photo-qc', ( route ) => route.fulfill( { contentType: 'application/json', body: JSON.stringify( { ok: true, reason: null } ), } ) ); await page.route( '**/api/storefront/size', ( route ) => route.fulfill( { contentType: 'application/json', body: JSON.stringify( { recommended_size: 'M', recommended_variant_id: '102', confidence: 0.9, confidence_band: 'very_confident', explanation: 'Browser fixture', alternatives: [], } ), } ) ); } async function completeSizeFlow( page: Page, theme: 'classic' | 'swatches' | 'mismatch' ) { await stubStorefront( page ); await page.goto( `/widget-src/e2e/fixtures/product.html?theme=${ theme }` ); await page.getByRole( 'button', { name: 'Try it on' } ).click(); await page.getByRole( 'button', { name: 'Find my size' } ).click(); await page.getByLabel( 'Height (cm)' ).fill( '175' ); await page.getByRole( 'button', { name: 'Get my size' } ).click(); await expect( page.locator( '.aisthetix-size-result__size' ) ).toHaveText( 'M' ); await page.locator( '.aisthetix-size-result' ) .getByRole( 'button', { name: 'Add to cart', exact: true } ) .click(); } test( 'does not click a theme cart button resolved to a different variation', async ( { page } ) => { await completeSizeFlow( page, 'mismatch' ); await expect( page.locator( '.aisthetix-size-result' ).getByRole( 'alert' ) ) .toHaveText( 'Could not select this variation. Please choose it on the product page.' ); await expect.poll( () => page.evaluate( () => window.cartAdds ) ).toEqual( [] ); await expect( page.locator( 'input.variation_id' ) ).toHaveValue( '999' ); } ); for ( const theme of [ 'classic', 'swatches' ] as const ) { test( `selects and adds the confirmed recommendation on the ${ theme } theme fixture`, async ( { page } ) => { await completeSizeFlow( page, theme ); await expect.poll( () => page.evaluate( () => window.cartAdds ) ).toEqual( [ { variationId: '102', color: 'black', size: 'm', } ] ); await expect( page.locator( 'input.variation_id' ) ).toHaveValue( '102' ); await expect( page.locator( 'button.single_add_to_cart_button' ) ).toBeEnabled(); } ); } declare global { interface Window { cartAdds: Array<{ variationId: string; color: string; size: string }>; } }