30 lines
4.6 KiB
JavaScript
30 lines
4.6 KiB
JavaScript
/* Headless test of this app only; never attaches to the user's browser session. */
|
|||
|
|
const fs=require('fs');const path=require('path');const assert=require('assert');const {chromium}=require('playwright');
|
||
|
|
(async()=>{
|
||
|
|
const root=path.resolve(__dirname,'..');const env=fs.readFileSync(path.join(root,'.env'),'utf8');const token=env.split('\n').find(x=>x.startsWith('FRAME_FLOW_TOKEN=')).slice('FRAME_FLOW_TOKEN='.length);
|
||
|
|
const base='http://127.0.0.1:18787';const response=await fetch(base+'/api/v1/settings',{headers:{Authorization:'Bearer '+token}});const settings=await response.json();assert(settings.mock===true,'UI smoke requires Mock mode');
|
||
|
|
const browser=await chromium.launch({headless:true,executablePath:'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'});
|
||
|
|
const page=await browser.newPage({viewport:{width:1440,height:1000}});const errors=[];page.on('pageerror',e=>errors.push(e.message.replaceAll(token,'[REDACTED]')));let checks=0;
|
||
|
|
await page.goto(base);await page.locator('#api-token').fill(token);await page.locator('#login-form button').click();await page.locator('.hero').waitFor();assert(await page.locator('h2').first().innerText()==='客厅相框');checks++;
|
||
|
|
fs.mkdirSync(path.join(root,'docs/screenshots'),{recursive:true});await page.screenshot({path:path.join(root,'docs/screenshots/dashboard-light-zh.png'),fullPage:true});
|
||
|
|
await page.locator('#lang').click();await page.getByRole('heading',{name:'Dashboard',exact:true}).waitFor();checks++;
|
||
|
|
await page.locator('#theme').click();assert(await page.locator('html').getAttribute('data-theme')==='dark');checks++;
|
||
|
|
await page.screenshot({path:path.join(root,'docs/screenshots/dashboard-dark-en.png'),fullPage:true});
|
||
|
|
await page.locator('[data-page="gallery"]').click();await page.locator('.image-card').first().waitFor();await page.locator('.image-card .thumb').first().evaluate(img=>new Promise((resolve,reject)=>{if(img.complete&&img.naturalWidth)return resolve();img.onload=resolve;img.onerror=reject;}));checks++;
|
||
|
|
await page.locator('#show-name').click();await page.locator('#image-name').fill('Original Art.jpg');await page.locator('#modal-cancel').click();checks++;
|
||
|
|
await page.locator('[data-page="templates"]').click();await page.locator('.template-card').first().waitFor();assert(await page.locator('.template-card').count()===6);checks++;
|
||
|
|
await page.locator('#render-template').click();await page.locator('#template-image').waitFor({timeout:30000});assert(await page.locator('#display-template').isEnabled());checks++;
|
||
|
|
await page.locator('#display-template').click();await page.locator('[data-page="history"]').click();await page.locator('tbody tr').first().waitFor();checks++;
|
||
|
|
await page.locator('[data-page="automation"]').click();await page.locator('#new-job').click();await page.locator('#job-name').fill('UI acceptance');await page.locator('#job-form button[type=submit]').click();await page.locator('td strong').filter({hasText:'UI acceptance'}).waitFor();checks++;
|
||
|
|
await page.locator('[data-job-toggle]').first().click();await page.getByText('Paused',{exact:true}).first().waitFor();checks++;
|
||
|
|
await page.locator('[data-job-delete]').first().click();await page.locator('#modal-confirm').click();await page.locator('td strong').filter({hasText:'UI acceptance'}).waitFor({state:'hidden'});checks++;
|
||
|
|
await page.locator('[data-page="playlists"]').click();await page.locator('#new-playlist').click();await page.locator('#playlist-name').fill('UI art');await page.locator('#playlist-images').fill('1');await page.locator('#playlist-form button[type=submit]').click();await page.getByText('UI art',{exact:true}).waitFor();checks++;
|
||
|
|
await page.locator('[data-pl-delete]').click();await page.locator('#modal-confirm').click();checks++;
|
||
|
|
await page.locator('[data-page="settings"]').click();await page.locator('#theme-select').waitFor();await page.locator('#theme-select').selectOption('light');assert(await page.locator('html').getAttribute('data-theme')==='light');checks++;
|
||
|
|
await page.locator('#language-select').selectOption('zh');await page.getByRole('heading',{name:'设置',exact:true}).waitFor();checks++;
|
||
|
|
await page.setViewportSize({width:390,height:844});await page.locator('[data-page="dashboard"]').click();await page.locator('.hero').waitFor();assert(await page.evaluate(()=>document.documentElement.scrollWidth<=window.innerWidth));checks++;
|
||
|
|
await page.screenshot({path:path.join(root,'docs/screenshots/dashboard-mobile-zh.png'),fullPage:true});
|
||
|
|
assert(errors.length===0,JSON.stringify(errors));checks++;
|
||
|
|
await browser.close();console.log('Browser smoke:',checks,'passed; page errors:',errors.length);
|
||
|
|
})().catch(error=>{console.error(error.message);process.exit(1)});
|