Files
Arcrun/console-ui/test/portal-os-split.test.mjs
T
cloud-worker c93ed6f0f7 fix(t72): portal 下載頁依作業系統分流(原本寫死「下載 Mac 版」)
leo 07-27 交辦第①件的一部分。B 類(改 Arcrun 本體 UI)→ **待 leo 審**,未合併。

問題:進站完成安裝清單只給「下載 Mac 版」,Windows 用戶按下去拿到 .app 的 zip,
打不開也不知道為什麼。

改動(console-ui/public/portal/index.html):
- 新增 detectOS():優先 navigator.userAgentData.platform(不受 UA 凍結影響),
  退回 platform/userAgent;iPadOS 自稱 Macintosh 用 maxTouchPoints 排除。
  **認不出來就不猜**,兩個連結都給(同「按了連到錯的機制=不友善」判準)。
- 主按鈕依 OS 換字(下載 Windows 版/Mac 版)+另一系統的小字連結。
- 首開提示依 OS 換:Windows=SmartScreen「其他資訊→仍要執行」白話說明;
  Mac=原本的右鍵→打開。
- Windows zip **尚未上鏡像**(交叉編譯已通、真機未驗)→ 沒設 config.daemonDownloadWin
  時誠實顯示「Windows 版封測驗證中」,不放 404 連結;Windows 用戶仍可改抓 Mac 版或手動打勾。
- config.js 補註解說明 daemonDownload / daemonDownloadWin 兩個 key。

驗證:console-ui/test/portal-os-split.test.mjs(自帶,node 直接跑)——
8 種 navigator 情境全過(Win Chrome/舊 Firefox、mac Safari/Chrome、iPad、Linux、Android、空值),
並印出三種 OS 各自的實際文案;index.html 主 script 區塊 node --check 語法通過。
⚠️ 未在真瀏覽器點過(沙箱無 portal session),故標待審不標完成。
2026-07-27 09:57:52 +00:00

55 lines
3.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// t72 下載頁 OS 分流單測(2026-07-27):8 種 navigator 情境 → 分流結果。
// 用法:node console-ui/test/portal-os-split.test.mjs
// 直接從 index.html 抽最大的 <script> 區塊,測 t72 新增的四個分流函式。
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const here = path.dirname(fileURLToPath(import.meta.url));
const html = fs.readFileSync(path.join(here, '..', 'public', 'portal', 'index.html'), 'utf8');
const src = html.match(/<script>([\s\S]*?)<\/script>/g)
.map((b) => b.replace(/^<script>|<\/script>$/g, ''))
.sort((a, b) => b.length - a.length)[0];
const pick = (name) => {
const i = src.indexOf('function ' + name + '(');
if (i < 0) throw new Error('找不到 ' + name);
let depth = 0, j = src.indexOf('{', i);
for (let k = j; k < src.length; k++) {
if (src[k] === '{') depth++;
else if (src[k] === '}') { depth--; if (!depth) return src.slice(i, k + 1); }
}
};
const code = ['detectOS','osLabel','firstOpenHint','otherOsLine'].map(pick).join('\n');
const esc = (s) => String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/"/g,'&quot;');
const make = (nav) => {
const fn = new Function('navigator','esc', code + '; return {detectOS,osLabel,firstOpenHint,otherOsLine};');
return fn(nav, esc);
};
const MAC='https://x/mac.zip', WIN='https://x/win.zip';
const cases = [
['Windows 11 Chrome', {userAgentData:{platform:'Windows'},platform:'Win32',userAgent:'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',maxTouchPoints:0}, 'win'],
['Windows 舊 Firefox(無 userAgentData', {platform:'Win32',userAgent:'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Firefox/128',maxTouchPoints:0}, 'win'],
['macOS Safari', {platform:'MacIntel',userAgent:'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Safari/605',maxTouchPoints:0}, 'mac'],
['macOS Chrome (UA-CH)', {userAgentData:{platform:'macOS'},platform:'MacIntel',userAgent:'Mozilla/5.0 (Macintosh) Chrome/141',maxTouchPoints:0}, 'mac'],
['iPad(自稱 Macintosh,有觸控)', {platform:'MacIntel',userAgent:'Mozilla/5.0 (Macintosh; Intel Mac OS X) Safari',maxTouchPoints:5}, 'unknown'],
['Linux', {platform:'Linux x86_64',userAgent:'Mozilla/5.0 (X11; Linux x86_64)',maxTouchPoints:0}, 'unknown'],
['Android', {platform:'Linux armv8l',userAgent:'Mozilla/5.0 (Linux; Android 14)',maxTouchPoints:5}, 'unknown'],
['什麼都沒有', {maxTouchPoints:0}, 'unknown'],
];
let fail = 0;
for (const [name, nav, want] of cases) {
const m = make(nav);
const got = m.detectOS();
const ok = got === want;
if (!ok) fail++;
console.log(`${ok?'✅':'❌'} ${name.padEnd(34)}${got} (期望 ${want})`);
}
console.log('\n--- 各情境實際顯示的文字 ---');
for (const os of ['win','mac','unknown']) {
const m = make({});
console.log(`\n[${os}] 主按鈕:下載 ${m.osLabel(os)}版`);
console.log(` 首開提示:${m.firstOpenHint(os)}`);
console.log(` 另一個系統(Win zip 已上架):${m.otherOsLine(os, MAC, WIN) || '(不顯示)'}`);
console.log(` 另一個系統(Win zip 未上架=現況):${m.otherOsLine(os, MAC, '') || '(不顯示)'}`);
}
process.exit(fail ? 1 : 0);