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

test: suite for expected global object behaviour #67

Closed
wants to merge 1 commit into from

Conversation

Meemaw
Copy link
Collaborator

@Meemaw Meemaw commented Dec 17, 2020

What kind of change does this PR introduce?

Bug fix, feature, docs update, ...

What is the current behaviour?

You can also link to an open issue here.

What is the new behaviour?

...

Does this PR introduce a breaking change?

What changes might users need to make in their application due to this PR?

Other information:

Please check if the PR fulfills these requirements:

  • Tests for the changes have been added
  • Docs have been added / updated

@Meemaw
Copy link
Collaborator Author

Meemaw commented Dec 17, 2020

@toomuchdesign added some more tests for the problematic behaviour regarding module imports (see #64). I think if we are somehow able to make these tests pass, it will solve all regarding this.

It seems to achieve this we would need to do something like this:

  1. Somehow delete global JSDOM objects before tests are executed (e.g. in initTesthelpers)
  2. Render server side for _document
  3. Restore JSDOM & wipe require.cache (I think this is the most tricky part)
  4. Render client side
  5. Somehow merge/hydrate the result and return client side result (for client side events to work)

@toomuchdesign
Copy link
Collaborator

jest.isolateModules has a few open issues. Linking here just for documentation purpose:

@toomuchdesign
Copy link
Collaborator

toomuchdesign commented Dec 19, 2020

Brief report after a few attempts of working around ES/jest modules and global objects.

jest.isolateModules seems quite a powerful pattern but it currently comes with a couple of unexpected limitations.

jest.isolateModules relativity

I confirm that this issue still occurs and jest.isolateModules doesn't load a fresh module if that modules is already imported outside a jest.isolateModules call.

This means that, in order to ensure we get modules isolation, we should wrap all tests in a jest.isolateModules call :)

jest.isolateModules + Typescript

Since we have to use require from inside jest.isolateModules, I found out that Typescript looses typing information of those modules imported with require. Maybe I'm missing a TS config or something else? Eg:

jest.isolateModules(() => {
  const { createElement } = require('react');
  // createElement: any
});

React multiple instances error

Taking the opposite approach with jest.resetModules() took me to the error where React detects hook calls to different React instances.

Error: Uncaught [Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
    1. You might have mismatching versions of React and the renderer (such as React DOM)
    2. You might be breaking the Rules of Hooks
    3. You might have more than one copy of React in the same app

From React docs:

In general, React supports using multiple independent copies on one page (for example, if an app and a third-party widget both use it). It only breaks if require('react') resolves differently between the component and the react-dom copy it was rendered with.

The first reason that comes to my mind is react-testing-library being imported at the top of test file while resetting modules at beforeEach test. This would cause a misalignment between react-dom module in react-testing-library scope and react module loaded in tests.

In this case a not-very-satisfying-workaround could consist of ensuring next-page-tester and testing-library gets imported after the jest.resetModules() call:

it('test description', () => {
   jest.resetModules()
   const { getPage } = require('next-page-tester');
   const { render, screen } = require('@testing-library/react');
})

@Meemaw
Copy link
Collaborator Author

Meemaw commented Dec 20, 2020

Didn't dive into the problem yet, but there might be some ideas in this issue: jestjs/jest#8987, perhaps jestjs/jest#8987 (comment) could work with the different React instances.

@toomuchdesign
Copy link
Collaborator

Well, it seems we're going to have jest.isolateModules fixed: jestjs/jest#10963 😄

@toomuchdesign toomuchdesign deleted the global-object-experiments branch January 8, 2021 17:17
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