92 lines
6.0 KiB
Python
Executable File
92 lines
6.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Optional real-CSS/JS Chromium regression for the horizontal Overview card ribbon.
|
|
|
|
Mocks authenticated preferences; no server or physical iOS device involved.
|
|
Run with: python tools/checks/dashboard_appearance_ribbon_0326_browser.py
|
|
"""
|
|
from pathlib import Path
|
|
from playwright.sync_api import sync_playwright
|
|
import shutil
|
|
import json
|
|
root=Path(__file__).resolve().parents[2]
|
|
html=(root/'src/admin/web/index.html').read_text()
|
|
css=(root/'src/admin/web/style.css').read_text()
|
|
prefs=(root/'src/admin/web/app/preferences.js').read_text()
|
|
registry=json.loads((root/'src/admin/web/dashboard-widgets.json').read_text())
|
|
translations=json.loads((root/'langs/pl_pl.json').read_text())['translations']
|
|
heading=html.index('data-i18n="dashboardLayout"')
|
|
section_start=html.rfind('<section class="appearance-section">',0,heading)
|
|
section_end=html.index('</section>',heading)+len('</section>')
|
|
assert section_start >= 0
|
|
source=html[section_start:section_end]
|
|
start=prefs.index('function renderDashboardWidgetSettings() {')
|
|
end=prefs.index('function refreshChartStylePalette(',start)
|
|
code=prefs[start:end]
|
|
stub='''
|
|
const $ = id => document.getElementById(id);
|
|
const el = (tag, txt, classes) => { let node=document.createElement(tag); if (txt!==undefined) node.textContent=String(txt); if (classes) node.className=classes; return node; };
|
|
const labels = __TRANSLATIONS__;
|
|
const registry = __REGISTRY__;
|
|
const ADMIN_DASHBOARD_BY_ID = new Map(registry.map(def=>[def.id,def]));
|
|
const order = registry.map(def=>def.id);
|
|
let adminPreferences = {dashboard_widgets:order, dashboard_hidden_widgets:registry.filter(def=>def.default_hidden).map(def=>def.id)};
|
|
const ADMIN_APPEARANCE_DEFAULTS = adminPreferences;
|
|
function t(key){ return labels[key] || key; }
|
|
function dashboardWidgetLabel(id) { return t(ADMIN_DASHBOARD_BY_ID.get(id)?.label_key || id); }
|
|
function normalizeDashboardWidgets(value){return Array.isArray(value)?value:order;}
|
|
function normalizeHiddenDashboardWidgets(value){return Array.isArray(value)?value:[];}
|
|
function applyDashboardLayout(order,hidden){ window.__state={order,hidden}; }
|
|
async function saveAppearancePreference(next){ Object.assign(adminPreferences,next);return {}; }
|
|
'''.replace('__TRANSLATIONS__',json.dumps(translations,ensure_ascii=False)).replace('__REGISTRY__',json.dumps(registry))
|
|
with sync_playwright() as p:
|
|
browser=p.chromium.launch(executable_path=shutil.which('chromium') or shutil.which('chromium-browser'),args=['--no-sandbox'],headless=True)
|
|
for width,height in [(1500,950),(393,850)]:
|
|
page=browser.new_page(viewport={'width':width,'height':height},device_scale_factor=1)
|
|
page.set_content('<!doctype html><html data-theme="dark" lang="pl"><head><style>'+css+'</style></head><body><main style="margin:0; padding:28px 16px; width:100%; max-width:100%; box-sizing:border-box">'+source+'</main></body></html>',wait_until='domcontentloaded')
|
|
page.add_script_tag(content=stub+code+'\nrenderDashboardWidgetSettings();')
|
|
page.wait_for_timeout(90)
|
|
metrics=page.evaluate('''() => {
|
|
const list=document.getElementById('dashboard-widget-list'), section=document.querySelector('.appearance-section');
|
|
const parent=list.closest('.dashboard-widget-settings');
|
|
return { total: list.children.length, listHeight:list.getBoundingClientRect().height,
|
|
listWidth:list.getBoundingClientRect().width, contentWidth:list.scrollWidth,
|
|
sectionHeight:section.getBoundingClientRect().height,
|
|
overflowX:getComputedStyle(list).overflowX,
|
|
firstWidth:list.firstElementChild.getBoundingClientRect().width,
|
|
density: document.querySelector('.dashboard-density-setting').getBoundingClientRect().width,
|
|
widget:parent.getBoundingClientRect().width,
|
|
viewportOverflow:document.documentElement.scrollWidth>window.innerWidth,
|
|
nextDisabled:document.getElementById('dashboard-widget-scroll-next').disabled};
|
|
}''')
|
|
print(width,'COMPACT',metrics)
|
|
assert metrics['total']==len(registry)
|
|
assert metrics['listHeight']<66,(width,metrics)
|
|
assert metrics['contentWidth']>metrics['listWidth'],(width,metrics)
|
|
assert metrics['sectionHeight'] < (320 if width>700 else 450), (width,metrics)
|
|
assert not metrics['viewportOverflow']
|
|
page.locator('#dashboard-widget-scroll-next').click()
|
|
page.wait_for_timeout(450)
|
|
pos=page.evaluate('document.getElementById("dashboard-widget-list").scrollLeft')
|
|
print(width,'scroll after next:',pos)
|
|
assert pos>10
|
|
page.locator('.dashboard-widget-setting').nth(7).locator('button.dashboard-widget-toggle').click(force=True)
|
|
page.wait_for_timeout(60)
|
|
state=page.evaluate('window.__state')
|
|
assert state and len(state['order'])==len(registry)
|
|
retained=page.evaluate('document.getElementById("dashboard-widget-list").scrollLeft')
|
|
assert retained>=pos-15,(pos,retained)
|
|
page.locator('#dashboard-widget-expand').click()
|
|
page.wait_for_timeout(60)
|
|
expanded=page.evaluate('''() => { const list = document.getElementById("dashboard-widget-list"); return { height:list.getBoundingClientRect().height, mode:getComputedStyle(list).display, count:list.children.length, expanded:document.getElementById('dashboard-widget-expand').getAttribute('aria-expanded'), prevHidden:document.getElementById('dashboard-widget-scroll-prev').hidden } }''')
|
|
print(width,'EXPANDED',expanded)
|
|
assert expanded['mode']=='grid'
|
|
assert expanded['expanded']=='true' and expanded['prevHidden']
|
|
assert expanded['height']>metrics['listHeight']*3
|
|
page.locator('#dashboard-widget-expand').click()
|
|
assert page.locator('#dashboard-widget-expand').get_attribute('aria-expanded')=='false'
|
|
outfile=str(root.parent / f'dashboard_appearance_0326_preview_{width}.png')
|
|
page.locator('.appearance-section').screenshot(path=outfile)
|
|
print('screenshot',outfile)
|
|
page.close()
|
|
browser.close()
|