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

ReferenceError: self is not defined on Jest tests [email protected] #8365

Comments

@atomassoni
Copy link

atomassoni commented Jul 15, 2024

Operating System

iOS 16+

Browser Version

Chrome latest

Firebase SDK Version

10.12.3

Firebase SDK Product:

Analytics, Auth, Firestore, Functions, Remote-Config

Describe your project's tooling

Ionic Stencil app with Jest

Describe the problem

Running Jest tests I got this error anywhere I had imported firebase, I'm using the emulator on jest. Here is my command:

"test.ci": "firebase emulators:exec --only firestore 'stencil test --spec --ci --coverage --exit'",

Rolling back to [email protected] fixed the issue.

FAIL src/components/pages/sw-subscribe-success-page/sw-subscribe-success-page.spec.ts
  ● Test suite failed to run
    ReferenceError: self is not defined
       9 | import { Analytics, getAnalytics } from "firebase/analytics"
    > 11 | import firebaseCompat from "firebase/compat/app"
         | ^
      12 | import "firebase/compat/auth"
      13 | import "firebase/compat/firestore"
      14 | import "firebase/compat/functions"
      at Object.<anonymous> (node_modules/@firebase/app-compat/src/index.ts:26:21)
      at Object.<anonymous> (node_modules/firebase/compat/app/dist/index.cjs.js:3:16)
      at Object.require (src/global/firebase.ts:11:1)
      at Object.require (src/global/native.ts:4:1)
      at Object.require (src/global/workout-utils.ts:2:1)
      at Object.require (src/reducers/edit-workout.ts:2:1)
      at Object.require (src/reducers/index.ts:5:1)
      at Object.require (src/store/index.ts:3:1)
      at Object.require (src/components/pages/sw-subscribe-success-page/sw-subscribe-success-page.tsx:3:1)
      at Object.<anonymous> (src/components/pages/sw-subscribe-success-page/sw-subscribe-success-page.spec.ts:1:1)

Steps and code to reproduce issue

For our app I can update from Firebase 10.12.2 to 10.12.3 to trigger the error. Rolling back to 10.12.2 fixes it.

@atomassoni atomassoni added new A new issue that hasn't be categoirzed as question, bug or feature request question labels Jul 15, 2024
@google-oss-bot
Copy link
Contributor

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@atomassoni atomassoni changed the title Title for the bug ReferenceError: self is not defined on Jest tests [email protected] Jul 15, 2024
@jbalidiong jbalidiong added api: core needs-attention and removed needs-triage new A new issue that hasn't be categoirzed as question, bug or feature request labels Jul 15, 2024
@hsubox76
Copy link
Contributor

hsubox76 commented Jul 16, 2024

May be related to #8315. The change seems to cause isBrowser() to pass in this environment where it previously failed, which causes this check: https://github.com/firebase/firebase-js-sdk/blob/master/packages/app-compat/src/index.ts#L26 to no longer short-circuit on the first condition, but continue to the second, where it fails to find global self. Need to check which of these assumptions is wrong.

Edit: Jest runs in Node so self doesn't exist. However, because it's using JSDOM to mimic the DOM for browser tests, window does exist. I guess we should probably leave isBrowser() as is, because when you're running Jest in JSDOM mode, you do want it to pass the isBrowser() check as it's pretending to be a browser. We should probably fix the (self as any).firebase check.

@hsubox76 hsubox76 self-assigned this Jul 16, 2024
@hsubox76 hsubox76 added bug and removed question labels Jul 16, 2024
@hsubox76
Copy link
Contributor

Actually I looked further into this and it looks like Jest is supposed to have self, if you are using JSDOM mode.
https://stackoverflow.com/questions/68678854/jest-test-suite-fails-with-message-self-is-not-defined

I'm not actually sure what kind of environment you have where window exists but self doesn't. I've tried to reproduce using the latest version of Jest, using both the node and jsdom testEnvironments. Can you share your Jest config? What Jest version are you using?

@atomassoni
Copy link
Author

atomassoni commented Jul 18, 2024

Hi, I'm using the @Stencil preset "jest": {
"preset": "@stencil/core/testing",
}

with jest 29.

  "@types/jest": "^29.5.11",
    "jest": "^29.7.0",
    "jest-cli": "^29.7.0",

Now get this:

I tried rolling back my @stencil/core version from the latest 4.19.2 to what I was using before which was version 4.12.0 and that ALSO fixed the issue with the latest version of firebase. There are some reports on the stencil github of errors on the latest version, so maybe I'll file a bug with them if I could get a clearer picture of what's happening.

Sorry, I got ahead of myself. I rolled stencil forward and back again and I could not "reproduce" the fix. I double checked and the version of Firebase was actually rolled back which caused it to function with both versions of Stencil.

@hsubox76
Copy link
Contributor

Looks like stencil does not use either Jest's provided jest-environment-node nor jest-environment-jsdom for the Jest test environment but creates a custom one https://github.com/ionic-team/stencil/blob/main/src/testing/jest/jest-29/jest-environment.ts

The custom environment is built off of Jest's jest-environment-node which, due to being for Node, has neither self nor window. If you were using Jest's jest-environment-jsdom it would inject both window and self into the global scope, as both should exist in a simulated browser environment. I'm guessing that when stencil's custom environment calls puppeteer to set up the simulated browser, it only adds window and not self. I don't think that's an accurately simulated browser environment if it's missing self so I think it might be a bug on stencil/puppeteer's end?

In your case, maybe a quick hacky workaround would be to assign const self = window anywhere in the global scope of your tests, like at the top of the test file, or if you have any kind of pre-test setup function, or if there's a way to inject it into the test environment config.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.