category-layout.mjs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435
  1. import assert from 'node:assert/strict';
  2. import { chromium } from 'playwright';
  3. // 分类页使用实际容器和控件几何检查,覆盖手机与桌面预览的底部布局。
  4. const browser = await chromium.launch({headless:true,executablePath:process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE || 'C:/Users/Administrator/AppData/Local/ms-playwright/chromium-1228/chrome-win64/chrome.exe'});
  5. try {
  6. const page=await browser.newPage();
  7. for (const width of [320,390,490,768,1440]) {
  8. await page.setViewportSize({width,height:886});
  9. await page.goto(`${process.env.FRONTEND_URL || 'http://127.0.0.1:18763'}/#/customer/categories`);
  10. await page.locator('.catalog').waitFor();
  11. const geometry=await page.evaluate(() => Object.fromEntries(['.mobile','.content','.shop-search','.catalog','.goods-card','.goods-info','.shop-tabs','.ai-float'].map(selector => {
  12. const node=document.querySelector(selector),r=node.getBoundingClientRect(),s=getComputedStyle(node);
  13. return [selector,{x:r.x,y:r.y,width:r.width,height:r.height,bottom:r.bottom,position:s.position,boxSizing:s.boxSizing,borderRadius:s.borderRadius,padding:s.padding,transform:s.transform}];
  14. })));
  15. const frame=geometry['.mobile'],tabs=geometry['.shop-tabs'],ai=geometry['.ai-float'];
  16. assert.ok(Math.abs(frame.bottom-tabs.bottom)<=1,`${width}px 导航下方不应存在额外空白`);
  17. assert.ok(ai.x>frame.x+frame.width/2 && ai.x+ai.width<=frame.x+frame.width,`${width}px AI入口位于容器右侧`);
  18. assert.ok(ai.bottom<tabs.y,`${width}px AI入口与导航保持间距`);
  19. assert.equal(geometry['.shop-search'].borderRadius,'24px');
  20. assert.equal(geometry['.goods-card'].borderRadius,'16px');
  21. assert.equal(geometry['.catalog'].y-geometry['.shop-search'].bottom,14);
  22. const categories=page.getByRole('navigation',{name:'商品分类'});
  23. const selected=await categories.locator('[aria-current="page"]').evaluate(node=>getComputedStyle(node).backgroundColor);
  24. const inactive=await categories.locator('button:not([aria-current="page"])').first().evaluate(node=>getComputedStyle(node).backgroundColor);
  25. assert.notEqual(selected,inactive,'当前分类具有可辨认的选中状态');
  26. await categories.getByRole('button',{name:'鼠标',exact:true}).click();
  27. assert.equal(await categories.getByRole('button',{name:'鼠标',exact:true}).getAttribute('aria-current'),'page');
  28. await page.locator('.content').evaluate(node=>node.scrollTo(0,node.scrollHeight));
  29. await page.locator('.ai-float').click();
  30. await page.locator('.mobile[data-page="chat"]').waitFor();
  31. assert.equal(await page.locator('.content').evaluate(node=>node.scrollTop),0,'新页面正文从顶部显示');
  32. }
  33. console.log('分类区域、AI入口与底部布局在5组宽度下检查通过。');
  34. } finally { await browser.close(); }