import { expect, test } from '@playwright/test'; const IMAGE = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAF/gL+Xw0YAAAAAElFTkSuQmCC'; test.beforeEach(async ({context, page}) => { await context.route('**/*', route => new URL(route.request().url()).origin === 'http://127.0.0.1:4173' ? route.continue() : route.abort()); await page.addInitScript(image => { localStorage.setItem('aisthetix_tryon_consent', '1'); localStorage.setItem('aisthetix-avatar', JSON.stringify({imageData: `data:image/png;base64,${image}`, createdAt: new Date().toISOString()})); }, IMAGE); await page.route('**/garment.png', route => route.fulfill({contentType:'image/png', body:Buffer.from(IMAGE,'base64')})); }); for (const width of [390, 320]) test(`saved-photo reopen and non-retryable recovery at ${width}px`, async ({page}, info) => { await page.setViewportSize({width, height:844}); let requests = 0; await page.route('**/api/storefront/tryon', route => {requests++; return route.fulfill({status:422, contentType:'application/json', body:JSON.stringify({error:'cannot_generate', code:'photo_body_hidden', retryable:false})});}); await page.goto('/widget-src/e2e/fixtures/product.html'); await page.addStyleTag({content:'button { background:#1C2B45!important;color:#FBFAF7!important;border:1px solid #1C2B45!important;border-radius:0!important;text-transform:uppercase;letter-spacing:.13em;font-size:.72rem;padding:.95em 1.9em; }'}); const trigger = page.getByRole('button', {name:'Try it on', exact:true}); await trigger.click(); await expect(page.getByText('Use this photo again?', {exact:true})).toBeVisible(); expect(requests).toBe(0); await page.locator('.aisthetix-modal-close').click(); await expect(page.getByRole('dialog')).toHaveCount(0); await trigger.click(); await expect(page.getByText('Use this photo again?', {exact:true})).toBeVisible(); expect(requests).toBe(0); await page.getByRole('button', {name:'Use This Photo', exact:true}).click(); await expect(page.getByRole('button', {name:'Use another photo', exact:true})).toBeVisible(); await expect(page.getByRole('button', {name:'Try Again', exact:true})).toHaveCount(0); expect(requests).toBe(1); await page.getByRole('button', {name:'Use another photo', exact:true}).click(); await expect(page.locator('.aisthetix-preview-image')).toHaveCount(0); await expect(page.locator('.aisthetix-guide-do li')).toHaveCount(5); await expect(page.locator('.aisthetix-guide-grid p')).toHaveText(['Baggy clothes','Cropped','Too far','Other people','Too dark']); expect(await page.locator('.aisthetix-modal-body').evaluate(el => el.scrollWidth <= el.clientWidth)).toBe(true); const fits = await page.locator('.aisthetix-guide-grid p').evaluateAll(elements => elements.every(el => {const r=el.getBoundingClientRect(); return r.left>=0 && r.right<=innerWidth && el.scrollWidth<=el.clientWidth;})); expect(fits).toBe(true); await expect(page.locator('.aisthetix-mobile-upload')).toBeVisible(); await expect(page.locator('.aisthetix-mobile-upload')).toHaveCSS('text-transform','none'); expect(await page.evaluate(() => localStorage.getItem('aisthetix-avatar'))).toContain(IMAGE); await page.screenshot({path:info.outputPath('guide.png')}); }); test('production loader uses the shopper photo and advances while waiting', async ({page}) => { await page.route('**/api/storefront/tryon', () => {}); await page.goto('/widget-src/e2e/fixtures/product.html'); await page.getByRole('button', {name:'Try it on', exact:true}).click(); await page.getByRole('button', {name:'Use This Photo', exact:true}).click(); await expect(page.locator('.aisthetix-processing-avatar')).toHaveAttribute('src', `data:image/png;base64,${IMAGE}`); await expect(page.locator('.aisthetix-status')).toHaveText('Analyzing your photo', {timeout:6000}); await expect(page.locator('.aisthetix-elapsed')).toContainText(/\d+\.\ds/); }); for (const demo of [false, true]) for (const width of [320, 390, 1280]) test(`shipping ${demo ? 'demo' : 'merchant'} result supports keyboard comparison and preserves its split at ${width}px`, async ({page}) => { await page.setViewportSize({width, height:844}); let requests = 0; await page.route('**/api/storefront/tryon', route => { requests++; return route.fulfill({contentType:'application/json', body:JSON.stringify({image:IMAGE, cached:false})}); }); await page.goto(`/widget-src/e2e/fixtures/product.html?demo=${demo ? '1' : '0'}`); await page.getByRole('button', {name:'Try it on', exact:true}).click(); await page.getByRole('button', {name:'Use This Photo', exact:true}).click(); const slider = page.getByRole('slider', {name:'Drag to compare your photo before and after the try-on'}); await expect(slider).toHaveValue('50'); await expect(page.getByRole('img', {name:'Your original photo', exact:true})).toHaveAttribute('src', `data:image/png;base64,${IMAGE}`); await slider.focus(); await slider.press('ArrowRight'); await expect(slider).toHaveValue('51'); await expect(page.locator('.aisthetix-before-after')).toHaveCSS('outline-style','solid'); await page.getByRole('button', {name:'Compare', exact:true}).click(); await expect(slider).toHaveCount(0); await expect(page.getByRole('img', {name:'Original', exact:true})).toBeVisible(); await expect(page.getByRole('img', {name:'Try-On', exact:true})).toBeVisible(); await expect(page.locator('.aisthetix-result-compare')).toHaveCSS('flex-direction', width <= 480 ? 'column' : 'row'); await page.getByRole('button', {name:'Result', exact:true}).click(); await expect(slider).toHaveValue('51'); expect(requests).toBe(1); });