diff --git a/packages/core/src/transport/httpRequest.spec.ts b/packages/core/src/transport/httpRequest.spec.ts index 354608ad46..c46beeba29 100644 --- a/packages/core/src/transport/httpRequest.spec.ts +++ b/packages/core/src/transport/httpRequest.spec.ts @@ -89,13 +89,12 @@ describe('httpRequest', () => { return Promise.resolve({ status: 200 }) } }) - const { waitAsyncCalls, expectNoExtraAsyncCall } = collectAsyncCalls(fetchSpy) interceptor.withFetch(fetchSpy) request.send({ data: '{"foo":"bar1"}\n{"foo":"bar2"}', bytesCount: 10 }) - waitAsyncCalls(2, () => expectNoExtraAsyncCall(done)) + collectAsyncCalls(fetchSpy, 2, () => done()) }) }) diff --git a/packages/core/test/collectAsyncCalls.ts b/packages/core/test/collectAsyncCalls.ts index 7669d3cc70..81ec9222bf 100644 --- a/packages/core/test/collectAsyncCalls.ts +++ b/packages/core/test/collectAsyncCalls.ts @@ -1,23 +1,30 @@ -export function collectAsyncCalls(spy: jasmine.Spy) { - return { - waitAsyncCalls: (expectedCallsCount: number, callback: (calls: jasmine.Calls) => void) => { +import { getCurrentJasmineSpec } from './getCurrentJasmineSpec' + +export function collectAsyncCalls( + spy: jasmine.Spy, + expectedCallsCount: number, + callback: (calls: jasmine.Calls) => void +) { + const currentSpec = getCurrentJasmineSpec() + if (!currentSpec) { + throw new Error('collectAsyncCalls should be called within jasmine code') + } + + if (spy.calls.count() === expectedCallsCount) { + spy.and.callFake(extraCallDetected as F) + callback(spy.calls) + } else if (spy.calls.count() > expectedCallsCount) { + extraCallDetected() + } else { + spy.and.callFake((() => { if (spy.calls.count() === expectedCallsCount) { + spy.and.callFake(extraCallDetected as F) callback(spy.calls) - } else if (spy.calls.count() > expectedCallsCount) { - fail('Unexpected extra call') - } else { - spy.and.callFake((() => { - if (spy.calls.count() === expectedCallsCount) { - callback(spy.calls) - } - }) as F) } - }, - expectNoExtraAsyncCall: (done: () => void) => { - spy.and.callFake((() => { - fail('Unexpected extra call') - }) as F) - setTimeout(done, 300) - }, + }) as F) + } + + function extraCallDetected() { + fail(`Unexpected extra call for spec '${currentSpec!.fullName}'`) } } diff --git a/packages/core/test/getCurrentJasmineSpec.ts b/packages/core/test/getCurrentJasmineSpec.ts new file mode 100644 index 0000000000..59a114abe3 --- /dev/null +++ b/packages/core/test/getCurrentJasmineSpec.ts @@ -0,0 +1,14 @@ +let currentSpec: jasmine.SpecResult | null = null + +export function getCurrentJasmineSpec() { + return currentSpec +} + +jasmine.getEnv().addReporter({ + specStarted(specResult) { + currentSpec = specResult + }, + specDone() { + currentSpec = null + }, +}) diff --git a/packages/rum/src/boot/startRecording.spec.ts b/packages/rum/src/boot/startRecording.spec.ts index 45760037e8..5a7e318b24 100644 --- a/packages/rum/src/boot/startRecording.spec.ts +++ b/packages/rum/src/boot/startRecording.spec.ts @@ -21,13 +21,9 @@ describe('startRecording', () => { let setupBuilder: TestSetupBuilder let sessionManager: RumSessionManagerMock let viewId: string - let waitRequestSendCalls: ( - expectedCallsCount: number, - callback: (calls: jasmine.Calls) => void - ) => void let sandbox: HTMLElement let textField: HTMLInputElement - let expectNoExtraRequestSendCalls: (done: () => void) => void + let requestSendSpy: jasmine.Spy let stopRecording: () => void beforeEach((done) => { @@ -55,15 +51,12 @@ describe('startRecording', () => { defaultPrivacyLevel: DefaultPrivacyLevel.ALLOW, }) .beforeBuild(({ lifeCycle, configuration, viewContexts, sessionManager }) => { - const requestSendSpy = jasmine.createSpy() - const httpRequest: HttpRequest = { + requestSendSpy = jasmine.createSpy() + const httpRequest = { send: requestSendSpy, sendOnExit: requestSendSpy, } - ;({ waitAsyncCalls: waitRequestSendCalls, expectNoExtraAsyncCall: expectNoExtraRequestSendCalls } = - collectAsyncCalls(requestSendSpy)) - const recording = startRecording(lifeCycle, configuration, sessionManager, viewContexts, worker!, httpRequest) stopRecording = recording ? recording.stop : noop return { stop: stopRecording } @@ -82,7 +75,7 @@ describe('startRecording', () => { const { lifeCycle } = setupBuilder.build() flushSegment(lifeCycle) - waitRequestSendCalls(1, (calls) => { + collectAsyncCalls(requestSendSpy, 1, (calls) => { expect(calls.first().args[0]).toEqual({ data: jasmine.any(FormData), bytesCount: jasmine.any(Number) }) expect(getRequestData(calls.first())).toEqual({ 'application.id': 'appId', @@ -98,7 +91,7 @@ describe('startRecording', () => { index_in_view: '0', source: 'browser', }) - expectNoExtraRequestSendCalls(done) + done() }) }) @@ -113,9 +106,9 @@ describe('startRecording', () => { document.body.dispatchEvent(inputEvent) } - waitRequestSendCalls(1, (calls) => { + collectAsyncCalls(requestSendSpy, 1, (calls) => { expect(getRequestData(calls.first()).records_count).toBe(String(inputCount + recordsPerFullSnapshot())) - expectNoExtraRequestSendCalls(done) + done() }) }) @@ -130,9 +123,9 @@ describe('startRecording', () => { flushSegment(lifeCycle) - waitRequestSendCalls(1, (calls) => { + collectAsyncCalls(requestSendSpy, 1, (calls) => { expect(getRequestData(calls.first()).records_count).toBe(String(1 + recordsPerFullSnapshot())) - expectNoExtraRequestSendCalls(done) + done() }) }) @@ -148,11 +141,11 @@ describe('startRecording', () => { flushSegment(lifeCycle) - waitRequestSendCalls(1, (calls) => { + collectAsyncCalls(requestSendSpy, 1, (calls) => { const data = getRequestData(calls.first()) expect(data.records_count).toBe('1') expect(data['session.id']).toBe('new-session-id') - expectNoExtraRequestSendCalls(done) + done() }) }) @@ -162,9 +155,9 @@ describe('startRecording', () => { changeView(lifeCycle) flushSegment(lifeCycle) - waitRequestSendCalls(2, (calls) => { + collectAsyncCalls(requestSendSpy, 2, (calls) => { expect(getRequestData(calls.mostRecent()).has_full_snapshot).toBe('true') - expectNoExtraRequestSendCalls(done) + done() }) }) @@ -175,7 +168,7 @@ describe('startRecording', () => { changeView(lifeCycle) flushSegment(lifeCycle) - waitRequestSendCalls(2, (calls) => { + collectAsyncCalls(requestSendSpy, 2, (calls) => { readRequestSegment(calls.first(), (segment) => { expect(segment.records[0].timestamp).toEqual(timeStampNow()) expect(segment.records[1].timestamp).toEqual(timeStampNow()) @@ -189,7 +182,7 @@ describe('startRecording', () => { expect(segment.records[1].timestamp).toEqual(VIEW_TIMESTAMP) expect(segment.records[2].timestamp).toEqual(VIEW_TIMESTAMP) - expectNoExtraRequestSendCalls(done) + done() }) }) }) @@ -201,11 +194,11 @@ describe('startRecording', () => { changeView(lifeCycle) flushSegment(lifeCycle) - waitRequestSendCalls(2, (calls) => { + collectAsyncCalls(requestSendSpy, 2, (calls) => { expect(getRequestData(calls.first())['view.id']).toBe('view-id') readRequestSegment(calls.first(), (segment) => { expect(segment.records[segment.records.length - 1].type).toBe(RecordType.ViewEnd) - expectNoExtraRequestSendCalls(done) + done() }) }) }) @@ -217,14 +210,14 @@ describe('startRecording', () => { changeView(lifeCycle) flushSegment(lifeCycle) - waitRequestSendCalls(2, (calls) => { + collectAsyncCalls(requestSendSpy, 2, (calls) => { readRequestSegment(calls.first(), (segment) => { expect(segment.records[segment.records.length - 2].type).toBe(RecordType.IncrementalSnapshot) expect(segment.records[segment.records.length - 1].type).toBe(RecordType.ViewEnd) readRequestSegment(calls.mostRecent(), (segment) => { expect(segment.records[0].type).toBe(RecordType.Meta) - expectNoExtraRequestSendCalls(done) + done() }) }) }) @@ -234,12 +227,12 @@ describe('startRecording', () => { setSegmentBytesLimit(0) setupBuilder.build() - waitRequestSendCalls(1, (calls) => { + collectAsyncCalls(requestSendSpy, 1, (calls) => { readRequestSegment(calls.first(), (segment) => { expect(segment.records[0].type).toBe(RecordType.Meta) expect(segment.records[1].type).toBe(RecordType.Focus) expect(segment.records[2].type).toBe(RecordType.FullSnapshot) - expectNoExtraRequestSendCalls(done) + done() }) }) }) @@ -253,9 +246,9 @@ describe('startRecording', () => { document.body.dispatchEvent(createNewEvent('click', { clientX: 1, clientY: 2 })) flushSegment(lifeCycle) - waitRequestSendCalls(1, (calls) => { + collectAsyncCalls(requestSendSpy, 1, (calls) => { expect(getRequestData(calls.first()).records_count).toBe(String(1 + recordsPerFullSnapshot())) - expectNoExtraRequestSendCalls(done) + done() }) }) @@ -266,9 +259,9 @@ describe('startRecording', () => { changeView(lifeCycle) flushSegment(lifeCycle) - waitRequestSendCalls(1, (calls) => { + collectAsyncCalls(requestSendSpy, 1, (calls) => { expect(getRequestData(calls.first()).records_count).toBe(String(recordsPerFullSnapshot())) - expectNoExtraRequestSendCalls(done) + done() }) }) }) diff --git a/packages/rum/src/domain/record/mutationBatch.spec.ts b/packages/rum/src/domain/record/mutationBatch.spec.ts index 66240d14dc..4e88d9a65f 100644 --- a/packages/rum/src/domain/record/mutationBatch.spec.ts +++ b/packages/rum/src/domain/record/mutationBatch.spec.ts @@ -19,14 +19,9 @@ describe('createMutationBatch', () => { const mutation = { type: 'childList' } as RumMutationRecord mutationBatch.addMutations([mutation]) - const { - waitAsyncCalls: waitProcessMutationBatchCalls, - expectNoExtraAsyncCall: expectNoExtraProcessMutationBatchCall, - } = collectAsyncCalls(processMutationBatchSpy) - - waitProcessMutationBatchCalls(1, (calls) => { + collectAsyncCalls(processMutationBatchSpy, 1, (calls) => { expect(calls.mostRecent().args[0]).toEqual([mutation]) - expectNoExtraProcessMutationBatchCall(done) + done() }) }) diff --git a/packages/rum/src/domain/record/observers/mutationObserver.spec.ts b/packages/rum/src/domain/record/observers/mutationObserver.spec.ts index ab3e21bce9..1b6888571c 100644 --- a/packages/rum/src/domain/record/observers/mutationObserver.spec.ts +++ b/packages/rum/src/domain/record/observers/mutationObserver.spec.ts @@ -102,16 +102,12 @@ describe('startMutationCollection', () => { it('processes mutations asynchronously', (done) => { serializeDocumentWithDefaults() const { mutationCallbackSpy } = startMutationCollection() - const { waitAsyncCalls: waitMutationCallbackCalls, expectNoExtraAsyncCall: expectNoExtraMutationCallbackCalls } = - collectAsyncCalls(mutationCallbackSpy) sandbox.appendChild(document.createElement('div')) expect(mutationCallbackSpy).not.toHaveBeenCalled() - waitMutationCallbackCalls(1, () => { - expectNoExtraMutationCallbackCalls(done) - }) + collectAsyncCalls(mutationCallbackSpy, 1, () => done()) }) it('does not emit a mutation when a node is appended to a unknown node', () => { diff --git a/packages/rum/src/domain/record/record.spec.ts b/packages/rum/src/domain/record/record.spec.ts index c43d8b6103..24e699cb70 100644 --- a/packages/rum/src/domain/record/record.spec.ts +++ b/packages/rum/src/domain/record/record.spec.ts @@ -20,8 +20,6 @@ describe('record', () => { let sandbox: HTMLElement let recordApi: RecordAPI let emitSpy: jasmine.Spy<(record: BrowserRecord) => void> - let waitEmitCalls: (expectedCallsCount: number, callback: () => void) => void - let expectNoExtraEmitCalls: (done: () => void) => void let clock: Clock | undefined beforeEach(() => { @@ -30,7 +28,6 @@ describe('record', () => { } emitSpy = jasmine.createSpy() - ;({ waitAsyncCalls: waitEmitCalls, expectNoExtraAsyncCall: expectNoExtraEmitCalls } = collectAsyncCalls(emitSpy)) sandbox = createDOMSandbox() }) @@ -60,7 +57,7 @@ describe('record', () => { styleSheet.insertRule('body { color: #ccc; }') }, 10) - waitEmitCalls(recordsPerFullSnapshot() + 6, () => { + collectAsyncCalls(emitSpy, recordsPerFullSnapshot() + 6, () => { const records = getEmittedRecords() let i = 0 @@ -115,7 +112,7 @@ describe('record', () => { }) ) - expectNoExtraEmitCalls(done) + done() }) }) @@ -126,7 +123,7 @@ describe('record', () => { recordApi.takeSubsequentFullSnapshot() - waitEmitCalls(1 + 2 * recordsPerFullSnapshot(), () => { + collectAsyncCalls(emitSpy, 1 + 2 * recordsPerFullSnapshot(), () => { const records = getEmittedRecords() let i = 0 @@ -143,7 +140,7 @@ describe('record', () => { expect(records[i++].type).toEqual(RecordType.Focus) expect(records[i++].type).toEqual(RecordType.FullSnapshot) - expectNoExtraEmitCalls(done) + done() }) })