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

Simple spy on document throws unhandled exception #6459

Closed
6 tasks done
sashberd opened this issue Sep 8, 2024 · 3 comments
Closed
6 tasks done

Simple spy on document throws unhandled exception #6459

sashberd opened this issue Sep 8, 2024 · 3 comments

Comments

@sashberd
Copy link

sashberd commented Sep 8, 2024

Describe the bug

I have next very simple react hook that catches escape key down event:
import { DependencyList, useEffect } from 'react'


const ESCAPE_KEY = 'Escape'

type CallbackFunction = (event: KeyboardEvent) => void

const useEscapeKey = (callback: CallbackFunction, dependencies: DependencyList = []): void => {
  useEffect(() => {
    if (!document || !callback) {
      return
    }

    const onKeyPress = (event: KeyboardEvent) => {
      if (event.key === ESCAPE_KEY) {
        callback(event)
      }
    }

    document.addEventListener('keydown', onKeyPress)

    return () => {
      document.removeEventListener('keydown', onKeyPress)
    }
  }, [callback, ...dependencies])
}
export default useEscapeKey

I added unit tests like:


describe('useEscapeKey hook unit tests', () => {
  let callback = vi.fn()

  afterEach(() => {
    callback.mockReset()
  })

  it('should add and remove the keydown event listener on mount and unmount', () => {
    const { unmount } = renderHook(() => useEscapeKey(callback))

    // Check if the event listener is attached
     const addEventListenerSpy = vi.spyOn(document, 'addEventListener')
    expect(addEventListenerSpy).toBeCalledTimes(1)

    // // Unmount the hook and check if the listener is removed
    const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener')
    unmount()
    expect(removeEventListenerSpy).toHaveBeenCalledWith('keydown', expect.any(Function))

    addEventListenerSpy.mockRestore()
    removeEventListenerSpy.mockRestore()
  })
})

The error I get:

⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯

Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯⎯ Unhandled Error ⎯⎯⎯⎯⎯⎯⎯
TypeError: s.getBrowserSourceMapModuleById is not a function
 ❯ Object.getSourceMap ../../../.vscode/extensions/vitest.explorer-0.10.7/dist/worker.js:3:944
 ❯ ../../../.vscode/extensions/vitest.explorer-0.10.7/dist/worker.js:1:18634
 ❯ Mt ../../../.vscode/extensions/vitest.explorer-0.10.7/dist/worker.js:1:18580
 ❯ Oe ../../../.vscode/extensions/vitest.explorer-0.10.7/dist/worker.js:3:130
 ❯ ../../../.vscode/extensions/vitest.explorer-0.10.7/dist/worker.js:3:920
 ❯ ../../../.vscode/extensions/vitest.explorer-0.10.7/dist/worker.js:3:875
 ❯ V.onTaskUpdate ../../../.vscode/extensions/vitest.explorer-0.10.7/dist/worker.js:3:809

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

I found that error thrown by next row:
expect(addEventListenerSpy).toBeCalledTimes(1)

Looks like v2.0.0 has an issue with document spying❓

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-9wx4pc?file=test%2FuseEscapeKey.spec.ts

System Info

System:
    OS: Windows 10 10.0.19045
    CPU: (12) x64 12th Gen Intel(R) Core(TM) i5-1245U
    Memory: 15.69 GB / 31.64 GB
  Binaries:
    Node: 20.11.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.22 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 10.2.4 - C:\Program Files\nodejs\npm.CMD
    pnpm: 8.15.6 - ~\AppData\Local\pnpm\pnpm.EXE
  Browsers:
    Edge: Chromium (127.0.2651.74)
    Internet Explorer: 11.0.19041.4355
  npmPackages:
    @vitejs/plugin-react: 4.1.0 => 4.1.0
    @vitest/coverage-v8: ^2.0.0 => 2.0.5
    @vitest/ui: ^2.0.0 => 2.0.5
    vite: ^4.4.9 => 4.5.3
    vitest: ^2.0.0 => 2.0.5

Used Package Manager

pnpm

Validations

@sheremet-va
Copy link
Member

sheremet-va commented Sep 8, 2024

It looks like you are using the old vscode extension. It doesn't support Vitest 2, please update it: vitest.dev/vscode

@sheremet-va
Copy link
Member

Regarding your reproduction. It doesn't have jsdom installed, so every test fails. After installing jsdom, some tests still fail:

This test fails because you need to spy on document before you attack the listener, how else would it intercept it?

const { unmount } = renderHook(() => useEscapeKey(callback));

// Check if the event listener is attached
const addEventListenerSpy = vi.spyOn(document, 'addEventListener');
expect(addEventListenerSpy).toBeCalledTimes(1);

After moving it before the render call, the new error is that addEventListenerSpy is called more than once. This is not an issue with Vitest, but with how react handles useEffect. I cannot give you any advice here, I suggest asking in Discord or open a community discussion.

@sheremet-va sheremet-va closed this as not planned Won't fix, can't repro, duplicate, stale Sep 8, 2024
@sashberd
Copy link
Author

sashberd commented Sep 8, 2024

Hi @sheremet-va Thanks for your feedback!

I think it would be beneficial to add a note to the v2.0.0 breaking change description mentioning that the new version is incompatible with the older Vitest VSCode extension. This would have saved me a lot of time trying to resolve the unit test errors I encountered after updating to version 2.0.0.

@github-actions github-actions bot locked and limited conversation to collaborators Sep 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants