Skip to content

Commit

Permalink
test(browser): Switch from jest to vitest (#13092)
Browse files Browse the repository at this point in the history
Before: `Time: 10.517 s`

After: `Duration 3.65s (transform 2.76s, setup 7ms, collect 15.44s,
tests 1.36s, environment 4.96s, prepare 3.63s)`

We also change the folder structure of the browser unit tests, because
we've removed the in-package integration tests.

This change also removes `environment: 'jsdom'` from the central config
in favour of explicitly adding jsdom environment via the
`@vitest-environment` pragma to the specific test file that needs it.
This should means that our tests are not polluted with jsdom globals,
and that future writers have to explicitly opt-in to the behaviour.
  • Loading branch information
AbhiPrasad authored Aug 1, 2024
1 parent 6285808 commit 21b0dae
Show file tree
Hide file tree
Showing 36 changed files with 303 additions and 226 deletions.
7 changes: 0 additions & 7 deletions packages/browser/jest.config.js

This file was deleted.

5 changes: 2 additions & 3 deletions packages/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,8 @@
"fix": "eslint . --format stylish --fix",
"lint": "eslint . --format stylish",
"size:check": "cat build/bundles/bundle.min.js | gzip -9 | wc -c | awk '{$1=$1/1024; print \"ES2017: \",$1,\"kB\";}'",
"test": "yarn test:unit",
"test:unit": "jest",
"test:unit:watch": "jest --watch",
"test": "vitest run",
"test:watch": "vitest --watch",
"yalc:publish": "yalc publish --push --sig"
},
"volta": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { defaultStackParser } from '../../src';
import { eventFromUnknownInput } from '../../src/eventbuilder';
/**
* @vitest-environment jsdom
*/

jest.mock('@sentry/core', () => {
const original = jest.requireActual('@sentry/core');
import { afterEach, describe, expect, it, vi } from 'vitest';

import { defaultStackParser } from '../src';
import { eventFromUnknownInput } from '../src/eventbuilder';

vi.mock('@sentry/core', async requireActual => {
return {
...original,
...((await requireActual()) as any),
getClient() {
return {
getOptions(): any {
Expand All @@ -21,7 +26,7 @@ class MyTestClass {
}

afterEach(() => {
jest.resetAllMocks();
vi.resetAllMocks();
});

describe('eventFromUnknownInput', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createTransport } from '@sentry/core';
import { resolvedSyncPromise } from '@sentry/utils';

import type { BrowserClientOptions } from '../../../src/client';
import type { BrowserClientOptions } from '../../src/client';

export function getDefaultBrowserClientOptions(options: Partial<BrowserClientOptions> = {}): BrowserClientOptions {
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { describe, expect, it } from 'vitest';

import { browserTracingIntegrationShim, replayIntegrationShim } from '@sentry-internal/integration-shims';
import { feedbackAsyncIntegration } from '../../src';
import { feedbackAsyncIntegration } from '../src';

import * as FeedbackBundle from '../../src/index.bundle.feedback';
import * as FeedbackBundle from '../src/index.bundle.feedback';

describe('index.bundle.feedback', () => {
it('has correct exports', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { describe, expect, it } from 'vitest';

import { browserTracingIntegrationShim, feedbackIntegrationShim } from '@sentry-internal/integration-shims';
import { replayIntegration } from '../../src';
import { replayIntegration } from '../src';

import * as ReplayBundle from '../../src/index.bundle.replay';
import * as ReplayBundle from '../src/index.bundle.replay';

describe('index.bundle.replay', () => {
it('has correct exports', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { describe, expect, it } from 'vitest';

import {
browserTracingIntegrationShim,
feedbackIntegrationShim,
replayIntegrationShim,
} from '@sentry-internal/integration-shims';

import * as Bundle from '../../src/index.bundle';
import * as Bundle from '../src/index.bundle';

describe('index.bundle', () => {
it('has correct exports', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { browserTracingIntegration, feedbackAsyncIntegration, replayIntegration } from '../../src';
import { describe, expect, it } from 'vitest';

import * as TracingReplayFeedbackBundle from '../../src/index.bundle.tracing.replay.feedback';
import { browserTracingIntegration, feedbackAsyncIntegration, replayIntegration } from '../src';

import * as TracingReplayFeedbackBundle from '../src/index.bundle.tracing.replay.feedback';

describe('index.bundle.tracing.replay.feedback', () => {
it('has correct exports', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { describe, expect, it } from 'vitest';

import { feedbackIntegrationShim } from '@sentry-internal/integration-shims';
import { browserTracingIntegration, replayIntegration } from '../../src';
import { browserTracingIntegration, replayIntegration } from '../src';

import * as TracingReplayBundle from '../../src/index.bundle.tracing.replay';
import * as TracingReplayBundle from '../src/index.bundle.tracing.replay';

describe('index.bundle.tracing.replay', () => {
it('has correct exports', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { describe, expect, it } from 'vitest';

import { feedbackIntegrationShim, replayIntegrationShim } from '@sentry-internal/integration-shims';
import { browserTracingIntegration } from '../../src';
import { browserTracingIntegration } from '../src';

import * as TracingBundle from '../../src/index.bundle.tracing';
import * as TracingBundle from '../src/index.bundle.tracing';

describe('index.bundle.tracing', () => {
it('has correct exports', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* @vitest-environment jsdom
*/

import type { Mock } from 'vitest';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import {
SDK_VERSION,
getGlobalScope,
Expand All @@ -8,7 +15,7 @@ import {
} from '@sentry/core';
import * as utils from '@sentry/utils';

import { setCurrentClient } from '../../src';
import { setCurrentClient } from '../src';
import {
BrowserClient,
Scope,
Expand All @@ -22,7 +29,7 @@ import {
getCurrentScope,
init,
showReportDialog,
} from '../../src';
} from '../src';
import { getDefaultBrowserClientOptions } from './helper/browser-client-options';
import { makeSimpleTransport } from './mocks/simpletransport';

Expand All @@ -31,16 +38,15 @@ const dsn = 'https://[email protected]/4291';
// eslint-disable-next-line no-var
declare var global: any;

jest.mock('@sentry/core', () => {
const original = jest.requireActual('@sentry/core');
vi.mock('@sentry/core', async requireActual => {
return {
...original,
getReportDialogEndpoint: jest.fn(),
...((await requireActual()) as any),
getReportDialogEndpoint: vi.fn(),
};
});

describe('SentryBrowser', () => {
const beforeSend = jest.fn(event => event);
const beforeSend = vi.fn(event => event);

beforeEach(() => {
getGlobalScope().clear();
Expand Down Expand Up @@ -84,7 +90,7 @@ describe('SentryBrowser', () => {

describe('showReportDialog', () => {
beforeEach(() => {
(getReportDialogEndpoint as jest.Mock).mockReset();
(getReportDialogEndpoint as Mock).mockReset();
});

describe('user', () => {
Expand Down Expand Up @@ -145,14 +151,14 @@ describe('SentryBrowser', () => {
});

describe('onClose', () => {
const dummyErrorHandler = jest.fn();
const dummyErrorHandler = vi.fn();
beforeEach(() => {
// this prevents jest-environment-jsdom from failing the test
// this prevents vi-environment-jsdom from failing the test
// when an error in `onClose` is thrown
// it does not prevent errors thrown directly inside the test,
// so we don't have to worry about tests passing that should
// otherwise fail
// see: https://github.com/jestjs/jest/blob/main/packages/jest-environment-jsdom/src/index.ts#L95-L115
// see: https://github.com/vijs/vi/blob/main/packages/vi-environment-jsdom/src/index.ts#L95-L115
WINDOW.addEventListener('error', dummyErrorHandler);
});

Expand All @@ -166,7 +172,7 @@ describe('SentryBrowser', () => {
};

it('should call `onClose` when receiving `__sentry_reportdialog_closed__` MessageEvent', async () => {
const onClose = jest.fn();
const onClose = vi.fn();

showReportDialog({ onClose });

Expand All @@ -179,7 +185,7 @@ describe('SentryBrowser', () => {
});

it('should call `onClose` only once even if it throws', async () => {
const onClose = jest.fn(() => {
const onClose = vi.fn(() => {
throw new Error();
});

Expand All @@ -194,7 +200,7 @@ describe('SentryBrowser', () => {
});

it('should not call `onClose` for other MessageEvents', async () => {
const onClose = jest.fn();
const onClose = vi.fn();

showReportDialog({ onClose });

Expand Down Expand Up @@ -236,49 +242,52 @@ describe('SentryBrowser', () => {
expect(event.exception.values[0]?.stacktrace.frames).not.toHaveLength(0);
});

it('should capture a message', done => {
const options = getDefaultBrowserClientOptions({
beforeSend: event => {
expect(event.message).toBe('test');
expect(event.exception).toBeUndefined();
done();
return event;
},
dsn,
});
setCurrentClient(new BrowserClient(options));
captureMessage('test');
});

it('should capture an event', done => {
const options = getDefaultBrowserClientOptions({
beforeSend: event => {
expect(event.message).toBe('event');
expect(event.exception).toBeUndefined();
done();
return event;
},
dsn,
});
setCurrentClient(new BrowserClient(options));
captureEvent({ message: 'event' });
});

it('should set `platform` on events', done => {
const options = getDefaultBrowserClientOptions({
beforeSend: event => {
expect(event.platform).toBe('javascript');
done();
return event;
},
dsn,
});
setCurrentClient(new BrowserClient(options));
captureEvent({ message: 'event' });
});
it('should capture a message', () =>
new Promise<void>(resolve => {
const options = getDefaultBrowserClientOptions({
beforeSend: event => {
expect(event.message).toBe('test');
expect(event.exception).toBeUndefined();
resolve();
return event;
},
dsn,
});
setCurrentClient(new BrowserClient(options));
captureMessage('test');
}));

it('should capture an event', () =>
new Promise<void>(resolve => {
const options = getDefaultBrowserClientOptions({
beforeSend: event => {
expect(event.message).toBe('event');
expect(event.exception).toBeUndefined();
resolve();
return event;
},
dsn,
});
setCurrentClient(new BrowserClient(options));
captureEvent({ message: 'event' });
}));

it('should set `platform` on events', () =>
new Promise<void>(resolve => {
const options = getDefaultBrowserClientOptions({
beforeSend: event => {
expect(event.platform).toBe('javascript');
resolve();
return event;
},
dsn,
});
setCurrentClient(new BrowserClient(options));
captureEvent({ message: 'event' });
}));

it('should not dedupe an event on bound client', async () => {
const localBeforeSend = jest.fn();
const localBeforeSend = vi.fn();
const options = getDefaultBrowserClientOptions({
beforeSend: localBeforeSend,
dsn,
Expand All @@ -295,7 +304,7 @@ describe('SentryBrowser', () => {
});

it('should use inboundfilter rules of bound client', async () => {
const localBeforeSend = jest.fn();
const localBeforeSend = vi.fn();
const options = getDefaultBrowserClientOptions({
beforeSend: localBeforeSend,
dsn,
Expand Down Expand Up @@ -374,7 +383,7 @@ describe('SentryBrowser initialization', () => {
});

it('uses SDK source from global for package name', () => {
const spy = jest.spyOn(utils, 'getSDKSource').mockReturnValue('cdn');
const spy = vi.spyOn(utils, 'getSDKSource').mockReturnValue('cdn');
init({ dsn });

const sdkData = getClient()?.getOptions()._metadata?.sdk || {};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { describe, expect, it, vi } from 'vitest';

import * as SentryCore from '@sentry/core';

import { BrowserClient, breadcrumbsIntegration, flush } from '../../../src';
import { BrowserClient, breadcrumbsIntegration, flush } from '../../src';
import { getDefaultBrowserClientOptions } from '../helper/browser-client-options';

describe('Breadcrumbs', () => {
Expand All @@ -14,7 +16,7 @@ describe('Breadcrumbs', () => {
SentryCore.setCurrentClient(client);
client.init();

const addBreadcrumbSpy = jest.spyOn(SentryCore, 'addBreadcrumb').mockImplementation(() => {});
const addBreadcrumbSpy = vi.spyOn(SentryCore, 'addBreadcrumb').mockImplementation(() => {});

client.captureMessage('test');
await flush(2000);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { describe, expect, it } from 'vitest';

import type { StackFrame } from '@sentry/types';

import { applySourceContextToFrame } from '../../../src/integrations/contextlines';
import { applySourceContextToFrame } from '../../src/integrations/contextlines';

const lines = ['line1', 'line2', 'line3', 'line4', 'line5', 'line6', 'line7', 'line8', 'line9'];
describe('ContextLines', () => {
Expand Down
Loading

0 comments on commit 21b0dae

Please sign in to comment.