Add Settings > Учебный каталог, off by default and available on ordinary writable profiles. Load ready example boxes, photos, TTKs and linked sample inventory additively; preserve own data, saved orders and edited examples when hiding or re-enabling. Respect company/profile scope, read-only permissions, failed downloads and tenant changes. Preserve the opened recipe guide across real catalog refreshes on iPhone. Integrated feature checks and full pull-request QA passed. Standard main QA and exact-asset production UI verification remain in place.
48 lines
3.8 KiB
JavaScript
48 lines
3.8 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs/promises';
|
|
import {chromium,expect} from '@playwright/test';
|
|
import {trainingInit} from './training-catalog-fixture.mjs';
|
|
|
|
// Exercise the actual published assets with a synthetic profile. All traffic
|
|
// except same-origin static GETs is blocked, so no real workspace is touched.
|
|
const base=new URL(process.env.TIMEWEB_BASE_URL||'https://app.caterium.ru');
|
|
if(base.protocol!=='https:')throw new Error('Published UI verification requires HTTPS');
|
|
const output='production-ui-results';await fs.mkdir(output,{recursive:true});
|
|
const browser=await chromium.launch(),results=[];
|
|
try{
|
|
for(const width of [390,1440]){
|
|
const context=await browser.newContext({viewport:{width,height:900},serviceWorkers:'block'});
|
|
try{
|
|
await context.route('**/*',route=>{const r=route.request(),u=new URL(r.url());return r.method()==='GET'&&u.origin===base.origin&&!u.pathname.startsWith('/api/')?route.continue():route.abort();});
|
|
await context.addInitScript(trainingInit);
|
|
const page=await context.newPage();page.on('dialog',d=>d.accept());
|
|
await page.goto(base.href,{waitUntil:'domcontentloaded',timeout:60000});
|
|
await expect(page.locator('body > header')).toBeVisible({timeout:20000});
|
|
await page.waitForFunction(()=>window.CateriumDataV1773&&window.SunOpsUXV1762&&window.CateriumTrialDemo&&window.CateriumTrainingCatalog);
|
|
const nav=page.locator('header nav'),toggle=page.locator('#ctTrainingEnabled');
|
|
const settings=async()=>{await nav.getByRole('button',{name:'Настройки',exact:true}).click();await expect(toggle).toBeVisible();};
|
|
await settings();await expect(toggle).not.toBeChecked();
|
|
const before=await page.evaluate(()=>({orders:localStorage.sunOrders,box:boxes.find(b=>b.id==='own-box'),stock:JSON.parse(localStorage.sunStock).find(p=>p.id==='own-stock')}));
|
|
await toggle.check();await expect(toggle).toBeEnabled();
|
|
await expect.poll(()=>page.evaluate(()=>CateriumTrainingCatalog.enabled())).toBe(true);
|
|
assert.equal(await page.evaluate(()=>boxes.length),45);
|
|
await page.locator('#ctTrainingSettings').scrollIntoViewIfNeeded();
|
|
await page.screenshot({path:`${output}/training-settings-${width}.png`,animations:'disabled'});
|
|
await nav.getByRole('button',{name:'Меню',exact:true}).click();await expect(page.locator('[data-menu-item-v1762]')).toHaveCount(11);
|
|
await expect(page.locator('[data-menu-item-v1762="demo-v1-bruschetta-tomato"] .ct-training-badge')).toHaveText('Учебное');
|
|
await page.screenshot({path:`${output}/training-catalog-${width}.png`,animations:'disabled'});
|
|
await settings();await toggle.uncheck();await expect(toggle).toBeEnabled();
|
|
await expect.poll(()=>page.evaluate(()=>CateriumTrainingCatalog.enabled())).toBe(false);
|
|
await nav.getByRole('button',{name:'Меню',exact:true}).click();await expect(page.locator('[data-menu-item-v1762]')).toHaveCount(1);
|
|
const after=await page.evaluate(()=>({orders:localStorage.sunOrders,box:boxes.find(b=>b.id==='own-box'),stock:JSON.parse(localStorage.sunStock).find(p=>p.id==='own-stock')}));
|
|
assert.deepEqual(after,before);
|
|
assert.equal(await page.evaluate(()=>boxes.length),45);
|
|
await settings();await toggle.check();await expect(toggle).toBeEnabled();
|
|
assert.equal(await page.evaluate(()=>boxes.length),45);
|
|
results.push({width,defaultOff:true,readyExamples:44,hideRestoresOwnCatalog:true,repeatDoesNotDuplicate:true,ordersAndOwnDataPreserved:true});
|
|
console.log(`PASS published training catalog ${width}px: opt-in, complete examples, hide/show, preserved own data and orders`);
|
|
}finally{await context.close();}
|
|
}
|
|
await fs.writeFile(`${output}/training-catalog-result.json`,JSON.stringify({base:base.href,checkedAt:new Date().toISOString(),backend:'synthetic, network-blocked',results},null,2));
|
|
}finally{await browser.close();}
|