diff --git a/packages/web/test/SplunkExporter.test.ts b/packages/web/src/tests/SplunkExporter.test.ts similarity index 67% rename from packages/web/test/SplunkExporter.test.ts rename to packages/web/src/tests/SplunkExporter.test.ts index 318e34a0..6ad42c3e 100644 --- a/packages/web/test/SplunkExporter.test.ts +++ b/packages/web/src/tests/SplunkExporter.test.ts @@ -16,17 +16,15 @@ * */ -import sinon from 'sinon' -import { expect } from 'chai' - import * as api from '@opentelemetry/api' import { timeInputToHrTime } from '@opentelemetry/core' -import { SplunkZipkinExporter } from '../src/exporters/zipkin' -import { RateLimitProcessor } from '../src/exporters/rate-limit' +import { SplunkZipkinExporter } from '../exporters/zipkin' +import { RateLimitProcessor } from '../exporters/rate-limit' import { ReadableSpan } from '@opentelemetry/sdk-trace-base' +import { describe, vi, expect, it, Mock, assert, beforeEach, afterEach } from 'vitest' -function buildDummySpan({ name = '', attributes = {} } = {}) { - return { +const buildDummySpan = ({ name = '', attributes = {} } = {}) => + ({ spanContext: () => ({ traceId: '0000', spanId: '0001', @@ -40,22 +38,24 @@ function buildDummySpan({ name = '', attributes = {} } = {}) { status: { code: api.SpanStatusCode.UNSET }, resource: { attributes: {} }, events: [] as { name: string; time: api.HrTime }[], - } as ReadableSpan -} + }) as ReadableSpan describe('SplunkZipkinExporter', () => { - let beaconSenderMock - let xhrSenderMock - let exporter + let beaconSenderMock: Mock + const originalBeacon = window.navigator.sendBeacon + let xhrSenderMock: Mock + let exporter: SplunkZipkinExporter beforeEach(() => { - beaconSenderMock = sinon.stub(navigator, 'sendBeacon').returns(true) - xhrSenderMock = sinon.fake() + beaconSenderMock = vi.fn().mockReturnValue(true) + window.navigator.sendBeacon = beaconSenderMock + + xhrSenderMock = vi.fn().mockReturnValue(undefined) }) - afterEach(() => { - exporter.shutdown() - beaconSenderMock.restore() + afterEach(async () => { + await exporter.shutdown() + window.navigator.sendBeacon = originalBeacon }) it('uses Beacon API if in background', () => { @@ -73,34 +73,43 @@ describe('SplunkZipkinExporter', () => { configurable: true, enumerable: true, }) + const dummySpan = buildDummySpan() exporter.export([dummySpan], () => {}) + assert(oldDef) Object.defineProperty(targetDocProto, 'hidden', oldDef) - expect(beaconSenderMock.args[0][0]).to.eq('https://domain1') - const sentSpan = JSON.parse(beaconSenderMock.args[0][1])[0] - expect(sentSpan.name).to.equal('') - expect(sentSpan.id).to.equal('0001') + expect(beaconSenderMock).toHaveBeenCalledTimes(1) + const sendBeaconArgs = beaconSenderMock.mock.calls[0] + expect(sendBeaconArgs[0]).toBe('https://domain1') + + const sentSpan = JSON.parse(sendBeaconArgs[1])[0] - expect(xhrSenderMock.called).to.eq(false) + expect(sentSpan.name).toBe('') + expect(sentSpan.id).toBe('0001') + + expect(xhrSenderMock).toHaveBeenCalledTimes(0) }) it('uses XHR if Beacon API is unavailable', () => { exporter = new SplunkZipkinExporter({ url: 'https://domain2', - beaconSender: null, + beaconSender: undefined, xhrSender: xhrSenderMock, }) const dummySpan = buildDummySpan() exporter.export([dummySpan], () => {}) - expect(xhrSenderMock.args[0][0]).to.eq('https://domain2') + expect(xhrSenderMock).toHaveBeenCalledTimes(1) + const sendXhrArgs = xhrSenderMock.mock.calls[0] + + expect(sendXhrArgs[0]).toBe('https://domain2') - const sentSpan = JSON.parse(xhrSenderMock.args[0][1])[0] - expect(sentSpan.name).to.equal('') - expect(sentSpan.id).to.equal('0001') + const sentSpan = JSON.parse(sendXhrArgs[1])[0] + expect(sentSpan.name).toBe('') + expect(sentSpan.id).toBe('0001') }) it('truncates long values', () => { @@ -117,11 +126,12 @@ describe('SplunkZipkinExporter', () => { }, }) exporter.export([dummySpan], () => {}) - - const sentSpan = JSON.parse(xhrSenderMock.getCall(0).args[1])[0] - expect(sentSpan.name).to.eq('a'.repeat(4096)) - expect(sentSpan.tags['longValue']).to.eq('b'.repeat(4096)) - expect(sentSpan.tags['shortValue']).to.eq('c'.repeat(4000)) + expect(xhrSenderMock).toHaveBeenCalledTimes(1) + const sendXhrArgs = xhrSenderMock.mock.calls[0] + const sentSpan = JSON.parse(sendXhrArgs[1])[0] + expect(sentSpan.name).toBe('a'.repeat(4096)) + expect(sentSpan.tags['longValue']).toBe('b'.repeat(4096)) + expect(sentSpan.tags['shortValue']).toBe('c'.repeat(4000)) }) it('filters out missing cors timings', () => { @@ -153,15 +163,17 @@ describe('SplunkZipkinExporter', () => { name: 'responseEnd', }) exporter.export([dummySpan], () => {}) - - const sentSpan = JSON.parse(xhrSenderMock.getCall(0).args[1])[0] - expect(sentSpan.annotations.length).to.eq(2) + expect(xhrSenderMock).toHaveBeenCalledTimes(1) + const sendXhrArgs = xhrSenderMock.mock.calls[0] + const sentSpan = JSON.parse(sendXhrArgs[1])[0] + expect(sentSpan.annotations).toHaveLength(2) }) it('allows hooking into serialization', () => { exporter = new SplunkZipkinExporter({ url: 'https://localhost', xhrSender: xhrSenderMock, + // @ts-expect-error null is not a valid value onAttributesSerializing: (attributes) => ({ ...attributes, key1: 'new value 1', @@ -177,11 +189,12 @@ describe('SplunkZipkinExporter', () => { }, }) exporter.export([dummySpan], () => {}) + expect(xhrSenderMock).toHaveBeenCalledTimes(1) + const sendXhrArgs = xhrSenderMock.mock.calls[0] - const sentSpan = JSON.parse(xhrSenderMock.getCall(0).args[1])[0] - expect(sentSpan.name).to.eq('') - console.log(sentSpan.tags) - expect(sentSpan.tags).to.deep.eq({ + const sentSpan = JSON.parse(sendXhrArgs[1])[0] + expect(sentSpan.name).toBe('') + expect(sentSpan.tags).toStrictEqual({ key1: 'new value 1', key2: 'value 2', key3: 'null', @@ -210,7 +223,7 @@ describe('Rate Limiter', () => { rateLimiter.onEnd(dummySpan) } - expect(allowedSpans).to.have.lengthOf(100) + expect(allowedSpans).toHaveLength(100) }) it('still exports parent spans', () => { @@ -242,6 +255,6 @@ describe('Rate Limiter', () => { parentSpan.parentSpanId = undefined rateLimiter.onEnd(parentSpan) - expect(allowedSpans).to.have.lengthOf(101) + expect(allowedSpans).toHaveLength(101) }) }) diff --git a/packages/web/test/index.ts b/packages/web/test/index.ts index 46c8f305..09d754a4 100644 --- a/packages/web/test/index.ts +++ b/packages/web/test/index.ts @@ -23,7 +23,7 @@ import './init.test' import '../src/tests/session.test' import '../src/tests/websockets.test' import '../src/tests/SessionBasedSampler.test' -import './SplunkExporter.test' +import '../src/tests/SplunkExporter.test' import './SplunkContextManager.test' import './SplunkSpanAttributesProcessor.test' import './SplunkOtelWeb.test'