修改页面,完成单页模式新增首页返回上一页按钮
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const test = require('node:test');
|
||||
|
||||
const createConfig = require('../config.js');
|
||||
const projectRoot = path.resolve(__dirname, '..');
|
||||
|
||||
function read(relativePath) {
|
||||
return fs.readFileSync(path.join(projectRoot, relativePath), 'utf8');
|
||||
}
|
||||
|
||||
test('NavigationUtil 在隔离的新窗口中打开有效地址', () => {
|
||||
const openedWindow = { opener: 'source-window' };
|
||||
const calls = [];
|
||||
const root = {
|
||||
location: { hostname: 'localhost', port: '5500' },
|
||||
open(...args) {
|
||||
calls.push(args);
|
||||
return openedWindow;
|
||||
}
|
||||
};
|
||||
|
||||
createConfig(root);
|
||||
const result = root.NavigationUtil.open('profile.html');
|
||||
|
||||
assert.equal(result, openedWindow);
|
||||
assert.deepEqual(calls, [['profile.html', '_blank', 'noopener']]);
|
||||
assert.equal(openedWindow.opener, null);
|
||||
});
|
||||
|
||||
test('NavigationUtil 拒绝可执行协议', () => {
|
||||
let openCount = 0;
|
||||
const root = {
|
||||
location: { hostname: 'localhost', port: '5500' },
|
||||
open() {
|
||||
openCount += 1;
|
||||
}
|
||||
};
|
||||
|
||||
createConfig(root);
|
||||
assert.equal(root.NavigationUtil.open('javascript:alert(1)'), null);
|
||||
assert.equal(root.NavigationUtil.open('data:text/html,unsafe'), null);
|
||||
assert.equal(openCount, 0);
|
||||
});
|
||||
|
||||
test('所有页面在公共交互脚本前加载全站跳转配置', () => {
|
||||
const htmlFiles = fs.readdirSync(projectRoot).filter((file) => file.endsWith('.html'));
|
||||
|
||||
htmlFiles.forEach((file) => {
|
||||
const source = read(file);
|
||||
const configIndex = source.indexOf('<script src="config.js"></script>');
|
||||
const effectsIndex = source.indexOf('<script src="public/js/page-effects.js"></script>');
|
||||
|
||||
assert.ok(configIndex >= 0, `${file} 缺少 config.js`);
|
||||
assert.ok(effectsIndex > configIndex, `${file} 必须先加载 config.js`);
|
||||
});
|
||||
});
|
||||
|
||||
test('全站链接覆盖初始和动态生成的有效链接', () => {
|
||||
const source = read('public/js/page-effects.js');
|
||||
|
||||
assert.match(source, /link\.target = "_blank"/);
|
||||
assert.match(source, /link\.setAttribute\("rel", \[\.\.\.relValues, "noopener"\]/);
|
||||
assert.match(source, /new MutationObserver/);
|
||||
assert.match(source, /attributeFilter: \["href", "target", "download"\]/);
|
||||
});
|
||||
|
||||
test('Logo 和首页提供稳定入口,主导航不注入重复返回操作', () => {
|
||||
const htmlFiles = fs.readdirSync(projectRoot).filter((file) => file.endsWith('.html'));
|
||||
const effects = read('public/js/page-effects.js');
|
||||
const profileCommon = read('public/js/profile-common.js');
|
||||
|
||||
htmlFiles.forEach((file) => {
|
||||
const source = read(file);
|
||||
const brandLinks = [...source.matchAll(/<a\s+class="[^"]*\bbrand\b[^"]*"\s+href="([^"]+)"/g)];
|
||||
|
||||
brandLinks.forEach((match) => {
|
||||
assert.equal(match[1], 'index.html', `${file} 的 Logo 没有指向首页`);
|
||||
});
|
||||
});
|
||||
assert.doesNotMatch(effects, /data-page-navigation-controls|data-navigation-back/);
|
||||
assert.match(profileCommon, /\{ label: '首页', href: 'index\.html' \}/);
|
||||
assert.match(profileCommon, /\.attr\('href', 'index\.html'\)/);
|
||||
assert.doesNotMatch(profileCommon, /data-navigation-back/);
|
||||
});
|
||||
|
||||
test('登录态顶栏以头像和昵称作为唯一账户入口', () => {
|
||||
const effects = read('public/js/page-effects.js');
|
||||
const authPages = read('public/js/auth-pages.js');
|
||||
const profilePages = read('public/js/profile-pages.js');
|
||||
|
||||
assert.match(effects, /className = "nav-user-entry"/);
|
||||
assert.match(effects, /className = "nav-user-avatar"/);
|
||||
assert.match(effects, /name\.textContent = user\.nickName/);
|
||||
assert.doesNotMatch(effects, /loginLink\.textContent = "个人中心"/);
|
||||
assert.doesNotMatch(effects, /registerLink\.textContent = "账户资料"/);
|
||||
assert.match(authPages, /storeUser\(await api\.currentProfile\(\)\)/);
|
||||
assert.match(profilePages, /PublicNavigation\.storeUser\(profile\)/);
|
||||
});
|
||||
|
||||
test('业务脚本不再直接覆盖当前窗口地址', () => {
|
||||
const scriptsDirectory = path.join(projectRoot, 'public', 'js');
|
||||
const scriptFiles = fs.readdirSync(scriptsDirectory).filter((file) => file.endsWith('.js'));
|
||||
|
||||
scriptFiles.forEach((file) => {
|
||||
assert.doesNotMatch(
|
||||
read(path.join('public', 'js', file)),
|
||||
/(?:root|window)\.location\.(?:href\s*=|replace\()/,
|
||||
`${file} 仍在当前窗口跳转`
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user