sbardian / gatsby-plugin-breadcrumb

Breadcrumbs for gatsby sites
51 stars 5 forks source link

Unit Test failed with: TypeError: Cannot read properties of undefined (reading 'pathname') #236

Closed SerenaIce closed 1 year ago

SerenaIce commented 1 year ago

The features are working well on the UI pages. But when I tried to test the MyPage which includes the plugin, it gave me the error:

TypeError: Cannot read properties of undefined (reading 'pathname')

The passing mocked data:

image

And I was using the AutoGen with version "gatsby-plugin-breadcrumb": "^12.3.2", and gatsby version is 5.10.0

{ resolve: gatsby-plugin-breadcrumb, options: { useAutoGen: true, autoGenHomeLabel: Home, excludeOptions: { separator: '/' }, crumbLabelUpdates: [ { pathname: '/mypage', crumbLabel: 'MyPage' } ] } },

I'm guessing when I run the test it reads the location.pathname. Please let me know how to solve this issue which has blocked my commitment.
github-actions[bot] commented 1 year ago

Thanks for creating an issue! I try to respond as quickly as possible to all issues. If it has been a while feel free to mention me to get my attention.

sbardian commented 1 year ago

@SerenaIce correct, location in your mock data shouldn't be a string, it should be an object with pathname as a property. Give that a try and let me know. Thanks!

SerenaIce commented 1 year ago

@sbardian , please be noticed that I used the AutoGen which means I shouldn't pass the location.pathname params. But I did try that, and it came out with the same error: TypeError: Cannot read properties of undefined (reading 'pathname')

image

And I also found the tracing from the error log that it runs into the click-tracking-crumb.js which should not happen since I set AutoGen in config.

image

So not sure which object the pathname belongs to. But it seems when running test cases, the 'AutoGen' was not read and set which causes it goes into click-tracking-crumb.js. Please verify from your side.

sbardian commented 1 year ago

I also use AutoGen. The pageContext that is passed to pages still has a location property that is an object. I have never tried to mock the pageContext that is passed to a page. I'm not sure how to do what you are trying to do. Is there a reason to mock the pageContext data at all?

SerenaIce commented 1 year ago

@sbardian , to take the about-us page as an example, if we want to test it, we need to pass the pageContext prop, right? That's why I did the similar test to my pages.

image

So from the error log, I believe there're some issues in the plugin's source code.

sbardian commented 1 year ago

@SerenaIce what are you using to test the page? Are you using something like jest, testing-library, or cypress?

SerenaIce commented 1 year ago

@sbardian , we're using jest. To avoid this issue, I have to avoid to test it with passing the location.pathname = '/' below. But in this way, I have to pass the pathname when I run the pages which is not needed for AutoGen.

image
sbardian commented 1 year ago

@SerenaIce if you are unit testing using Jest and testing-library/react, I guess it makes sense you can't test the component, because Gatsby is not running to supply you the pageContext. I have a layout component that has the component in it using AutoGen.

       const Layout = ({ children, crumbs, crumbLabel }) => {
         return (
           <>
              <Breadcrumb
                crumbs={crumbs}
                crumbLabel={crumbLabel}
                disableLinks={disableLinks}
              />
              {children}
          </>
        )
   }

I use Jest and testing-library/react. Here is a simple test that seemed to work mocking the props passed to my <Layout /> component.

import React from "react"
import { render } from "@testing-library/react"
import Layout from "./layout"

describe("Layout test", () => {
  it("should render layout including breadcrumbs link", () => {
    const { queryByText } = render(
      <Layout
        crumbs={[
          {
            pathname: "/",
            crumbLabel: "Home",
          },
        ]}
      />
    )
    queryByText("Home").should.exist
  })
})

The reason you are getting Click Tracking is that none of the Gatsby tooling is running to pull in the plugin options/etc. And Click Tracking is default. So the `useAutoGen=true' is not being applied while testing and none of the pages are generating crumbs for the plugins breadcrumb components. Try splitting your Breadcumbs off into a component and unit test that component like I have above. This is just my best guess at the moment.

When Gatsby builds your site, there are plugin hooks that are called. This plugin makes use of those hooks to kick off processes that are used with the AutoGen option that generates the crumbs for each page in your site during the Gatsby build process.

SerenaIce commented 1 year ago

Thank you for the quick replies @sbardian . To put it into should be a solution. But based on my case for now, I need to put it in required pages which have differences.

sbardian commented 1 year ago

To unit test this in AutoGen mode the only thing I can think of, so that Gatsby builds your site and the plugin hooks run, AutoGen breadcrumbs are generated/etc., would be to use something like Cypress or Playwright to perform your tests. That way you would still use Gatsby and all the build steps would take place and you could perform your UI unit tests.