Download app/tests/http-live.mjs from Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP: direct link, hf CLI and curl.
- Browser
- Download file 6.45 kB
-
https://huggingface.co/spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/resolve/main/app/tests/http-live.mjs
- Command line
-
hf download hf://spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/app/tests/http-live.mjs
-
curl -L -o http-live.mjs https://huggingface.co/spaces/Mike0021/MiniCPM5-2B-WebGPU-Pi-HTTP/resolve/main/app/tests/http-live.mjs
6.45 kB
| import { chromium } from 'playwright'; | |
| import fs from 'node:fs/promises'; | |
| import assert from 'node:assert/strict'; | |
| const root = new URL('../..', import.meta.url).pathname; | |
| const url = process.argv[2] ?? 'https://mike0021-minicpm5-2b-webgpu-pi-http.static.hf.space/'; | |
| const result = { date: new Date().toISOString(), url, cases: [], errors: [], requests: [] }; | |
| const context = await chromium.launchPersistentContext(root + '/validation/http-browser-profile', { | |
| executablePath: '/usr/bin/chromium', headless: true, viewport: { width: 1440, height: 1000 }, | |
| args: ['--enable-unsafe-webgpu', '--use-angle=vulkan', '--enable-features=Vulkan', '--disable-vulkan-surface'], | |
| }); | |
| context.setDefaultTimeout(30_000); | |
| const page = await context.newPage(); | |
| page.on('pageerror', e => result.errors.push(e.message)); | |
| context.on('request', r => { if (!r.url().startsWith(new URL(url).origin)) result.requests.push({ url: r.url(), method: r.method() }); }); | |
| const rpc = (action, args) => page.evaluate(({ action, args }) => window.browserPi.rpc(action, args), { action, args }); | |
| const save = () => fs.writeFile(root + '/validation/http-shell-live.json', JSON.stringify(result, null, 2) + '\n'); | |
| const cases = [ | |
| ['new-host-json', 'curl -fsS https://dummyjson.com/products/1 -o product.json && jq -r .id product.json', r => r.exitCode === 0 && r.stdout.trim() === '1'], | |
| ['public-gist', 'curl -fsS https://gist.githubusercontent.com/mbostock/4063269/raw/b111d979d7fcd0fabb554cccd37caf2691f31706/flare.csv -o gist.csv && head -n 1 gist.csv', r => r.exitCode === 0 && r.stdout.trim() === 'id,value'], | |
| ['json-get-save', 'curl -fsS https://jsonplaceholder.typicode.com/todos/1 -o todo.json && jq -r .title todo.json', r => r.exitCode === 0 && r.stdout.includes('delectus aut autem')], | |
| ['github-pipeline', "set -o pipefail; curl -fsS https://api.github.com/repos/huggingface/transformers.js | jq -r '.full_name, .license.spdx_id'", r => r.exitCode === 0 && r.stdout.includes('huggingface/transformers.js')], | |
| ['hf-metadata', 'set -o pipefail; curl -fsS https://huggingface.co/api/models/openbmb/MiniCPM5-2B | jq -r .id', r => r.exitCode === 0 && /openbmb\/MiniCPM5-2B/i.test(r.stdout)], | |
| ['raw-github', 'curl -fsS https://raw.githubusercontent.com/huggingface/transformers.js/main/package.json -o package.json && jq -r .name package.json', r => r.exitCode === 0 && r.stdout.includes('@huggingface/transformers')], | |
| ['head', 'curl -I https://jsonplaceholder.typicode.com/todos/1', r => r.exitCode === 0 && r.stdout.includes('200')], | |
| ['post-json', `set -o pipefail; curl -fsS https://httpbin.org/post -H 'Content-Type: application/json' -d '{"demo":"browser-http","value":144}' | jq -c .json`, r => r.exitCode === 0 && r.stdout.includes('browser-http') && r.stdout.includes('144')], | |
| ['request-headers', "set -o pipefail; curl -fsS https://httpbin.org/headers -H 'X-Demo: browser-http' | jq -r '.headers[\"X-Demo\"]'", r => r.exitCode === 0 && r.stdout.trim() === 'browser-http'], | |
| ['http-404', 'curl -fsS https://jsonplaceholder.typicode.com/does-not-exist', r => r.exitCode !== 0 && /404/.test(r.stderr)], | |
| ['http-rejected', 'curl -fsS http://example.com/', r => r.exitCode !== 0 && /Only HTTPS/.test(r.stderr)], | |
| ['cors-failure', 'curl -fsS https://huggingface.co/', r => r.exitCode !== 0 && /CORS/.test(r.stderr)], | |
| ['redirect-failure', 'curl -fsSL https://httpbin.org/redirect-to?url=https%3A%2F%2Fhttpbin.org%2Fget', r => r.exitCode !== 0 && /redirect/i.test(r.stderr)], | |
| ['timeout', 'curl -fsS --max-time 1 https://httpbin.org/delay/5', r => r.exitCode !== 0 && /timed out/i.test(r.stderr)], | |
| ['failed-pipeline', 'set -o pipefail; curl -fsS http://example.com/ | jq .', r => r.exitCode !== 0], | |
| ]; | |
| try { | |
| await page.goto(url); await page.waitForFunction(() => window.browserPi?.terminal); await page.evaluate(() => window.browserPi.ready); | |
| assert.match(await page.locator('.workspace-note').textContent(), /any HTTPS URL/); | |
| for (const [name, command, check] of cases) { | |
| const start = Date.now(); const response = await rpc('shell', { command }); | |
| const entry = { name, command, elapsedMs: Date.now() - start, stdout: response.stdout, stderr: response.stderr, exitCode: response.exitCode, passed: check(response) }; | |
| result.cases.push(entry); console.log(JSON.stringify(entry)); await save(); | |
| } | |
| const start = Date.now(); const pending = rpc('shell', { command: 'curl -fsS https://httpbin.org/delay/7' }); | |
| await page.waitForFunction(() => window.browserPi.busy); await page.waitForTimeout(200); await rpc('stop'); | |
| let cancelled; try { cancelled = await pending; } catch(e) { cancelled = { stderr: e.message, exitCode: 1 }; } | |
| result.cases.push({ name: 'cancel', elapsedMs: Date.now() - start, stdout: cancelled.stdout, stderr: cancelled.stderr, exitCode: cancelled.exitCode, passed: cancelled.exitCode !== 0 && Date.now() - start < 2500 }); | |
| await page.locator('#command').fill('curl -fsS https://jsonplaceholder.typicode.com/todos/1 -o todo.json && jq . todo.json'); | |
| await page.locator('#shell-run').click(); | |
| await page.waitForFunction(() => !window.browserPi.busy && document.querySelector('.shell-entry:last-child .shell-status.success')); | |
| await page.screenshot({ path: root + '/validation/http-desktop.png', fullPage: true }); | |
| await page.reload(); await page.waitForFunction(() => window.browserPi); await page.evaluate(() => window.browserPi.ready); | |
| const saved = await rpc('read', { path: '/workspace/todo.json' }); | |
| result.cases.push({ name: 'file-survives-reload', passed: JSON.parse(saved).title === 'delectus aut autem' }); | |
| await page.setViewportSize({ width: 390, height: 844 }); | |
| await page.screenshot({ path: root + '/validation/http-mobile.png', fullPage: true }); | |
| result.mobileOverflow = await page.evaluate(() => document.documentElement.scrollWidth > innerWidth); | |
| result.device = await page.evaluate(async () => { const a = await navigator.gpu?.requestAdapter({powerPreference:'high-performance'}); return a ? { vendor:a.info.vendor, architecture:a.info.architecture, features:[...a.features] } : null; }); | |
| result.passed = result.cases.every(c => c.passed) && !result.errors.length && !result.mobileOverflow; | |
| console.log('SUMMARY', JSON.stringify({passed:result.passed, cases:result.cases.length, device:result.device, errors:result.errors})); | |
| } catch (e) { result.failure = e.stack; console.log('FAIL',e.stack); process.exitCode=1; } | |
| finally { await save(); await context.close(); } | |