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

[v25] --detectLeaks option always reports a leak when using jsdom environment #9507

Closed
dylanwulf opened this issue Feb 3, 2020 · 16 comments · Fixed by jsdom/jsdom#2840 or #9606
Closed

Comments

@dylanwulf
Copy link

dylanwulf commented Feb 3, 2020

💥 Regression Report

Starting in v25, the --detectLeaks option will always report a leak when using env=jsdom.

Last working version

Worked up to version: v24.9.0

Stopped working in version: v25.0.0

To Reproduce

https://github.com/dylanwulf/jest-25-detect-leak
npm run test: run test with jsdom environment
npm run test:sixteen: run test with jest-environment-jsdom-sixteen
npm run test:node: run test with node environment

When using jsdom or jest-environment-jsdom-sixteen it reports a memory leak even though the only thing in the test is a console log. When using the node environment, it does not report a leak.

Expected behavior

Should not report a memory leak for a simple test that clearly does not leak memory.

Link to repl or repo (highly encouraged)

https://github.com/dylanwulf/jest-25-detect-leak

Run npx envinfo --preset jest

Paste the results here:

  System:
    OS: Windows 10 10.0.18363
    CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
  Binaries:
    Node: 12.14.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.21.1 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD
  npmPackages:
    jest: 25.1.0 => 25.1.0
@SimenB
Copy link
Member

SimenB commented Feb 3, 2020

Thanks! We probably mess with some global or some such we don't cleanup...

@dav1app
Copy link

dav1app commented Feb 3, 2020

This very minimal test point leaks

describe('MemoryLeakTest', function () {
  it('should should do nothing', function () {
    expect(true).toBeTruthy()
  })
})

run with ./node_modules/jest/bin/jest.js --detectLeaks.

@lh0x00
Copy link
Contributor

lh0x00 commented Feb 4, 2020

I debugged and this issue from jsdom package, I will try to fix it and update in new version in Jest. Ref jsdom/jsdom#2757

@lh0x00
Copy link
Contributor

lh0x00 commented Feb 5, 2020

hi @SimenB , ref jsdom/jsdom#2825
jsdom maybe not release a bug fix version 15. Will I downgrade the current version of jsdom to use or upgrade to the new version? Upgrading to the new version will only compatible node >= 10, I don't think this is a good way.

@SimenB
Copy link
Member

SimenB commented Feb 5, 2020

You can use https://www.npmjs.com/package/jest-environment-jsdom-sixteen to get v16 in your tests. Jest itself well upgrade the default version in Jest 26

@lh0x00
Copy link
Contributor

lh0x00 commented Feb 5, 2020

@SimenB in Jest 26, jest-environment-jsdom should be downgrade version of jsdom? can I make a PR to do it?

@SimenB
Copy link
Member

SimenB commented Feb 5, 2020

Jest 26 is months away, and we'll upgrade, not downgrade. So no need for a PR yet 🙂

If you want the old version of jsdom back, you can install jest-environment-jsdom@24 and use that through config.

terite added a commit to terite/jsdom that referenced this issue Feb 8, 2020
A monkey-patch as modified by commit 75a921e
maintains a reference to the most recent JSDOMParse5Adapter (and all its
options) through the push/pop closures. Because the monkey-patches are
never cleaned up, there is always a reference to the most recent
JSDOMParse5Adapter and its related objects.

This fixes jestjs/jest#9507
This may fix jsdom#2757
@terite
Copy link
Contributor

terite commented Feb 8, 2020

I was able to reproduce this using the above code snippet, and have tracked the issue down to commit jsdom/jsdom@75a921e released in jsdom 14.

It is possible to work around the issue by adding the following code snippet to the teardown method of jest-environment-jsdom

  async teardown() {
    // ...

    const OpenElementStack = require('parse5/lib/parser/open-element-stack')
    if (OpenElementStack.prototype.pop.toString().includes('OriginalPop')) {
      delete OpenElementStack.prototype.pop;
    }
    if (OpenElementStack.prototype.push.toString().includes('OriginalPush')) {
      delete OpenElementStack.prototype.push;
    }
  }
}

edit: I should've read a little closer, I didn't notice that lamhieu-vk already found the issue and put up a PR. I hope the workaround steps are at least helpful for someone.

@Qziem
Copy link

Qziem commented Feb 13, 2020

@terite
Hey, to be honest I don't know what is teardown in Jest. Could you please write which file and what exactly should be changed to work around this ? Thanks!

domenic added a commit to jsdom/jsdom that referenced this issue Feb 16, 2020
The monkey-patch for maintaining the open element stack, as modified by commit 75a921e, maintained a reference to the most recent JSDOMParse5Adapter (and all its options) through the push/pop closures. This means there was always a reference from the rooted OpenElementStack.prototype.{push,pop} functions to the most recent JSDOMParse5Adapter and its related objects.

This commit instead uses the this.treeAdapter pointer, which already exists in parse5. Doing so also allows us to move the monkeypatch back into the top level, instead of establishing it on construction of each tree adapter.

Closes #2831. Closes #2825. Fixes jestjs/jest#9507.
domenic added a commit to jsdom/jsdom that referenced this issue Feb 16, 2020
The monkey-patch for maintaining the open element stack, as modified by commit 75a921e, maintained a reference to the most recent JSDOMParse5Adapter through the push/pop closures. This means there was always a reference from the rooted OpenElementStack.prototype.{push,pop} functions to the most recent JSDOMParse5Adapter and its related objects. Since one of the related objects was an element, which has a pointer to a document and window, essentially the whole JSDOM would be retained.

This commit instead uses the this.treeAdapter pointer, which already exists in parse5. Doing so also allows us to move the monkeypatch back into the top level, instead of establishing it on construction of each tree adapter.

Closes #2831. Closes #2825. Helps with the root cause of jestjs/jest#9507.
@SimenB
Copy link
Member

SimenB commented Feb 16, 2020

This has been fixed upstream in JSDOM now. Unfortunately, since we still support Node 8, we cannot upgrade to a fixed version. @terite do you think it makes sense to add your hack to jest-environment-jsdom? It seems pretty invasive, but we can probably lock down our version of jsdom (it probably won't be updated anyways, but better safe than sorry I think) and it should be relatively safe.

@jeysal @thymikee thoughts on ^?


Alternatively, people can install jest-environment-jsdom-sixteen which will install the fixed version of JSDOM (when the fix is released, which I guess should happen any minute now since the fix just got merged).

@thymikee
Copy link
Collaborator

Maybe there's a slight chance that jsdom could release a patch to v15?

@lh0x00
Copy link
Contributor

lh0x00 commented Feb 17, 2020

I asked about release a patch to v15 but it is not supported! jsdom/jsdom#2825 (comment)

@lh0x00
Copy link
Contributor

lh0x00 commented Feb 17, 2020

hmm... if we upgrade jsdom to v16 has some breaking changes, can I create a PR for it (for Jest 26)? because I have a stash in local, I updated while creating jsdom/jsdom#2825

@kirillgroshkov
Copy link

Is there a way to use jest-environment-jsdom-sixteen for all @jest-environment jsdom, but without specifying it in jest.config.js? Cause I have jestEnvironment: node there and don't want jsdom to be default.

@SimenB
Copy link
Member

SimenB commented May 1, 2020

@kirillgroshkov sorry, missed your q. It's @jest-environment jsdom-sixteen

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
8 participants