Spaces:
Running
Running
Download test_runtime.js from codex-automatus/race: direct link, hf CLI and curl.
- Browser
- Download file 3.29 kB
-
https://huggingface.co/spaces/codex-automatus/race/resolve/refs%2Fpr%2F1/test_runtime.js
- Command line
-
hf download hf://spaces/codex-automatus/race@refs/pr/1/test_runtime.js
-
curl -L -o test_runtime.js https://huggingface.co/spaces/codex-automatus/race/resolve/refs%2Fpr%2F1/test_runtime.js
3.29 kB
| // Runtime smoke test: load the real game in headless Chromium and drive it. | |
| const puppeteer = require('puppeteer'); | |
| const path = require('path'); | |
| (async () => { | |
| const browser = await puppeteer.launch({ | |
| headless: 'new', | |
| args: ['--no-sandbox', '--disable-setuid-sandbox', '--use-gl=swiftshader', | |
| '--enable-unsafe-swiftshader', '--disable-gpu-sandbox'], | |
| }); | |
| const page = await browser.newPage(); | |
| await page.setViewport({ width: 1280, height: 720 }); | |
| const errors = []; | |
| page.on('pageerror', e => errors.push('PAGEERROR: ' + e.message)); | |
| page.on('console', m => { if (m.type() === 'error') errors.push('CONSOLE: ' + m.text()); }); | |
| const url = 'file://' + path.resolve(__dirname, 'index.html'); | |
| await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 }); | |
| await new Promise(r => setTimeout(r, 1500)); | |
| // basic state | |
| let st = await page.evaluate(() => ({ | |
| hasG: typeof G !== 'undefined', | |
| state: G.state, | |
| three: typeof THREE !== 'undefined', | |
| cars: G.cars ? G.cars.length : 0, | |
| })); | |
| console.log('BOOT:', JSON.stringify(st)); | |
| // start race | |
| await page.evaluate(() => startRace()); | |
| await new Promise(r => setTimeout(r, 500)); | |
| st = await page.evaluate(() => ({ state: G.state, raceTime: G.raceTime.toFixed(2) })); | |
| console.log('AFTER START:', JSON.stringify(st)); | |
| // hold gas + steer a bit for ~6 simulated seconds | |
| await page.keyboard.down('ArrowUp'); | |
| await new Promise(r => setTimeout(r, 3000)); | |
| await page.keyboard.down('ArrowLeft'); | |
| await new Promise(r => setTimeout(r, 1500)); | |
| await page.keyboard.up('ArrowLeft'); | |
| // use nitro briefly | |
| await page.keyboard.down('Shift'); | |
| await new Promise(r => setTimeout(r, 1200)); | |
| await page.keyboard.up('Shift'); | |
| await new Promise(r => setTimeout(r, 1500)); | |
| st = await page.evaluate(() => { | |
| const p = G.player; | |
| return { | |
| state: G.state, | |
| raceTime: +G.raceTime.toFixed(1), | |
| speed: +(Math.hypot(p.vx, p.vz) * 3.6).toFixed(0), | |
| lap: p.lap, s: Math.round(p.s), x: +p.x.toFixed(1), z: +p.z.toFixed(1), | |
| nitro: +p.nitro.toFixed(2), | |
| aiSpeeds: G.cars.filter(c => !c.isPlayer).map(a => +(a.v * 3.6).toFixed(0)), | |
| rank: getRank(), | |
| hudSpeed: document.getElementById('speed').textContent, | |
| }; | |
| }); | |
| console.log('AFTER DRIVING:', JSON.stringify(st)); | |
| await page.keyboard.up('ArrowUp'); | |
| // run 20 more seconds idle (AI keeps going), check laps progress & no NaN | |
| await new Promise(r => setTimeout(r, 20000)); | |
| st = await page.evaluate(() => { | |
| const p = G.player; | |
| const bad = [p.x, p.z, p.vx, p.vz, p.heading].some(v => !isFinite(v)); | |
| return { | |
| raceTime: +G.raceTime.toFixed(1), | |
| aiLaps: G.cars.filter(c => !c.isPlayer).map(a => a.lap), | |
| playerPos: [ +p.x.toFixed(0), +p.z.toFixed(0) ], | |
| anyNaN: bad, | |
| cam: [ +camera.position.x.toFixed(0), +camera.position.y.toFixed(0), +camera.position.z.toFixed(0) ], | |
| }; | |
| }); | |
| console.log('AFTER 20s IDLE:', JSON.stringify(st)); | |
| await page.screenshot({ path: 'shot_menu_race.png' }); | |
| console.log('ERRORS(' + errors.length + '):'); | |
| errors.slice(0, 20).forEach(e => console.log(' ' + e)); | |
| await browser.close(); | |
| process.exit(errors.length ? 1 : 0); | |
| })().catch(e => { console.error('FATAL', e); process.exit(2); }); | |