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

Window event listener fires but spy does not count it #7202

Closed
6 tasks done
nick-roth-sas opened this issue Jan 9, 2025 · 4 comments
Closed
6 tasks done

Window event listener fires but spy does not count it #7202

nick-roth-sas opened this issue Jan 9, 2025 · 4 comments

Comments

@nick-roth-sas
Copy link

Describe the bug

Trying to migrate a test from jest to vitest. I have a use case where we are listening for message events on window, and I want to verify calls to the listener with a spy.

The provided reproduction shows two scenarios. One where the I call vi.spyOn before the event listener is added and the second where event listener is added first. The listener is called and runs in both cases but the spy only counts if the spy was created before adding to window.

This behavior seems unintuitive at best and like an error in the worst case.

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-t28wegld?file=test%2Fbasic.test.ts

System Info

System:
    OS: macOS 15.1.1
    CPU: (8) arm64 Apple M3
    Memory: 133.05 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.20.4 - ~/.nvm/versions/node/v18.20.4/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v18.20.4/bin/yarn
    npm: 10.7.0 - ~/.nvm/versions/node/v18.20.4/bin/npm
  Browsers:
    Chrome: 131.0.6778.206
    Safari: 18.1.1
  npmPackages:
    vitest: ^2.1.8 => 2.1.8

Used Package Manager

yarn

Validations

@hi-ogawa
Copy link
Contributor

Can you check if this really works on Jest?

I don't think this would work because listenerObj.listener is simply accessed before spied. You would need to delay it like this to make it work:
https://stackblitz.com/edit/vitest-dev-vitest-ril9f8z1?file=src%2Fbasic.ts

export const register = () => {
  // window.addEventListener('message', listenerObj.listener);
  window.addEventListener('message', (e) => listenerObj.listener(e));
};

@nick-roth-sas
Copy link
Author

Hi @hi-ogawa Thanks for the quick reply. The actual use case is more complex and I thought I boiled it down to what's in the sample. But I think you might be right and I just needed to step back a bit. I will look at this some more, including a jest version.

@nick-roth-sas
Copy link
Author

nick-roth-sas commented Jan 10, 2025

I put together a jest project that does the same thing. https://stackblitz.com/edit/stackblitz-starters-idnbgrtd?file=src%2Fmain.spec.js This shows both tests passing.

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Jan 11, 2025

@nick-roth-sas Thanks for the follow up. Okay, I think the same pattern actually exists on jest if you run only the 2nd test. https://stackblitz.com/edit/stackblitz-starters-emriphcy?file=src%2Fmain.spec.js

Probably, the test looks working when running two together only because first spy didn't get cleaned up. I'd assume that's not what you intended in the test.

The difference between Vitest and Jest is whether calling twice vi.spyOn(listenerObj, 'listener') would reset the spy. This is actually fixed to align with Jest in #6464 and the same test (running two tests together) is going to pass in Vitest 3 https://stackblitz.com/edit/vitest-dev-vitest-wgwrvy9a?file=test%2Fbasic.test.ts.

I don't think the issue is on Vitest, so let me close the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants