Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(replay): Use vitest instead of jest #11899

Merged
merged 12 commits into from
May 8, 2024
Merged

Conversation

billyvg
Copy link
Member

@billyvg billyvg commented May 5, 2024

Use vitest instead of jest. Some notes:

  • Use vi/jest *Async fake timer functions instead of process.nextTick
  • Our useFakeTimers module was setting an interval which was causing all sorts of flakes in tests with the updated fake timers library
  • removed the interval in use-fake-timers module which seemed to be unnecessary and was causing lots of flakes in our tests (also was able to remove all of the random tick values in timestamps due to this)

From the CI runs I've looked at, doesn't seem like much of a runtime difference.

WIP, use vitest instead of jest. Some notes:

* Using jsdom 24 to deal with `TextEncoder` issues
* Use vi/jest `*Async` fake timer functions instead of `process.nextTick`
* Our `useFakeTimers` module was setting an interval which was causing all sorts of flakes in tests with the updated fake timers library
@@ -73,7 +73,10 @@
"@sentry-internal/rrweb": "2.15.0",
"@sentry-internal/rrweb-snapshot": "2.15.0",
"fflate": "^0.8.1",
"jsdom-worker": "^0.2.1"
"jest-matcher-utils": "^29.0.0",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our custom matchers use a util fn from this lib to pretty print diffs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can possibly refactor this later to avoid this dependency, but all good for now!

packages/replay-internal/package.json Outdated Show resolved Hide resolved
packages/replay-internal/package.json Outdated Show resolved Hide resolved
@@ -1,17 +1,17 @@
import { TextEncoder } from 'util';
Copy link
Member Author

@billyvg billyvg May 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now included in jsdom Not sure what dependency resolved it in between jsdom/vitest.

Comment on lines 1 to 2
import { vi } from 'vitest';
import type { Assertion, AsymmetricMatchersContaining, Mocked, MockedFunction } from 'vitest';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't sure what people would prefer, globals vs explicit imports. For this PR I'm just importing vi and types, but can follow-up to make it consistent.

Comment on lines -19 to -26
const saveSessionSpy = jest.fn();

jest.mock('../../src/session/saveSession', () => {
return {
saveSession: saveSessionSpy,
};
});

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gets hoisted and yells at you for using vars outside of scope

@@ -48,8 +50,7 @@ describe('Integration | eventProcessors', () => {
const TEST_EVENT = getTestEventIncremental({ timestamp: BASE_TIMESTAMP });

mockRecord._emitter(TEST_EVENT);
jest.runAllTimers();
jest.advanceTimersByTime(1);
vi.runAllTimers();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'll do a separate PR to update how we use fake timers to remove nextTick calls and change runAllTimers to advancedToNextTimerAsync or runAllTimersAsync

Comment on lines +377 to +391
{
type: 5,
timestamp: BASE_TIMESTAMP,
data: {
tag: 'breadcrumb',
payload: {
timestamp: BASE_TIMESTAMP / 1000,
type: 'default',
category: 'console',
data: { logger: 'replay' },
level: 'info',
message: '[Replay] Creating new session',
},
},
},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why old test didn't have this

Comment on lines -7 to -13
beforeAll(function () {
interval = _setInterval(() => jest.advanceTimersByTime(20), 20);
});
import { vi } from 'vitest';

afterAll(function () {
_clearInterval(interval);
});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what this was used for but this was causing all sorts of trouble in the tests.

@billyvg billyvg changed the title feat(replay): Use vitest instead of jest [WIP] feat(replay): Use vitest instead of jest May 6, 2024
@billyvg billyvg marked this pull request as ready for review May 6, 2024 13:49
@billyvg billyvg requested a review from a team as a code owner May 6, 2024 13:49
@billyvg billyvg requested a review from mydea May 6, 2024 13:49
Comment on lines +54 to +56
"fix": "run-s fix:biome fix:eslint",
"fix:eslint": "eslint . --format stylish --fix",
"fix:biome": "biome check --apply .",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this, kept running into lint errors because I only want to yarn fix this package.

Copy link
Member

@mydea mydea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty awesome!

@billyvg billyvg merged commit 4cc5301 into develop May 8, 2024
98 checks passed
@billyvg billyvg deleted the feat-use-vitest-replay branch May 8, 2024 10:36
andreiborza pushed a commit that referenced this pull request May 16, 2024
Use vitest instead of jest. Some notes:

* Use vi/jest `*Async` fake timer functions instead of
`process.nextTick`
* Our `useFakeTimers` module was setting an interval which was causing
all sorts of flakes in tests with the updated fake timers library
* removed the interval in `use-fake-timers` module which seemed to be
unnecessary and was causing lots of flakes in our tests (also was able
to remove all of the random tick values in timestamps due to this)
billyvg added a commit that referenced this pull request May 22, 2024
… detection (#11924)

This PR makes sure we use the native, unwrapped `setTimeout`
implementation of the browser. Some environments, e.g. Angular, monkey
patch this for their change detection, leading to performance issues
(possibly). We have already changed this in rrweb, but we also have some
usage of this in replay itself.

This PR _should_ work fine, however all test fail today because we
heavily use `jest.useFakeTimers()`, which basically monkey patches fetch
too. So with this change, we do not use the patched timers, leading to
everything blowing up 🤯


Based on #11864
Depends on #11899

---------

Co-authored-by: Francesco Novy <francesco.novy@sentry.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants