I'm writing unit tests for a client's website built with Gatsby. I need to be able to deliver 100% coverage. I am unable to make major edits to the source code, since I didn't build the site nor do I own the code, lest I risk breaking the UI (I'm not doing snapshot or UI testing).
I have been searching for an answer within Github issues, Stack Overflow, etc, and it seems there are recurring peculiarities with the usage of /* istanbul ignore next */.
With Gatsby, you have to check for references to the window for any scripts or Web APIs and conditionally ignore that code if typeof window === 'undefined', since Gatsby statically generates the site on the server. To add coverage to those statements, branches, functions and lines, I have been able to use /* istanbul ignore next */. However, I am having a rough time with a particular class component.
I have tried using /* istanbul ignore next */ before componentDidMount and componentDidUpdate, just inside the lifecycle definitions, between the function name and parentheses, before the if blocks within the lifecycles. I've also tried using /* istanbul ignore if */.
No matter what code I use, I cannot get coverage. I am open to any suggestions here, whether a better approach to using ignore statements or a hint on ways to create tests that would do the trick. Thank you for your help!
Here are uncoverable (thus far) lines of the component:
careers.js
  componentDidMount() {
    this.context.setHeaderTheme(`bright`)
    /* istanbul ignore next */
    if (typeof window !== `undefined` && typeof document !== `undefined`) {
      if (!window.Grnhse) {
        const script = document.createElement(`script`)
        script.setAttribute(
          `src`,
          `<hidden/path/for/security/purposes>`
        )
        script.setAttribute(`width`, `100%`)
        script.onload = () => window.Grnhse && window.Grnhse.Iframe.load()
        document.body.appendChild(script)
      } else {
        if (window.Grnhse) {
          window.Grnhse.Iframe.load()
        }
      }
    }
  }
  componentDidUpdate() {
    /* istanbul ignore next */
    if (
      !this.scrollDone &&
      typeof window !== `undefined` &&
      window.location.search.includes(`gh_jid`) &&
      this.greenhouseContainer
    ) {
      this.scrollDone = true
      window.scrollTo({
        top: this.greenhouseContainer.offsetTop,
        behavior: `smooth`,
      })
    }
  }  
I think I found an answer that works.
Within jest.config.js with Jest version 26.0, you can configure the coverageProvider to be either babel (default) or v8 (considered experimental).
I changed to v8 and installed v8-to-istanbul:
npm i --save-dev v8-to-istanbul
This provides some new functionality which seems to work wonders. I got to 100% coverage on everything but functions immediately.
    /* c8 ignore next 16 */
    if (typeof window !== `undefined` && typeof document !== `undefined`) {
      if (!window.Grnhse) {
        const script = document.createElement(`script`)
        script.setAttribute(
          `src`,
          `...`
        )
        script.setAttribute(`width`, `100%`)
        script.onload = () => window.Grnhse && window.Grnhse.Iframe.load()
        document.body.appendChild(script)
      } else {
        if (window.Grnhse) {
          window.Grnhse.Iframe.load()
        }
      }
    }
    /* c8 ignore next 13 */
    if (
      !this.scrollDone &&
      typeof window !== `undefined` &&
      window.location.search.includes(`gh_jid`) &&
      this.greenhouseContainer
    ) {
      this.scrollDone = true
      window.scrollTo({
        top: this.greenhouseContainer.offsetTop,
        behavior: `smooth`,
      })
    }
Please check out this package if you run into a similar issue: https://openbase.io/js/v8-to-istanbul/documentation#ignoring-the-next-line
Moreover, I found a method for testing that the script was appended to the DOM on componentDidMount with @testing-library/react and jest:
  it(`adds script to body`, async () => {
    render(<CareersWithProvider />)
    const Grnhse = await waitFor(() => screen.findAllByTestId(`Grnhse`))
    expect(Grnhse).not.toBeNull()
  })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With