Mercurial
diff hg-web/e2e/app_e2e_test.js @ 224:3007ef5fc0ed hg-web
[hg-web] Simplify visuals and preview static files
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Sun, 02 Aug 2026 13:51:11 -0700 |
| parents | 0e7b9464248d |
| children | 70de0c80d093 |
line wrap: on
line diff
--- a/hg-web/e2e/app_e2e_test.js Sun Aug 02 10:07:40 2026 -0700 +++ b/hg-web/e2e/app_e2e_test.js Sun Aug 02 13:51:11 2026 -0700 @@ -73,6 +73,17 @@ ); fs.writeFileSync(path.join(root, 'docs', 'README.md'), '# Documentation\n\nNested README.\n'); fs.writeFileSync(path.join(root, 'src', 'main.c'), 'int main(void) { return 0; }\n'); + fs.writeFileSync( + path.join(root, 'pixel.png'), + Buffer.from( + 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAusB9Wl2nWQAAAAASUVORK5CYII=', + 'base64', + ), + ); + fs.writeFileSync(path.join(root, 'movie.mp4'), Buffer.from('00000018667479706d703432', 'hex')); + fs.writeFileSync(path.join(root, 'sound.mp3'), Buffer.from('ID3')); + fs.writeFileSync(path.join(root, 'document.pdf'), Buffer.from('%PDF-1.4\n%%EOF\n')); + fs.writeFileSync(path.join(root, 'archive.bin'), Buffer.from([0, 1, 2, 3])); run('hg', ['--repository', root, 'add'], options); run('hg', ['--repository', root, 'commit', '-u', 'Test User <[email protected]>', '-m', 'Initial fixture'], options); const firstNode = run('hg', ['--repository', root, 'log', '-r', '.', '-T', '{node}'], options); @@ -178,6 +189,9 @@ assert.equal(response.status, 200, `${pathname} static asset`); assert.ok((await response.arrayBuffer()).byteLength > 0, `${pathname} is non-empty`); } + for (const pathname of ['/hg-web-background.jpg', '/pencil_texture.png']) { + assert.equal((await fetch(`${BASE_URL}${pathname}`)).status, 404); + } const rootList = await assertJson('/api/repo/list'); assert.ok(rootList.directories.some(entry => entry.basename === 'docs')); @@ -190,6 +204,28 @@ assert.equal(fileResponse.status, 200); assert.match(await fileResponse.text(), /int main/); + for (const [filename, contentType, disposition] of [ + ['pixel.png', 'image/png', 'inline'], + ['movie.mp4', 'video/mp4', 'inline'], + ['sound.mp3', 'audio/mpeg', 'inline'], + ['document.pdf', 'application/pdf', 'inline'], + ['archive.bin', 'application/octet-stream', 'attachment'], + ]) { + const response = await fetch( + `${BASE_URL}/api/repo/file?path=${encodeURIComponent(filename)}`, + ); + assert.equal(response.status, 200, `${filename} response`); + assert.match(response.headers.get('content-type') || '', new RegExp(`^${contentType}`)); + assert.equal(response.headers.get('content-disposition'), disposition); + assert.equal(response.headers.get('x-content-type-options'), 'nosniff'); + assert.ok((await response.arrayBuffer()).byteLength > 0); + } + const binaryResponse = await fetch(`${BASE_URL}/api/repo/file?path=archive.bin`); + assert.deepEqual( + Buffer.from(await binaryResponse.arrayBuffer()), + Buffer.from([0, 1, 2, 3]), + ); + const readmeResponse = await fetch(`${BASE_URL}/api/repo/readme?path=docs`); assert.equal(readmeResponse.status, 200); assert.match(await readmeResponse.text(), /Nested README/); @@ -234,6 +270,12 @@ await page.getByText('Recent Commits').waitFor(); await page.getByText('Repository Files').waitFor(); assert.equal(await page.evaluate(() => window.__hgWebXss), undefined); + assert.equal( + await page.locator('.graph-container').evaluate( + element => getComputedStyle(element).backgroundImage, + ), + 'none', + ); await page.locator('.theme-toggle').click(); }); @@ -268,6 +310,21 @@ assert.equal(await page.getByText('Documentation').count(), 0); assert.equal(delayedReadmeRequested, true); + await page.getByRole('link', { name: 'pixel.png' }).click(); + const image = page.locator('.static-file-image'); + await image.waitFor(); + await image.evaluate(element => { + const imageElement = element; + if (imageElement.complete) return; + return new Promise((resolve, reject) => { + imageElement.addEventListener('load', resolve, { once: true }); + imageElement.addEventListener('error', reject, { once: true }); + }); + }); + assert.equal(await image.evaluate(element => element.naturalWidth), 1); + await page.getByRole('dialog', { name: 'Preview pixel.png' }).waitFor(); + await page.keyboard.press('Escape'); + await page.getByRole('link', { name: 'src' }).click(); await page.getByRole('link', { name: 'main.c' }).click(); await page.getByText('int main(void)').waitFor(); @@ -298,6 +355,12 @@ await page.locator('.changeset-files code').filter({ hasText: 'new-file.txt' }).waitFor(); await page.getByText('added', { exact: true }).waitFor(); await page.getByRole('region', { name: 'Changeset diff' }).waitFor(); + assert.equal( + await page.locator('.changeset-paper').evaluate( + element => getComputedStyle(element).backgroundImage, + ), + 'none', + ); await page.getByRole('button', { name: firstNode.slice(0, 12) }).click(); await page.waitForFunction( expectedPath => window.location.pathname === expectedPath,