|
| 1 | +const test = require('node:test'); |
| 2 | +const assert = require('node:assert/strict'); |
| 3 | +const http = require('node:http'); |
| 4 | +const path = require('node:path'); |
| 5 | +const serveStatic = require('serve-static'); |
| 6 | +const {chromium} = require('playwright'); |
| 7 | + |
| 8 | +const TILES = path.join(__dirname, '..', 'integration', 'tiles'); |
| 9 | +const PROVIDER_DIST = path.join(__dirname, '..', '..', 'plugins', 'mapbox-gl-pmtiles-provider', 'dist'); |
| 10 | + |
| 11 | +function serve(root) { |
| 12 | + const middlewares = [serveStatic(root), serveStatic(PROVIDER_DIST), serveStatic(TILES)]; |
| 13 | + return http.createServer((req, res) => { |
| 14 | + const notFound = () => { res.writeHead(404); res.end(); }; |
| 15 | + const middleware = middlewares.reduceRight((next, serve) => () => serve(req, res, next), notFound); |
| 16 | + middleware(); |
| 17 | + }); |
| 18 | +} |
| 19 | + |
| 20 | +async function expectNoErrors(browser, port, file) { |
| 21 | + const tab = await browser.newPage(); |
| 22 | + try { |
| 23 | + const errors = []; |
| 24 | + tab.on('pageerror', (e) => errors.push(e.message)); |
| 25 | + tab.on('console', (m) => { if (m.type() === 'error') errors.push(m.text()); }); |
| 26 | + await tab.goto(`http://localhost:${port}/${file}`); |
| 27 | + const gotTiles = await tab.waitForResponse((r) => r.url().endsWith('.pmtiles'), {timeout: 8000}).then(() => true, () => false); |
| 28 | + // A broken worker import surfaces just after the .pmtiles fetch; let it flush. |
| 29 | + await tab.waitForTimeout(100); |
| 30 | + assert.deepEqual(errors, []); |
| 31 | + assert.ok(gotTiles, 'page produced no .pmtiles request within 8s'); |
| 32 | + } finally { |
| 33 | + try { await tab.close(); } catch { /* a crashed tab must not mask the assertion */ } |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +function testPages({label, root, files}) { |
| 38 | + let browser, server, port; |
| 39 | + test.before(async () => { |
| 40 | + server = serve(root); |
| 41 | + await new Promise((resolve) => server.listen(0, resolve)); |
| 42 | + ({port} = server.address()); |
| 43 | + try { |
| 44 | + // CI installs full chromium via `playwright install --no-shell`; match vitest.config.base.ts. |
| 45 | + browser = await chromium.launch({channel: process.env.CI === 'true' ? 'chromium' : 'chrome'}); |
| 46 | + } catch (e) { |
| 47 | + throw new Error(`Chromium failed to launch (is Playwright installed? in CI, run under xvfb): ${e.message}`); |
| 48 | + } |
| 49 | + }); |
| 50 | + test.after(async () => { |
| 51 | + if (browser) await browser.close(); |
| 52 | + if (server) await new Promise((resolve) => server.close(resolve)); |
| 53 | + }); |
| 54 | + for (const file of files) { |
| 55 | + const name = file.replace('.html', ''); |
| 56 | + test(`${label}-${name} build loads a PMTiles source without errors`, {timeout: 15000}, () => expectNoErrors(browser, port, file)); |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +module.exports = {testPages}; |
0 commit comments