import {expect} from '@playwright/test'; // Only GET requests for public static assets are allowed. No real account, // promo, subscription or backend is read or written, including on production. export async function bootPromoFixture(page,base='http://127.0.0.1:4173/'){ const origin=new URL(base).origin; await page.route('**/*',route=>{const r=route.request(),u=new URL(r.url());return r.method()==='GET'&&u.origin===origin&&!u.pathname.startsWith('/api/')?route.continue():route.abort();}); await page.addInitScript(()=>{ const user={id:'promo-test-user',email:'promo-ui@example.invalid',email_confirmed_at:'2026-01-01T00:00:00Z'},ws='promo-test-workspace'; window.promoCalls=[];window.promoRows=[];window.promoCreateError=null;window.promoDelay=false; localStorage.setItem('sunCloudV2Config',JSON.stringify({workspaceId:ws,localWorkspaceId:ws,tenantStorageReady:true,autoSync:false})); localStorage.setItem('sunBoxes','[]');localStorage.setItem('sunOrders','[]'); const features=Object.fromEntries('orders calendar clients catalog_view catalog_edit production shopping stock routes mailings money stats_basic stats_advanced team suppliers print settings branding client_offers offer_templates backups audit users_manage'.split(' ').map(k=>[k,true])); const sdk={ auth:{onAuthStateChange:()=>({data:{subscription:{unsubscribe(){}}}}),getSession:async()=>({data:{session:{user}},error:null}),getUser:async()=>({data:{user},error:null}),mfa:{getAuthenticatorAssuranceLevel:async()=>({data:{currentLevel:'aal2'}})}}, rpc:async(name,args={})=>{ if(name==='sun_my_workspaces')return {data:[{id:ws,name:'Проверка интерфейса',role:'admin',is_active:true,permissions:{}}]}; if(name==='sun_subscription_snapshot')return {data:{plan_id:'full',plan_name:'Полный',status:'active',access_mode:'full',features}}; if(name==='sun_is_platform_admin')return {data:true}; if(name==='sun_dev_dashboard')return {data:{}}; if(name==='caterium_trial_demo_status')return {data:{canInstall:false,canUpgrade:false}}; if(name==='sun_dev_list_trial_promos'){promoCalls.push({name,args});return {data:structuredClone(promoRows)};} if(name==='sun_dev_create_trial_promo'){ promoCalls.push({name,args});if(promoDelay)await new Promise(resolve=>window.completePromo=resolve); if(promoCreateError)return {error:{message:promoCreateError}}; const data={promo_id:'test-code-'+promoRows.length,code:args.p_code||'CTM-UI-TEST',trial_days:args.p_trial_days,valid_until:'2099-01-01T00:00:00Z'}; promoRows.push({...data,client_email:args.p_email,max_uses:args.p_max_uses,use_count:0,is_active:true});return {data}; } if(name==='sun_dev_set_trial_promo_active'){promoCalls.push({name,args});const r=promoRows.find(r=>r.promo_id===args.p_promo);if(r)r.is_active=args.p_active;return {data:null};} return {data:null,error:null}; },channel:()=>({on(){return this},subscribe(){return this}}),removeChannel(){} }; window.supabase={createClient:()=>sdk}; }); await page.goto(base,{waitUntil:'domcontentloaded',timeout:60000}); await expect(page.locator('body > header')).toBeVisible({timeout:20000}); await page.waitForFunction(()=>window.SunDeveloperV22&&window.SunDeveloperUXV1768&&window.CateriumTrialPromoDeveloperV181); await page.locator('#sunDeveloperNavV22').click(); await expect(page.locator('#ctmPromoOpen')).toBeVisible(); } export async function exercisePromoCreation(page){ await page.locator('#ctmPromoOpen').click(); await expect(page.locator('#ctmPromoPlan')).toBeVisible(); await expect(page.locator('#ctmPromoPlan option')).toHaveCount(3); await page.locator('#ctmPromoPlan').selectOption('professional'); await page.locator('#ctmPromoTrial').fill('30'); await page.locator('#ctmPromoValid').fill('7'); await page.locator('#ctmPromoCreate').click(); await expect(page.locator('#ctmInvitationText')).toHaveValue(/Профессиональный/); await expect(page.locator('#ctmInvitationText')).toHaveValue(/30 дн/); await expect(page.locator('#ctmPromoList')).toContainText('CTM-UI-TEST'); const calls=await page.evaluate(()=>promoCalls.filter(c=>c.name==='sun_dev_create_trial_promo')); expect(calls).toHaveLength(1);expect(calls[0].args).toMatchObject({p_plan:'professional',p_trial_days:30,p_valid_days:7,p_max_uses:1,p_code:null}); }