diff --git a/src/main/transports/electron-net.ts b/src/main/transports/electron-net.ts index 7d30cfc36..bde1efdb3 100644 --- a/src/main/transports/electron-net.ts +++ b/src/main/transports/electron-net.ts @@ -42,6 +42,9 @@ function getRequestOptions(url: string): Electron.ClientRequestConstructorOption path: `${pathname}${search}`, port: parseInt(port, 10), protocol, + // Use a non-persistent in-memory session to avoid triggering a macOS keychain + // prompt during Chromium's cookie-store initialization of the default session. + partition: 'sentry-electron', }; } diff --git a/test/e2e/runner.ts b/test/e2e/runner.ts index c065dd7b8..388ff81ad 100644 --- a/test/e2e/runner.ts +++ b/test/e2e/runner.ts @@ -90,11 +90,7 @@ export function electronTestRunner( let resolve: undefined | (() => void); let reject: undefined | ((reason: unknown) => void); - - const completePromise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); + let completePromise: Promise = Promise.resolve(); const unorderedEvents: Array = []; @@ -110,18 +106,39 @@ export function electronTestRunner( unorderedEvents.push(event); if (unorderedEvents.length === expectations.length) { - const expectedEvents = expectations.map((e) => { - if ('envelope' in e) { - return e.envelope; - } - if ('minidump' in e) { - return e.minidump; - } + // Match each received event to one expectation. Processed in arrival order so that + // function matchers with cross-event side-effects (e.g. capturing a session ID in + // the first handler and verifying it in the second) fire in dependency order. + const unmatched = [...expectations]; + + for (const received of unorderedEvents) { + const idx = unmatched.findIndex((expected) => { + try { + if ('envelope' in expected) { + if (typeof expected.envelope === 'function') { + expected.envelope(received as Envelope); + } else { + expect(received).toEqual(expected.envelope); + } + } else if ('minidump' in expected) { + if (typeof expected.minidump === 'function') { + expected.minidump(received as MinidumpResult); + } else { + expect(received).toEqual(expected.minidump); + } + } + return true; + } catch { + return false; + } + }); - return undefined; - }); + if (idx === -1) { + throw new Error(`No expectation matched received event:\n${inspect(received, false, null, true)}`); + } - expect(unorderedEvents).toEqual(expect.arrayContaining(expectedEvents)); + unmatched.splice(idx, 1); + } if (options.waitAfterExpectedEvents) { delay(options.waitAfterExpectedEvents).then(() => { @@ -182,7 +199,13 @@ export function electronTestRunner( beforeEach(async () => { electronPath = await downloadElectron(electronVersion.string); - server = createSentryTestServer(logger, ignoreOrder ? onNewServerEventIgnoreOrder : onNewServerEvent); + server = createSentryTestServer(logger, (event) => { + if (ignoreOrder) { + onNewServerEventIgnoreOrder(event); + } else { + onNewServerEvent(event); + } + }); await prepareTestFiles(logger, testPath, testExecutionRoot, electronVersion.string, server.port, convertToEsm); await installDepsAndBuild(logger, options.packageManager || 'yarn', testExecutionRoot, hasBuildScript); @@ -202,6 +225,17 @@ export function electronTestRunner( }); test(description, { timeout: options.timeout || 15_000 }, async () => { + // Reset state for retries + expectations.length = 0; + unorderedEvents.length = 0; + expectedErrorOutput = undefined; + ignoreOrder = false; + includeSessionEnvelopes = false; + completePromise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + if (!electronPath) { throw new Error('Electron path is not set'); } diff --git a/test/e2e/test-apps/other/browser-profiling-trace/test.ts b/test/e2e/test-apps/other/browser-profiling-trace/test.ts index e75c3bb0f..bfc414615 100644 --- a/test/e2e/test-apps/other/browser-profiling-trace/test.ts +++ b/test/e2e/test-apps/other/browser-profiling-trace/test.ts @@ -9,6 +9,7 @@ import { electronTestRunner(__dirname, async (ctx) => { await ctx + .ignoreExpectationOrder() // Expect the transaction with profile context (trace mode automatically profiles spans) .expect({ envelope: transactionEnvelope({