caterium-app/tests/production-banquet-client-menu.mjs
pavlov346346-source bc3f186992
One-page banquet menu for the client (#36)
Add a single-page A4 preview and PDF for all selected banquet dishes or a ready-menu selection, with company branding and optional costs. Preserve draft/order state and saved line prices, enforce access and tenant scope, and fail clearly rather than clipping oversized menus. Nineteen targeted browser scenarios passed twice and the generated iPhone PDF was visually checked. Full main QA must pass before the existing automatic production promotion; production verification includes the new renderer and real-asset client menu export.
2026-09-20 12:54:42 +03:00

38 lines
3.3 KiB
JavaScript

import fs from 'node:fs/promises';
import assert from 'node:assert/strict';
import {chromium,expect} from '@playwright/test';
import {trainingInit} from './training-catalog-fixture.mjs';
const base=new URL(process.env.TIMEWEB_BASE_URL||'https://app.caterium.ru');
if(base.protocol!=='https:')throw new Error('Production verification requires HTTPS');
const items=JSON.parse(await fs.readFile('public/demo/banquet-v1.json','utf8')).banquet.map((x,i)=>({...x,id:`onepage-${i}`,demo:false,banquet:{packageId:'test-set',packageName:'Праздничное меню'}}));
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('**/*',r=>{const u=new URL(r.request().url());return r.request().method()==='GET'&&u.origin===base.origin&&!u.pathname.startsWith('/api/')?r.continue():r.abort();});
await context.addInitScript(trainingInit);
await context.addInitScript(menu=>{localStorage.setItem('sunBoxes',JSON.stringify(menu));localStorage.setItem('sunPdfBrandNameV1','Студия вкуса');},items);
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.CateriumBanquet&&window.SunOpsUXV1762&&window.CateriumDataV1773);
await page.locator('header nav').getByRole('button',{name:'Новый заказ',exact:true}).click();
await page.getByRole('button',{name:'Банкетное меню',exact:true}).click();
await page.locator('[data-banquet-package="test-set"]').click();await page.locator('[data-banquet-preset]').click();
await page.locator('[data-banquet-guests]').fill('20');
const before=await page.evaluate(()=>({draft:JSON.stringify(draft),orders:localStorage.sunOrders,boxes:localStorage.sunBoxes}));
await page.locator('[data-banquet-client-menu]').click();
await expect(page.locator('[data-bcm-download]')).toBeEnabled({timeout:20000});
await page.screenshot({path:`${output}/banquet-client-menu-${width}.png`});
const promise=page.waitForEvent('download');await page.locator('[data-bcm-download]').click();const d=await promise;
const file=`${output}/banquet-client-menu-${width}.pdf`;await d.saveAs(file);
const bytes=await fs.readFile(file);assert.equal(bytes.subarray(0,5).toString(),'%PDF-');assert(bytes.toString('latin1').includes('/Count 1'));
await page.locator('[data-bcm-prices]').uncheck();await expect(page.locator('[data-bcm-status]')).toContainText('Без указания стоимости');
await page.locator('[data-bcm-close]').click();assert.deepEqual(await page.evaluate(()=>({draft:JSON.stringify(draft),orders:localStorage.sunOrders,boxes:localStorage.sunBoxes})),before);
results.push({width,selectedDishes:items.length,singlePage:true,hidePrices:true,noWrites:true});console.log(`PASS published single-page banquet menu ${width}px`);
}finally{await context.close();}
}
await fs.writeFile(`${output}/banquet-client-menu-result.json`,JSON.stringify({base:base.href,backend:'synthetic, network-blocked',results},null,2));
}finally{await browser.close();}