修改页面,完成单页模式新增首页返回上一页按钮
This commit is contained in:
@@ -5,7 +5,11 @@ import { mkdir, mkdtemp, readFile, readdir, rm, stat, writeFile } from 'node:fs/
|
||||
import { tmpdir } from 'node:os';
|
||||
import { extname, join, resolve, sep } from 'node:path';
|
||||
|
||||
const projectRoot = resolve(import.meta.dirname, '..');
|
||||
const sourceProjectRoot = resolve(import.meta.dirname, '..');
|
||||
const projectRootArg = process.argv.find((arg) => arg.startsWith('--project-root='));
|
||||
const projectRoot = projectRootArg
|
||||
? resolve(sourceProjectRoot, projectRootArg.slice('--project-root='.length))
|
||||
: sourceProjectRoot;
|
||||
const chromePath = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';
|
||||
const genealogyId = '2062179707935264701';
|
||||
const personId = '2062179707935264702';
|
||||
@@ -27,6 +31,9 @@ const shouldCaptureNavigationAudit = process.argv.includes('--capture-navigation
|
||||
process.env.JIAPU_CAPTURE_NAVIGATION_AUDIT === '1';
|
||||
const shouldRunFullProjectAudit = process.argv.includes('--full-project-audit');
|
||||
const shouldRunProfileUxAudit = process.argv.includes('--profile-ux-audit');
|
||||
const shouldRunNavigationStructureSmoke = process.argv.includes('--navigation-structure-smoke');
|
||||
const shouldRunProfileSpacingSmoke = process.argv.includes('--profile-spacing-smoke');
|
||||
const shouldRunSiteSpacingSmoke = process.argv.includes('--site-spacing-smoke');
|
||||
const profileOperationAuditRoundArg = process.argv.find((arg) => arg.startsWith('--profile-operation-audit-round='));
|
||||
const profileOperationAuditRound = profileOperationAuditRoundArg
|
||||
? Number(profileOperationAuditRoundArg.split('=')[1])
|
||||
@@ -398,6 +405,14 @@ try {
|
||||
localStorage.removeItem('genealogy_auth_token');
|
||||
} else if (!['/login.html', '/register.html', '/forgot-password.html'].includes(location.pathname)) {
|
||||
localStorage.setItem('genealogy_auth_token', 'browser-smoke-token');
|
||||
if (browserSmokeParams.has('no-user-cache')) {
|
||||
localStorage.removeItem('genealogy_public_user_v1');
|
||||
} else {
|
||||
localStorage.setItem('genealogy_public_user_v1', JSON.stringify({
|
||||
nickName: '叶用户',
|
||||
avatarUrl: 'http://127.0.0.1:${port}/public/images/logo-mark.png'
|
||||
}));
|
||||
}
|
||||
}
|
||||
sessionStorage.setItem('genealogy_current_context_v1', JSON.stringify({ genealogyId: '${genealogyId}', genealogyName: '叶氏家谱' }));
|
||||
window.confirm = () => false;
|
||||
@@ -874,6 +889,103 @@ try {
|
||||
console.log(`BROWSER: profile operation audit ${roundName} captured ${records.length} operations and ${records.length * 2} screenshots`);
|
||||
}
|
||||
|
||||
if (shouldRunProfileSpacingSmoke || shouldRunSiteSpacingSmoke) {
|
||||
const spacingPages = [];
|
||||
const spacingPagePattern = shouldRunSiteSpacingSmoke ? /\.html$/ : /^profile-.*\.html$/;
|
||||
for (const file of (await readdir(projectRoot)).filter((name) => spacingPagePattern.test(name))) {
|
||||
const source = await readFile(resolve(projectRoot, file), 'utf8');
|
||||
if (/class="[^"]*(?:actions|toolbar|cta|auth-links)/.test(source)) spacingPages.push(file);
|
||||
}
|
||||
const spacingViolations = [];
|
||||
for (const viewport of [{ width: 1440, height: 900, mobile: false }, { width: 390, height: 844, mobile: true }]) {
|
||||
await client.send('Emulation.setDeviceMetricsOverride', { ...viewport, deviceScaleFactor: 1 });
|
||||
for (const page of spacingPages) {
|
||||
await navigate(fullAuditPageUrl(page));
|
||||
await settlePageForOperationAudit();
|
||||
const pageViolations = await evaluate(`(() => Array.from(document.querySelectorAll('.row-actions, .bottom-actions, .profile-form-actions, .toolbar, .cta, .auth-links, [class$="-actions"], [class*="-actions "]')).flatMap((actions) => {
|
||||
if (!actions.getClientRects().length) return [];
|
||||
let previous = actions.previousElementSibling;
|
||||
while (previous && !previous.getClientRects().length) previous = previous.previousElementSibling;
|
||||
if (!previous) return [];
|
||||
const previousRect = previous.getBoundingClientRect();
|
||||
const actionsRect = actions.getBoundingClientRect();
|
||||
const gap = Math.round(actionsRect.top - previousRect.bottom);
|
||||
const parentStyle = getComputedStyle(actions.parentElement);
|
||||
if (actions.parentElement.matches('.editor-field') || parentStyle.display !== 'block' || gap < -1 || gap >= 12) return [];
|
||||
return [{
|
||||
className: actions.className,
|
||||
parentClass: actions.parentElement.className,
|
||||
parentDisplay: parentStyle.display,
|
||||
parentGap: parentStyle.rowGap,
|
||||
previousClass: previous.className,
|
||||
previousTag: previous.tagName.toLowerCase(),
|
||||
gap
|
||||
}];
|
||||
}))()`);
|
||||
pageViolations.forEach((violation) => spacingViolations.push({ viewport: viewport.width, page, ...violation }));
|
||||
}
|
||||
}
|
||||
assert.deepEqual(spacingViolations, [], `页面操作区间距不足:${JSON.stringify(spacingViolations)}`);
|
||||
console.log(`BROWSER: ${spacingPages.length} ${shouldRunSiteSpacingSmoke ? 'site' : 'profile'} pages action spacing passed at desktop and mobile widths`);
|
||||
} else if (shouldRunNavigationStructureSmoke) {
|
||||
await navigate('login.html');
|
||||
const authNavigation = await evaluate(`(() => ({
|
||||
brandHref: document.querySelector('.brand')?.getAttribute('href'),
|
||||
hasRedundantControls: Boolean(document.querySelector('[data-page-navigation-controls], [data-navigation-back]'))
|
||||
}))()`);
|
||||
assert.deepEqual(authNavigation, {
|
||||
brandHref: 'index.html',
|
||||
hasRedundantControls: false
|
||||
});
|
||||
|
||||
await client.send('Emulation.setDeviceMetricsOverride', { width: 1200, height: 800, deviceScaleFactor: 1, mobile: false });
|
||||
await navigate('index.html?no-user-cache=1');
|
||||
await waitFor(async () => evaluate(`document.querySelector('.site-header .nav-user-name')?.textContent.trim() === '叶用户'`));
|
||||
const publicNavigation = await evaluate(`(() => ({
|
||||
brandHref: document.querySelector('.site-header .brand')?.getAttribute('href'),
|
||||
hasHome: Array.from(document.querySelectorAll('.site-header .nav-links a')).some((link) => link.textContent.trim() === '首页'),
|
||||
userName: document.querySelector('.site-header .nav-user-name')?.textContent.trim(),
|
||||
userHref: document.querySelector('.site-header .nav-user-entry')?.getAttribute('href'),
|
||||
hasAvatar: Boolean(document.querySelector('.site-header .nav-user-avatar img')),
|
||||
hasLegacyAccountLinks: Array.from(document.querySelectorAll('.site-header .nav-actions a')).some((link) => ['个人中心', '账户资料'].includes(link.textContent.trim())),
|
||||
hasRedundantControls: Boolean(document.querySelector('[data-page-navigation-controls], [data-navigation-back]')),
|
||||
hasHorizontalOverflow: document.documentElement.scrollWidth > document.documentElement.clientWidth
|
||||
}))()`);
|
||||
assert.deepEqual(publicNavigation, {
|
||||
brandHref: 'index.html',
|
||||
hasHome: true,
|
||||
userName: '叶用户',
|
||||
userHref: 'profile.html',
|
||||
hasAvatar: true,
|
||||
hasLegacyAccountLinks: false,
|
||||
hasRedundantControls: false,
|
||||
hasHorizontalOverflow: false
|
||||
});
|
||||
|
||||
await client.send('Emulation.setDeviceMetricsOverride', { width: 1440, height: 900, deviceScaleFactor: 1, mobile: false });
|
||||
await navigate('profile.html');
|
||||
const profileNavigation = await evaluate(`(() => ({
|
||||
brandHref: document.querySelector('.site-header .brand')?.getAttribute('href'),
|
||||
hasHome: Array.from(document.querySelectorAll('.site-header .nav-links a')).some((link) => link.textContent.trim() === '首页'),
|
||||
userName: document.querySelector('.site-header .nav-user-name')?.textContent.trim(),
|
||||
userHref: document.querySelector('.site-header .nav-user-entry')?.getAttribute('href'),
|
||||
hasAvatar: Boolean(document.querySelector('.site-header .nav-user-avatar img')),
|
||||
hasLegacyAccountLinks: Array.from(document.querySelectorAll('.site-header .nav-actions a')).some((link) => ['个人中心', '账户资料'].includes(link.textContent.trim())),
|
||||
hasRedundantControls: Boolean(document.querySelector('[data-page-navigation-controls], [data-navigation-back]')),
|
||||
hasHorizontalOverflow: document.documentElement.scrollWidth > document.documentElement.clientWidth
|
||||
}))()`);
|
||||
assert.deepEqual(profileNavigation, {
|
||||
brandHref: 'index.html',
|
||||
hasHome: true,
|
||||
userName: '叶用户',
|
||||
userHref: 'profile.html',
|
||||
hasAvatar: true,
|
||||
hasLegacyAccountLinks: false,
|
||||
hasRedundantControls: false,
|
||||
hasHorizontalOverflow: false
|
||||
});
|
||||
console.log('BROWSER: home logo and primary navigation structure passed');
|
||||
} else {
|
||||
let writesBefore;
|
||||
|
||||
await assertEmptyAuthFormBlocked({ page: 'login.html', form: '#login-password-form' });
|
||||
@@ -1405,8 +1517,9 @@ try {
|
||||
await runProfileOperationAudit();
|
||||
}
|
||||
|
||||
assert.deepEqual(consoleErrors, []);
|
||||
console.log(`BROWSER CLICK SMOKE: ${28 + contentDetailJourneys.length + inlineDetailJourneys.length + mobileRowActionPages.length + emptyEditorFlows.length + emptyManagementFlows.length + familyWorkspacePages.length + accountWorkspacePages.length + familyNavigationTargets.length + accountNavigationTargets.length} flows passed`);
|
||||
}
|
||||
assert.deepEqual(consoleErrors, []);
|
||||
} finally {
|
||||
if (client) client.close();
|
||||
const chromeExited = chrome.exitCode === null
|
||||
|
||||
Reference in New Issue
Block a user