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

DO NOT MERGE - rewrite test act helpers based on react/#15591 #266

Merged
merged 6 commits into from May 28, 2019

Conversation

threepointone
Copy link
Contributor

@threepointone threepointone commented May 10, 2019

This needs facebook/react#15591 to land to work correctly.

This simplifies your test helpers to loop until all timers are flushed (including the ones that get queued after updates), and works in concurrent mode.

Sunil Pai added 3 commits May 10, 2019 12:13
This simplifies your test helpers to loop until all timers are flushed (including the ones that get queued after updates), and works in concurrent mode. I also renamed actSuspense to actAsync to be clearer.
@threepointone
Copy link
Contributor Author

(I also wanted to rename actSuspense to actAsync since it isn't exactly suspense related, but I'll leave that to you)

@bvaughn
Copy link
Owner

bvaughn commented May 24, 2019

Since facebook/react#15591 was merged and we're running on a canary release that includes it, I tried applying these changes in master. Looks like everything works except for inspectedElementContext-test.js which always fails with an infinite loop bug here:

while (jest.getTimerCount() > 0) {
// $FlowFixMe Flow doens't know about "await act()" yet
await TestUtils.act(async () => {
jest.runAllTimers();
});
}

Seems like the underlying cause are these bridge messages:

bridge.send('inspectElement', { id: selectedElementID, rendererID });
};
// Send the initial inspection request.
// We'll poll for an update in the response handler below.
sendRequest();
// Update the $r variable.
bridge.send('selectElement', { id: selectedElementID, rendererID });

Since the bridge batches things with a timeout:

this._messageQueue.push(event, payload, transferable);
if (!this._timeoutID) {
this._timeoutID = setTimeout(this._flush, 0);
}

Not sure why they would cause problems specifically, given that other bridge messages don't cause other tests to fail. I've tried commenting out the setTimeout further down to see if that's somehow related, but it isn't. Maybe we just aren't triggering other bridge messages within the actAsync helper?

@bvaughn
Copy link
Owner

bvaughn commented May 24, 2019

Let's talk when we're both back in the office on Tuesday, Sunil. In the meanwhile I'll push my work in progress here https://github.com/bvaughn/react-devtools-experimental/pull/new/threepointone-act-async

@threepointone
Copy link
Contributor Author

boop, have a look and let me know if this solves your problems

@threepointone
Copy link
Contributor Author

sorry, I should be a commie about this
our problems

@bvaughn
Copy link
Owner

bvaughn commented May 28, 2019

Cool, thanks Sunil!

@bvaughn bvaughn merged commit 388b03d into bvaughn:master May 28, 2019
@bvaughn
Copy link
Owner

bvaughn commented Aug 15, 2019

Hey uh...looks like jest.getTimerCount() doesn't exist in the version of Jest used in the React repo. Wondering what you're suggesting folks use who are using a version of Jest older than v24 (like me now, heh heh)

@threepointone
Copy link
Contributor Author

Oh hmm. We could just update to jest 24, if you could help resolve this issue with react-is? facebook/react#15778

@threepointone
Copy link
Contributor Author

(Alternately, there may be a way of getting at the timer count with a hidden api, I’ll have a look)

@bvaughn
Copy link
Owner

bvaughn commented Aug 15, 2019

Upgrading might be nice

@SimenB
Copy link

SimenB commented Aug 15, 2019

I'm pretty sure there's no way to access a count of scheduled timers in 23 without using a custom testEnvironment which could expose the FakeTimers instance on the global injected into the test

@bvaughn
Copy link
Owner

bvaughn commented Aug 15, 2019

That doesn't sound out of the question, unless I'm misunderstanding something.

It looks like the fake-timers object exposes a mockGetTimersCount() which I think might satisfy the need my tests have.

Not sure how to get a handle on that object though.

@bvaughn
Copy link
Owner

bvaughn commented Aug 15, 2019

Okay. I think that path would entail:

  • Extending the default Jest env (e.g. jest-environment-jsdom)
  • Specifying a custom testEnvironment in my Jest config to point to the subclass
  • Getting a handle on this.fakeTimers in my environment subclass
  • Exposing that handle to tests via some global ref the custom env's this.global

The last bit is the part I'm least sure about. I don't know if there are timing/concurrency concerns, or how best to share between the test env and test code. I tried storing a reference on global but it doesn't seem like that's shared between the env and the test (or maybe something is resetting it)

I'm able to inject, but I'm not seeing that function- maybe it was added in a later Jest v23 release. I'll try bumping that.

@bvaughn
Copy link
Owner

bvaughn commented Aug 15, 2019

Actually, tracing through the Jest source code- it looks like Jest sets mockGetTimersCount on the global object itself 😆 I don't even need to use a custom environment for this.

@SimenB
Copy link

SimenB commented Aug 15, 2019

Ah, I forgot about that. Removed in 24 and replaced by getTimerCount in jestjs/jest#7285. Great you were able to find it

@bvaughn
Copy link
Owner

bvaughn commented Aug 15, 2019

No problem 😄 Now I'm more familiar with Jest internals, having traced through this, so not wasted effort.

@SimenB
Copy link

SimenB commented Aug 15, 2019

Awesome! To answer your above question (even though they're striked out, so you probably figured it out), all your steps are correct. Should probably delete in teardown as well to avoid a potential memory leak, but all tests gets their own global, so there shouldn't have been any concurrency issues

@bvaughn
Copy link
Owner

bvaughn commented Aug 15, 2019

You rock. Thansk~

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

3 participants