49 lines
4.0 KiB
JavaScript
49 lines
4.0 KiB
JavaScript
const { chromium } = require('playwright');
|
|
const { writeFileSync } = require('node:fs');
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({ headless: true });
|
|
const findings = [];
|
|
let states = 0;
|
|
try {
|
|
const page = await browser.newPage({ reducedMotion: 'reduce' });
|
|
const errors = [];
|
|
page.on('pageerror', error => errors.push(error.message));
|
|
await page.goto(process.env.REVIEW_URL + '/admin/index.php');
|
|
await page.locator('#username').fill('admin');
|
|
await page.locator('#password').fill(process.env.REVIEW_PASSWORD);
|
|
await Promise.all([page.waitForURL('**/admin/dashboard.php'), page.locator('form button[type=submit]').first().click()]);
|
|
await page.waitForLoadState('networkidle');
|
|
for (const width of (process.env.REVIEW_WIDTH ? [Number(process.env.REVIEW_WIDTH)] : [360, 390, 768, 1024, 1440])) {
|
|
await page.setViewportSize({ width, height: 1000 });
|
|
const settingsTabs = await page.locator('[data-settings-tab]').evaluateAll(nodes => nodes.map(node => 'settings:' + node.dataset.settingsTab));
|
|
for (const tab of ['backup', 'settings', 'content', 'news', 'events', 'mails', 'media', 'icons', 'home', 'system', ...settingsTabs]) {
|
|
await page.evaluate(tab => { switchTab(tab.split(':')[0]); if (tab.includes(':')) document.querySelector('[data-settings-tab="' + tab.split(':')[1] + '"]').click(); }, tab);
|
|
await page.waitForLoadState('networkidle');
|
|
states++;
|
|
const layout = await page.evaluate(() => {
|
|
const visible = element => !element.closest('.rj-imgmgr-folder-list, .users-table-wrap') && element.getClientRects().length && getComputedStyle(element).visibility !== 'hidden' && getComputedStyle(element).opacity !== '0';
|
|
const controls = [...document.querySelectorAll('.admin-main input:not([type=checkbox]):not([type=radio]):not([type=hidden]), .admin-main select, .admin-main textarea')].filter(visible);
|
|
return {
|
|
overflow: document.documentElement.scrollWidth > innerWidth + 1,
|
|
wide: [...document.querySelectorAll('body *')].filter(visible).filter(el => el.getBoundingClientRect().right > innerWidth + 2).slice(-12).map(el => [el.tagName, el.id || el.className, Math.round(el.getBoundingClientRect().right)]),
|
|
narrow: controls.filter(element => element.getBoundingClientRect().width < 120 && !['number', 'color'].includes(element.type) && !element.classList.contains('color-hex-input')).map(element => element.id || element.name),
|
|
outside: [...document.querySelectorAll('.admin-main button, .admin-main input, .admin-main textarea, .rj-imgmgr-modal--embedded button, .rj-imgmgr-modal--embedded input')].filter(visible).filter(element => {
|
|
const rect = element.getBoundingClientRect(); return rect.right > innerWidth + 1 || rect.left < -1;
|
|
}).map(element => element.id || element.className)
|
|
};
|
|
});
|
|
if (layout.overflow || layout.narrow.length || layout.outside.length) findings.push({ width, tab, ...layout });
|
|
if (tab === 'backup' || tab === 'settings:menus' || width === 390) {
|
|
const filename = tab.replace(/[^a-z0-9_-]/gi, '-') + '-' + width + '.png';
|
|
await page.screenshot({ path: process.env.REVIEW_SCREENSHOTS + '/' + filename, fullPage: true });
|
|
}
|
|
}
|
|
}
|
|
writeFileSync(process.env.REVIEW_SCREENSHOTS + '/layout.json', JSON.stringify({ findings, errors }, null, 2));
|
|
console.log(JSON.stringify({ findings, errors }, null, 2));
|
|
if (errors.length || findings.length) process.exitCode = 1;
|
|
else console.log('PASS ' + states + ' responsive dashboard and settings states');
|
|
} finally { await browser.close(); }
|
|
})().catch(error => { console.error(error); process.exit(1); });
|