mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
fix(ci): systematic fixes for E2E tests and CI environment
- `js/nostr/client.js`: Exposed `derivePrivateKeyFromSecret` to `NostrClient` (delegating to `SignerManager`) to support programmatic login in E2E tests. - `tests/e2e/helpers/bitvidTestFixture.ts`: Refactored to use dynamic relay ports based on `workerIndex` to fix parallel execution collisions. - `scripts/agent/simple-relay.mjs`: Updated `close()` to force terminate connected clients, preventing test teardown hangs. - `scripts/check-sw-compat.mjs`: Added try-catch around git commands to gracefully handle shallow clones in CI environments. Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
f0f078b843
commit
3ef17d1122
4 files changed
+54
-33
No files matched your search
@@ -2417,6 +2417,10 @@ export class NostrClient {
|
||||
return this.signerManager.ensureActiveSignerForPubkey(pubkey);
|
||||
}
|
||||
|
||||
async derivePrivateKeyFromSecret(secret) {
|
||||
return this.signerManager.derivePrivateKeyFromSecret(secret);
|
||||
}
|
||||
|
||||
async loginWithExtension(options) {
|
||||
// Check if ensureExtensionPermissions was overridden on this instance (e.g. by tests).
|
||||
// Only proxy when the own property differs from the prototype method to avoid recursion.
|
||||
|
||||
@@ -194,6 +194,11 @@ export function startRelay(port = 8888, options = {}) {
|
||||
return {
|
||||
close: () => {
|
||||
return new Promise((resolve) => {
|
||||
// Force close all connected clients
|
||||
for (const client of wss.clients) {
|
||||
client.terminate();
|
||||
}
|
||||
|
||||
const closeHttp = httpServer
|
||||
? new Promise((r) => httpServer.close(r))
|
||||
: Promise.resolve();
|
||||
|
||||
+20
-15
@@ -13,24 +13,29 @@ const CRITICAL_PATH_PATTERNS = [
|
||||
];
|
||||
|
||||
function getChangedFilesAgainstHeadParent() {
|
||||
const hasHeadParent = execSync('git rev-parse --verify --quiet HEAD^', {
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'ignore']
|
||||
}).trim();
|
||||
try {
|
||||
const hasHeadParent = execSync('git rev-parse --verify --quiet HEAD^', {
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'ignore']
|
||||
}).trim();
|
||||
|
||||
if (!hasHeadParent) {
|
||||
if (!hasHeadParent) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const output = execSync('git diff-tree --no-commit-id --name-only -r HEAD', {
|
||||
encoding: 'utf8'
|
||||
}).trim();
|
||||
|
||||
if (!output) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return output.split('\n').map((value) => value.trim()).filter(Boolean);
|
||||
} catch (error) {
|
||||
console.warn('[sw-compat] Skipping check: unable to determine HEAD^ or git history unavailable.');
|
||||
return [];
|
||||
}
|
||||
|
||||
const output = execSync('git diff-tree --no-commit-id --name-only -r HEAD', {
|
||||
encoding: 'utf8'
|
||||
}).trim();
|
||||
|
||||
if (!output) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return output.split('\n').map((value) => value.trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
function getCriticalPathDiff() {
|
||||
|
||||
@@ -33,10 +33,7 @@ const TEST_PRIVATE_KEY_HEX =
|
||||
const TEST_SK = Uint8Array.from(Buffer.from(TEST_PRIVATE_KEY_HEX, "hex"));
|
||||
const TEST_PK = getPublicKey(TEST_SK);
|
||||
|
||||
const RELAY_PORT = 8877;
|
||||
const RELAY_HTTP_PORT = 8878;
|
||||
const RELAY_WS_URL = `ws://127.0.0.1:${RELAY_PORT}`;
|
||||
const RELAY_HTTP_URL = `http://127.0.0.1:${RELAY_HTTP_PORT}`;
|
||||
const BASE_RELAY_PORT = 8877;
|
||||
|
||||
export interface TestVideoEvent {
|
||||
title: string;
|
||||
@@ -85,8 +82,8 @@ function createVideoEvent(video: TestVideoEvent) {
|
||||
/**
|
||||
* Seed an event into the relay via HTTP API.
|
||||
*/
|
||||
async function seedEventViaHttp(event: any) {
|
||||
const resp = await fetch(`${RELAY_HTTP_URL}/seed`, {
|
||||
async function seedEventViaHttp(event: any, httpUrl: string) {
|
||||
const resp = await fetch(`${httpUrl}/seed`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(event),
|
||||
@@ -100,8 +97,8 @@ async function seedEventViaHttp(event: any) {
|
||||
/**
|
||||
* Clear all events from the relay.
|
||||
*/
|
||||
async function clearRelayEvents() {
|
||||
const resp = await fetch(`${RELAY_HTTP_URL}/events`, { method: "DELETE" });
|
||||
async function clearRelayEvents(httpUrl: string) {
|
||||
const resp = await fetch(`${httpUrl}/events`, { method: "DELETE" });
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Failed to clear events: ${resp.status}`);
|
||||
}
|
||||
@@ -110,9 +107,9 @@ async function clearRelayEvents() {
|
||||
/**
|
||||
* Navigate to bitvid with test mode and relay overrides enabled.
|
||||
*/
|
||||
async function gotoWithTestMode(page: Page, path = "/") {
|
||||
async function gotoWithTestMode(page: Page, relayUrl: string, path = "/") {
|
||||
const separator = path.includes("?") ? "&" : "?";
|
||||
const testUrl = `${path}${separator}__test__=1&__testRelays__=${encodeURIComponent(RELAY_WS_URL)}`;
|
||||
const testUrl = `${path}${separator}__test__=1&__testRelays__=${encodeURIComponent(relayUrl)}`;
|
||||
|
||||
// Set up localStorage before navigation
|
||||
await page.addInitScript(() => {
|
||||
@@ -163,8 +160,16 @@ type BitvidFixtures = {
|
||||
|
||||
export const test = base.extend<BitvidFixtures>({
|
||||
relay: [
|
||||
async ({}, use) => {
|
||||
const relayInstance = startRelay(RELAY_PORT, { httpPort: RELAY_HTTP_PORT });
|
||||
async ({}, use, testInfo) => {
|
||||
// Avoid port collisions when running in parallel workers
|
||||
const port = BASE_RELAY_PORT + (testInfo.workerIndex * 2);
|
||||
const httpPort = port + 1;
|
||||
|
||||
const relayInstance = startRelay(port, { httpPort });
|
||||
// Attach the dynamic URLs to the relay instance for downstream fixtures
|
||||
(relayInstance as any).wsUrl = `ws://127.0.0.1:${port}`;
|
||||
(relayInstance as any).httpUrl = `http://127.0.0.1:${httpPort}`;
|
||||
|
||||
await use(relayInstance);
|
||||
await relayInstance.close();
|
||||
},
|
||||
@@ -174,25 +179,25 @@ export const test = base.extend<BitvidFixtures>({
|
||||
seedEvent: async ({ relay }, use) => {
|
||||
await use(async (video: TestVideoEvent) => {
|
||||
const event = createVideoEvent(video);
|
||||
return seedEventViaHttp(event);
|
||||
return seedEventViaHttp(event, (relay as any).httpUrl);
|
||||
});
|
||||
},
|
||||
|
||||
seedRawEvent: async ({ relay }, use) => {
|
||||
await use(async (event: any) => {
|
||||
return seedEventViaHttp(event);
|
||||
return seedEventViaHttp(event, (relay as any).httpUrl);
|
||||
});
|
||||
},
|
||||
|
||||
clearRelay: async ({ relay }, use) => {
|
||||
await use(async () => {
|
||||
await clearRelayEvents();
|
||||
await clearRelayEvents((relay as any).httpUrl);
|
||||
});
|
||||
},
|
||||
|
||||
gotoApp: async ({ page }, use) => {
|
||||
gotoApp: async ({ page, relay }, use) => {
|
||||
await use(async (path = "/") => {
|
||||
await gotoWithTestMode(page, path);
|
||||
await gotoWithTestMode(page, (relay as any).wsUrl, path);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -204,7 +209,9 @@ export const test = base.extend<BitvidFixtures>({
|
||||
|
||||
testPubkey: TEST_PK,
|
||||
testPrivateKey: TEST_PRIVATE_KEY_HEX,
|
||||
relayUrl: RELAY_WS_URL,
|
||||
relayUrl: async ({ relay }, use) => {
|
||||
await use((relay as any).wsUrl);
|
||||
},
|
||||
});
|
||||
|
||||
export { expect };
|
||||
Reference in new issue
Block a user