- Let selector height adapt to model names and aliases - Add layout regression tests across languages, themes, and viewport sizes - Verify model selection, keyboard search, 1M toggles, and config updates
72 lines
4.4 KiB
JavaScript
72 lines
4.4 KiB
JavaScript
// Run Vite on port 1421, or set AGENT_MODEL_LAYOUT_TEST_URL to another local server.
|
|
const { chromium } = require(process.env.PLAYWRIGHT_MODULE || 'playwright');
|
|
const assert = require('node:assert/strict');
|
|
const path = require('node:path');
|
|
const os = require('node:os');
|
|
const base = process.env.AGENT_MODEL_LAYOUT_TEST_URL || 'http://127.0.0.1:1421';
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({ channel: 'msedge', headless: true, args: ['--no-proxy-server'] });
|
|
try {
|
|
const page = await browser.newPage();
|
|
page.setDefaultTimeout(10000);
|
|
const errors = [];
|
|
page.on('pageerror', error => errors.push(String(error)));
|
|
for (const locale of ['zh-CN', 'en', 'ja']) {
|
|
for (const theme of ['light', 'dark']) {
|
|
for (const width of [1392, 1100, 760, 480]) {
|
|
await page.setViewportSize({ width, height: 962 });
|
|
await page.goto(`${base}/tests/fixtures/agent-backups.html?client=claude-code&reset-selections&shell&claude-alias-layout&locale=${locale}&theme=${theme}`);
|
|
await page.locator('.claude-role-row[data-role=sonnet] .agent-model-trigger small').waitFor();
|
|
await page.evaluate(() => document.fonts.ready);
|
|
const issues = await page.locator('.claude-role-table').evaluate(table => {
|
|
const issues = [];
|
|
for (const row of table.querySelectorAll('.claude-role-row')) {
|
|
const trigger = row.querySelector('.agent-model-trigger');
|
|
const bounds = trigger.getBoundingClientRect();
|
|
for (const text of trigger.querySelectorAll('strong, small')) {
|
|
const rect = text.getBoundingClientRect();
|
|
if (rect.top < bounds.top - 1 || rect.bottom > bounds.bottom + 1
|
|
|| rect.left < bounds.left - 1 || rect.right > bounds.right + 1) {
|
|
issues.push(`${row.dataset.role}: model text exceeds the selector`);
|
|
}
|
|
}
|
|
const next = row.nextElementSibling?.getBoundingClientRect();
|
|
if (next && bounds.bottom > next.top + 1) issues.push(`${row.dataset.role}: selector overlaps the next row`);
|
|
if (row.scrollWidth > row.clientWidth + 1) issues.push(`${row.dataset.role}: horizontal overflow`);
|
|
const toggle = row.querySelector('.claude-inline-context').getBoundingClientRect();
|
|
if (bounds.right > toggle.left + 1) issues.push(`${row.dataset.role}: selector overlaps the context switch`);
|
|
}
|
|
return issues;
|
|
});
|
|
assert.deepEqual(issues, [], `${locale}/${theme}/${width}`);
|
|
if (locale === 'zh-CN' && theme === 'light' && [1392, 480].includes(width)) {
|
|
await page.screenshot({ path: path.join(os.tmpdir(), `claude-code-model-layout-${width}.png`), fullPage: true });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
await page.setViewportSize({ width: 1392, height: 962 });
|
|
await page.goto(`${base}/tests/fixtures/agent-backups.html?client=claude-code&reset-selections&shell&claude-alias-layout`);
|
|
const sonnet = page.locator('.claude-role-row[data-role=sonnet]');
|
|
await sonnet.locator('.agent-model-trigger small').waitFor();
|
|
await page.locator('.agent-claude-desktop-mapping-filter input').check();
|
|
const trigger = sonnet.locator('.agent-model-trigger');
|
|
await trigger.click();
|
|
await page.getByRole('option', { name: /^gpt-6\.1-sol / }).click();
|
|
assert.equal(await trigger.locator('small').count(), 0);
|
|
await trigger.focus();
|
|
await trigger.press('Enter');
|
|
await sonnet.locator('.agent-model-search input').fill('high-fast');
|
|
await page.getByRole('option', { name: /^gpt-6.1-sol-high-fast / }).click();
|
|
assert.equal(await trigger.locator('small').innerText(), 'gpt-6.1-sol');
|
|
await page.getByRole('switch', { name: 'sonnet 1M', exact: true }).check();
|
|
await page.getByRole('button', { name: '更新配置', exact: true }).click();
|
|
await page.waitForFunction(() => window.fixtureCalls.some(call => call.cmd === 'update_agent_config'
|
|
&& call.args.claudeCodeModelMappings.sonnet === 'gpt-6.1-sol-high-fast'
|
|
&& call.args.claudeCodeModelMappings.sonnet1m === true));
|
|
assert.deepEqual(errors, []);
|
|
console.log('PASS: 24 viewport/language/theme layouts, alias selection, keyboard search, context toggle and configuration update');
|
|
} finally { await browser.close(); }
|
|
})().catch(error => { console.error(error); process.exitCode = 1; });
|