Public Access
Manifest, gamepad icon (also the new favicon, instead of the Vite logo), iOS meta tags and the tab title ToBePlayed. No service worker, so a deploy never meets an old cached bundle. The title bar color follows light and dark mode. The README also lists adding a game by name.
36 lines
1.5 KiB
JavaScript
36 lines
1.5 KiB
JavaScript
import {readFileSync} from 'node:fs';
|
|
import path from 'node:path';
|
|
import {describe, expect, it} from 'vitest';
|
|
|
|
const root = path.resolve(import.meta.dirname, '..');
|
|
const read = (file) => readFileSync(path.join(root, file));
|
|
const manifest = JSON.parse(read('public/manifest.webmanifest'));
|
|
|
|
// Width and height sit at bytes 16-23 of every PNG.
|
|
const pngSize = (file) => {
|
|
const png = read(path.join('public', file));
|
|
return `${png.readUInt32BE(16)}x${png.readUInt32BE(20)}`;
|
|
};
|
|
|
|
describe('PWA manifest', () => {
|
|
it('links every icon to a PNG of the size it claims', () => {
|
|
for (const icon of manifest.icons) {
|
|
expect(pngSize(icon.src)).toBe(icon.sizes);
|
|
}
|
|
});
|
|
|
|
it('has the icons Chrome needs to offer the install', () => {
|
|
const sizes = manifest.icons.filter((icon) => icon.purpose === 'any').map((icon) => icon.sizes);
|
|
expect(sizes).toEqual(expect.arrayContaining(['192x192', '512x512']));
|
|
expect(manifest.display).toBe('standalone');
|
|
expect(manifest.icons.some((icon) => icon.purpose === 'maskable')).toBe(true);
|
|
});
|
|
|
|
it('is linked from index.html together with the iOS icon', () => {
|
|
const html = read('index.html').toString();
|
|
expect(html).toContain('<link rel="manifest" href="/manifest.webmanifest" />');
|
|
expect(html).toContain('<link rel="apple-touch-icon" href="/apple-touch-icon.png" />');
|
|
expect(pngSize('apple-touch-icon.png')).toBe('180x180');
|
|
});
|
|
});
|