Update Pier_v1 project
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
1 parent
f25e36c050
commit
ad73ddec2b
2476 files changed
+3423
-4902
No files matched your search
@@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Headless Chrome screenshot of the sample page (WSL2 → Windows Chrome).
|
||||
# Usage: scripts/capture-sample.sh <output.png> [url]
|
||||
# Requires the dev server: npm run dev -- --host 127.0.0.1 --port 5173
|
||||
set -euo pipefail
|
||||
OUT_WSL="${1:?output png path (WSL path)}"
|
||||
URL="${2:-http://127.0.0.1:5173/?sample=1}"
|
||||
CHROME="/mnt/c/Program Files/Google/Chrome/Application/chrome.exe"
|
||||
mkdir -p "$(dirname "$OUT_WSL")"
|
||||
timeout 200 "$CHROME" --headless=new --no-sandbox --use-gl=angle --use-angle=swiftshader \
|
||||
--enable-unsafe-swiftshader --enable-logging=stderr --v=0 --window-size=1600,1000 \
|
||||
--timeout=45000 --screenshot="$(wslpath -w "$OUT_WSL")" "$URL"
|
||||
@@ -1,43 +0,0 @@
|
||||
// Clicks the template download button in the import dialog through Chrome DevTools
|
||||
// and reports the saved file. Run with Windows Node (same machine as Chrome):
|
||||
// node verify-template-download.cjs "C:\\Users\\...\\Temp\\verify-downloads"
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const DL_DIR = process.argv[2];
|
||||
const CDP = 'http://127.0.0.1:9444';
|
||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
|
||||
async function main() {
|
||||
fs.mkdirSync(DL_DIR, { recursive: true });
|
||||
const page = (await (await fetch(`${CDP}/json`)).json()).find((t) => t.type === 'page');
|
||||
const ws = new WebSocket(page.webSocketDebuggerUrl);
|
||||
await new Promise((res, rej) => { ws.onopen = res; ws.onerror = rej; });
|
||||
let seq = 0;
|
||||
const waiting = new Map();
|
||||
ws.onmessage = (ev) => {
|
||||
const m = JSON.parse(ev.data);
|
||||
if (m.id && waiting.has(m.id)) { waiting.get(m.id)(m); waiting.delete(m.id); }
|
||||
};
|
||||
const send = (method, params = {}) => new Promise((res) => {
|
||||
const id = ++seq; waiting.set(id, res); ws.send(JSON.stringify({ id, method, params }));
|
||||
});
|
||||
const evalJs = async (expression) => {
|
||||
const r = await send('Runtime.evaluate', { expression, awaitPromise: true, returnByValue: true });
|
||||
if (r.result.exceptionDetails) throw new Error(JSON.stringify(r.result.exceptionDetails).slice(0, 300));
|
||||
return r.result.result.value;
|
||||
};
|
||||
await send('Page.enable');
|
||||
await send('Runtime.enable');
|
||||
await send('Browser.setDownloadBehavior', { behavior: 'allow', downloadPath: DL_DIR, eventsEnabled: false });
|
||||
await send('Page.navigate', { url: 'http://127.0.0.1:5173/' });
|
||||
await sleep(4000);
|
||||
await evalJs(`document.getElementById('open-import').click()`);
|
||||
await sleep(500);
|
||||
await evalJs(`document.getElementById('download-template').click()`);
|
||||
await sleep(4000);
|
||||
const files = fs.readdirSync(DL_DIR);
|
||||
console.log('DOWNLOADED', JSON.stringify(files));
|
||||
for (const f of files) console.log('SIZE', f, fs.statSync(path.join(DL_DIR, f)).size);
|
||||
ws.close();
|
||||
}
|
||||
main().catch((e) => { console.error('FAILED', e); process.exit(1); });
|
||||
@@ -1,113 +0,0 @@
|
||||
// UI verification driven through the Chrome DevTools Protocol.
|
||||
// Run with Windows Node (same machine as Chrome), e.g.:
|
||||
// node verify-ui.cjs "C:\\Users\\...\\input.xlsx" "\\\\wsl.localhost\\Ubuntu\\...\\shots"
|
||||
// Chrome must be started with --remote-debugging-port=9444 (see DOC/05_검증).
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const APP_URL = process.env.APP_URL || 'http://127.0.0.1:5173/';
|
||||
const CDP = process.env.CDP || 'http://127.0.0.1:9444';
|
||||
const INPUT_FILE = process.argv[2];
|
||||
const OUT_DIR = process.argv[3];
|
||||
if (!INPUT_FILE || !OUT_DIR) throw new Error('INPUT_FILE and OUT_DIR are required');
|
||||
|
||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
|
||||
async function main() {
|
||||
const targets = await (await fetch(`${CDP}/json`)).json();
|
||||
const page = targets.find((t) => t.type === 'page');
|
||||
if (!page) throw new Error('no page target');
|
||||
const ws = new WebSocket(page.webSocketDebuggerUrl);
|
||||
await new Promise((res, rej) => {
|
||||
ws.onopen = res;
|
||||
ws.onerror = rej;
|
||||
});
|
||||
|
||||
let seq = 0;
|
||||
const waiting = new Map();
|
||||
// Console and exception events, collected from the first navigation onward (V10 ③).
|
||||
const consoleEvents = [];
|
||||
ws.onmessage = (ev) => {
|
||||
const m = JSON.parse(ev.data);
|
||||
if (m.id && waiting.has(m.id)) {
|
||||
waiting.get(m.id)(m);
|
||||
waiting.delete(m.id);
|
||||
} else if (m.method === 'Runtime.consoleAPICalled' && ['error', 'warning'].includes(m.params.type)) {
|
||||
const text = m.params.args.map((a) => a.value ?? a.description ?? '').join(' ');
|
||||
consoleEvents.push(`console.${m.params.type}: ${text}`);
|
||||
} else if (m.method === 'Runtime.exceptionThrown') {
|
||||
const d = m.params.exceptionDetails;
|
||||
consoleEvents.push(`exception: ${d.exception?.description || d.text}`);
|
||||
} else if (m.method === 'Log.entryAdded' && ['error', 'warning'].includes(m.params.entry.level)) {
|
||||
consoleEvents.push(`log.${m.params.entry.level}: ${m.params.entry.text} ${m.params.entry.url || ''}`.trim());
|
||||
}
|
||||
};
|
||||
const send = (method, params = {}) =>
|
||||
new Promise((res) => {
|
||||
const id = ++seq;
|
||||
waiting.set(id, res);
|
||||
ws.send(JSON.stringify({ id, method, params }));
|
||||
});
|
||||
const evalJs = async (expression) => {
|
||||
const r = await send('Runtime.evaluate', { expression, awaitPromise: true, returnByValue: true });
|
||||
if (r.result.exceptionDetails) throw new Error(JSON.stringify(r.result.exceptionDetails).slice(0, 400));
|
||||
return r.result.result.value;
|
||||
};
|
||||
const shot = async (name) => {
|
||||
const r = await send('Page.captureScreenshot', { format: 'png' });
|
||||
fs.writeFileSync(path.join(OUT_DIR, name), Buffer.from(r.result.data, 'base64'));
|
||||
console.log(`SHOT ${name}`);
|
||||
};
|
||||
|
||||
await send('Page.enable');
|
||||
await send('Runtime.enable');
|
||||
await send('Log.enable');
|
||||
await send('DOM.enable');
|
||||
await send('Emulation.setDeviceMetricsOverride', { width: 1600, height: 1000, deviceScaleFactor: 1, mobile: false });
|
||||
await send('Page.navigate', { url: APP_URL });
|
||||
await sleep(4000);
|
||||
|
||||
// V11 — dialog with the user's three-sheet workbook.
|
||||
await evalJs(`document.getElementById('open-import').click()`);
|
||||
await sleep(500);
|
||||
await evalJs(`(() => { const i = document.getElementById('project-name'); i.value = '운곡교 검증';
|
||||
i.dispatchEvent(new Event('input')); return true; })()`);
|
||||
const doc = await send('DOM.getDocument', { depth: -1 });
|
||||
const q = await send('DOM.querySelector', { nodeId: doc.result.root.nodeId, selector: '#file' });
|
||||
await send('DOM.setFileInputFiles', { nodeId: q.result.nodeId, files: [INPUT_FILE] });
|
||||
await sleep(3000);
|
||||
|
||||
console.log('SHEETS_TEXT_BEGIN');
|
||||
console.log(await evalJs(`document.getElementById('sheets').innerText`));
|
||||
console.log('SHEETS_TEXT_END');
|
||||
console.log('SELECTED', await evalJs(`document.getElementById('dlg-selected').textContent`));
|
||||
console.log('APPLY', await evalJs(`(() => { const b = document.getElementById('dlg-apply');
|
||||
return b.textContent + ' | disabled=' + b.disabled; })()`));
|
||||
await shot('v11_dialog_user_file.png');
|
||||
|
||||
await evalJs(`document.getElementById('dlg-apply').click()`);
|
||||
await sleep(2000);
|
||||
console.log('STATUS', await evalJs(`document.getElementById('status').textContent`));
|
||||
console.log('PIERS', await evalJs(`[...document.querySelectorAll('#pier-items li')].map(li => li.textContent.trim()).join(' | ')`));
|
||||
console.log('RESULT_AXIS', await evalJs(`document.getElementById('res-axis').innerText.replace(/\\n+/g, ' / ')`));
|
||||
console.log('RESULT_FOUND', await evalJs(`document.getElementById('res-found').innerText.replace(/\\n+/g, ' / ')`));
|
||||
await shot('v11_main_user_file.png');
|
||||
|
||||
// V10 ② — the four view presets.
|
||||
for (const label of ['정면', '측면', '평면', '아이소']) {
|
||||
await evalJs(`[...document.querySelectorAll('#views button')].find((b) => b.textContent === '${label}').click()`);
|
||||
await sleep(1500);
|
||||
await shot(`v10_view_${label}.png`);
|
||||
console.log('PRESSED', label, await evalJs(`[...document.querySelectorAll('#views button')].filter((b) => b.getAttribute('aria-pressed') === 'true').map((b) => b.textContent).join(',')`));
|
||||
}
|
||||
|
||||
// V10 ③ — every console error/warning and uncaught exception seen during the run above.
|
||||
console.log(`CONSOLE_EVENTS ${consoleEvents.length}`);
|
||||
for (const e of consoleEvents) console.log(` ${e}`);
|
||||
ws.close();
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
console.error('FAILED', e);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in new issue
Block a user