Files
bitvid/tests/e2e/repro_issue.spec.ts
T
google-labs-jules[bot]andPR0M3TH3AN e79b2500c8 fix(ci): install firefox in e2e-headless and fix e2e test isolation
- Updated `.github/workflows/ci.yml` to install both chromium and firefox in `e2e-headless` job, resolving missing executable errors.
- Updated `js/relayManager.js` to respect `__testRelays__` overrides (via URL/localStorage) during initialization, preventing race conditions where tests fell back to production relays.
- Updated `tests/e2e/repro_issue.spec.ts` to use dynamic relay ports based on worker index, preventing `EADDRINUSE` errors in parallel runs.
- Updated `scripts/check-hex.js` to ignore `docs/agents/task-logs/**` to prevent lint failures on hex strings in log files.
- Executed `prompt-curator-agent` daily task to fix broken paths in prompt library.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-22 17:09:11 +00:00

113 lines
3.5 KiB
TypeScript

import { test, expect } from './helpers/instrumentedTest';
import { startRelay } from '../../scripts/agent/simple-relay.mjs';
import { WebSocket } from 'ws';
import { finalizeEvent, getPublicKey, nip19 } from 'nostr-tools';
// Polyfill WebSocket for node environment
if (!global.WebSocket) {
global.WebSocket = WebSocket;
}
test.describe('Embed Player', () => {
let relayServer;
let RELAY_URL;
test.beforeEach(async ({}, testInfo) => {
const port = 8900 + (testInfo.workerIndex * 10);
RELAY_URL = `ws://127.0.0.1:${port}`;
relayServer = startRelay(port);
});
test.afterEach(async () => {
if (relayServer) {
await relayServer.close();
}
});
test('reproduce embed resetStats error', async ({ page }) => {
// 1. Create a dummy video event
const sk = Uint8Array.from(Buffer.from('7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b', 'hex'));
const pk = getPublicKey(sk);
const event = finalizeEvent({
kind: 30078,
created_at: Math.floor(Date.now() / 1000),
tags: [
['d', 'test-video'],
['title', 'Test Video'],
['url', 'https://example.com/video.mp4'],
],
content: '',
pubkey: pk,
}, sk);
// 2. Publish event to local relay
await new Promise((resolve, reject) => {
const ws = new WebSocket(RELAY_URL);
ws.on('open', () => {
ws.send(JSON.stringify(['EVENT', event]));
});
ws.on('message', (msg) => {
const data = JSON.parse(msg.toString());
if (data[0] === 'OK') {
ws.close();
resolve();
}
});
ws.on('error', (e) => {
reject(e);
});
});
// 3. Construct nevent
const nevent = nip19.neventEncode({
id: event.id,
relays: [RELAY_URL]
});
// 4. Navigate
const consoleMessages = [];
page.on('console', msg => consoleMessages.push(msg.text()));
const errors = [];
page.on('pageerror', err => {
errors.push(err);
console.log('PAGE ERROR:', err.message);
});
// Force local storage cleanup or setup if needed
// The memory said: "Frontend verification scripts using Playwright must inject localStorage.setItem('hasSeenDisclaimer', 'true')"
await page.addInitScript(() => {
localStorage.setItem('hasSeenDisclaimer', 'true');
});
const embedUrl = `/embed.html?pointer=${nevent}&playback=url`;
await page.goto(embedUrl);
// 5. Wait for video attempt
// We expect the status to change from "Loading video..."
// If it crashes, it might not change, or it might change to "Resolving..." then crash.
// We wait for a bit to let the async playback logic run
try {
await expect(page.locator('#embedStatus')).not.toHaveText('Loading video…', { timeout: 5000 });
await expect(page.locator('#embedStatus')).not.toHaveText('Resolving video…', { timeout: 5000 });
} catch (e) {
console.log('Timeout waiting for status change. Current status:', await page.locator('#embedStatus').textContent());
}
// Check for the specific error
const typeError = errors.find(e => e.message && e.message.includes('this.videoModal.resetStats is not a function'));
if (typeError) {
console.error('Reproduced TypeError:', typeError);
// Fail the test
expect(typeError).toBeUndefined();
} else {
console.log('No TypeError found.');
}
// Log console for debugging
console.log('Console output:', consoleMessages.join('\n'));
});
});