97 lines
5.4 KiB
Python
Executable File
97 lines
5.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Overview traffic/connection heading cleanup against Chromium and the bundled JS.
|
|
|
|
Runs a simulated authenticated DOM rather than a live RustProxy service.
|
|
"""
|
|
from pathlib import Path
|
|
import json
|
|
import re
|
|
from playwright.sync_api import sync_playwright
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
HTML = (ROOT / 'src/admin/web/index.html').read_text(encoding='utf-8')
|
|
CSS = (ROOT / 'src/admin/web/style.css').read_text(encoding='utf-8')
|
|
ROUTER = (ROOT / 'src/admin/router.rs').read_text(encoding='utf-8')
|
|
|
|
|
|
def app_bundle():
|
|
match = re.search(r'fn admin_app_javascript\([^)]*\)[^{]*\{', ROUTER)
|
|
assert match
|
|
body = ROUTER[match.end():]
|
|
body = body[:re.search(r'\]\s*\.join\("\\n"\)', body).start()]
|
|
result = []
|
|
for line in body.splitlines():
|
|
line = line.strip()
|
|
include = re.search(r'include_str!\("([^"]+)"\)', line)
|
|
if include:
|
|
result.append((ROOT / 'src/admin' / include.group(1)).read_text(encoding='utf-8'))
|
|
elif line == 'admin_vhosts_javascript(),':
|
|
result.append('(() => {\n' + '\n'.join(
|
|
(ROOT / 'src/admin/web/vhosts' / (name + '.js')).read_text(encoding='utf-8')
|
|
for name in ('core', 'protocol', 'health', 'rates', 'editor', 'render')) + '\n})();')
|
|
elif line.startswith('"') and line.endswith('",'):
|
|
result.append(json.loads(line[:-1]))
|
|
return '\n'.join(result)
|
|
|
|
|
|
with sync_playwright() as p:
|
|
browser = p.chromium.launch(headless=True, executable_path='/usr/bin/chromium', args=['--no-sandbox'])
|
|
bundle = app_bundle()
|
|
for width in (320, 375, 768, 1440, 1920):
|
|
page = browser.new_page(viewport={'width': width, 'height': 920})
|
|
errors = []
|
|
page.on('pageerror', lambda error: errors.append(str(error)))
|
|
page.set_content(HTML.replace('/assets/app___RUSTPROXY_ASSET_ID__.js', '')
|
|
.replace('/assets/style___RUSTPROXY_ASSET_ID__.css', ''))
|
|
page.add_style_tag(content=CSS)
|
|
page.add_script_tag(content=bundle)
|
|
page.evaluate('''() => {
|
|
document.documentElement.classList.remove('app-loading', 'app-startup-failed');
|
|
document.getElementById('workspace').hidden = false;
|
|
document.getElementById('panel-overview').hidden = false;
|
|
currentPanel = 'overview';
|
|
samples.splice(0); samples.push(1.5, 85.5, 12.3);
|
|
redrawOverviewHistoryCharts();
|
|
}''')
|
|
for density in ('normal', 'compact', 'ultra'):
|
|
for span in (3, 6):
|
|
data = page.evaluate('''({density,span}) => {
|
|
document.documentElement.dataset.dashboardDensity = density;
|
|
const visible = ['traffic_chart', 'connection_chart'];
|
|
const hidden = ADMIN_DASHBOARD_WIDGETS.filter(id => !visible.includes(id));
|
|
applyDashboardLayout([...visible,...hidden], hidden,
|
|
{traffic_chart:span,connection_chart:span});
|
|
const traffic = document.querySelector('[data-dashboard-widget="traffic_chart"]');
|
|
const connection = document.querySelector('[data-dashboard-widget="connection_chart"]');
|
|
const heading = traffic.querySelector('.card-heading');
|
|
const peak = traffic.querySelector('#chart-peak');
|
|
const peakRect = peak.getBoundingClientRect();
|
|
const cardRect = traffic.getBoundingClientRect();
|
|
const headingRect = heading.getBoundingClientRect();
|
|
return {
|
|
title: heading.querySelector('h2')?.textContent.trim(),
|
|
peak: peak.textContent,
|
|
peakInHeading: peak.parentElement === heading,
|
|
peakNotInFooter: !traffic.querySelector('.chart-footer #chart-peak'),
|
|
noTrafficEyebrow: !traffic.querySelector('.small-label'),
|
|
noTrafficLiveBadge: !traffic.querySelector('.pill.live'),
|
|
noConnectionLiveBadge: !connection.querySelector('.pill.live'),
|
|
connectionTitleIntact: !!connection.querySelector('.card-heading .small-label[data-i18n="connectionActivity"]'),
|
|
peakInsideCard: peakRect.left >= cardRect.left - 1 && peakRect.right <= cardRect.right + 1,
|
|
peakInsideHeading: peakRect.top >= headingRect.top - 1 && peakRect.bottom <= headingRect.bottom + 1,
|
|
browserOverflow: document.documentElement.scrollWidth - innerWidth,
|
|
};
|
|
}''', {'density':density,'span':span})
|
|
assert data['title'] == 'Requests per second', (width, density, span, data)
|
|
assert data['peak'] == 'max 85.5 req/s', (width, density, span, data)
|
|
for key in ('peakInHeading', 'peakNotInFooter', 'noTrafficEyebrow',
|
|
'noTrafficLiveBadge', 'noConnectionLiveBadge',
|
|
'connectionTitleIntact', 'peakInsideCard', 'peakInsideHeading'):
|
|
assert data[key], (width, density, span, key, data)
|
|
assert data['browserOverflow'] <= 2, (width, density, span, data)
|
|
assert not errors, (width, errors)
|
|
print(f'PASS traffic/connection chart headers at {width}px (all densities, spans 3 and 6)')
|
|
page.close()
|
|
browser.close()
|
|
print('PASS Overview chart heading cleanup')
|