user2844780
user2844780

Reputation: 21

Next.js Cypress tests fail in Github Actions (cannot read properties of undefined (reading 'getInitialProps))

I am trying to run my headless Cypress tests on my Next.js React app via Github Actions. When I build and start my app locally, the Cypress tests work fine; however when I run the same command in Github Actions I appear to be getting a Next.js error indicating that the property getInitialProps throws an error.

Here is my Github Action definition for my Cypress tests:

      - uses: cypress-io/github-action@v4
        with:
          install-command: npm install
          build: npm run build
          spec: cypress/e2e/*.ts
          headed: true
          command: npm run e2e
          browser: firefox

where my e2e command is:

"e2e": "start-server-and-test start http://localhost:3000 cypress:ci"

I only reference the getInitialProps in the root document of my Next.js project:

export default class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          <meta charSet="utf-8" />
          <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
          <link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" />
          <link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" />

          <meta name="theme-color" content={palette.light.primary.main} />
          <link rel="manifest" href="/manifest.json" />

          <meta
            name="description"
            content="blah"
          />
          <meta name="keywords" content="blah" />
          <meta name="author" content="blah" />
        </Head>

        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

MyDocument.getInitialProps = async (ctx) => {
  const originalRenderPage = ctx.renderPage;

  const cache = createEmotionCache();
  const { extractCriticalToChunks } = createEmotionServer(cache);

  ctx.renderPage = () =>
    originalRenderPage({
      enhanceApp: (App) => (props) =>
      (
        <CacheProvider value={cache}>
          <App {...props} />
        </CacheProvider>
      ),
    });

  const initialProps = await Document.getInitialProps(ctx);

  const emotionStyles = extractCriticalToChunks(initialProps.html);
  const emotionStyleTags = emotionStyles.styles.map((style) => (
    <style
      data-emotion={`${style.key} ${style.ids.join(' ')}`}
      key={style.key}
      // eslint-disable-next-line react/no-danger
      dangerouslySetInnerHTML={{ __html: style.css }}
    />
  ));

  return {
    ...initialProps,
    styles: [...React.Children.toArray(initialProps.styles), ...emotionStyleTags],
  };
};

When I run the e2e command locally after building the project I can get all of my tests to run and pass yet the output I get for my tests in my Github Actions are the following:

====================================================================================================
  (Run Starting)
  ┌────────────────────────────────────────────────────────────────────────────────────────────..
  │ Cypress:        10.6.0                                                                         │
  │ Browser:        Electron 102 (headless)                                                        │
  │ Node Version:   v16.17.1 (/__t/node/16.17.1/x64/bin/node)                                      │
  │ Specs:          2 found (product.cy.ts, project.cy.ts)                                         │
  │ Searched:       cypress/e2e/**/*.cy.***js,jsx,ts,tsx***                                            │
  └────────────────────────────────────────────────────────────────────────────────────────────..
─────────────────────────────────────────────────────────────────────────────────────────────
                                                                                                    
  Running:  product.cy.ts                                                                   (1 of 2)

  product pages
    1) should open a list of products when clicking on a project
  0 passing (7s)
  1 failing
  1) product pages
       should open a list of products when clicking on a project:
     TypeError: The following error originated from your application code, not from Cypress. It was caused by an unhandled promise rejection.
  > Cannot read properties of undefined (reading 'getInitialProps')
When Cypress detects uncaught errors originating from your application it will automatically fail the current test.
This behavior is configurable, and you can choose to turn this off by listening to the `uncaught:exception` event.

We believe that the error is stemming from Next.js but still not sure why running the same steps locally yield a positive result while running in CI yields an error. Here is the next.config.js configuration to show that we are using standalone mode:

/** @type {import('next').NextConfig} */
/* eslint-disable @typescript-eslint/no-var-requires */
const withTM = require('next-transpile-modules')(['react-dnd']);

module.exports = withTM({
  reactStrictMode: true,
  trailingSlash: true,
  output: 'standalone',
  swcMinify: false,
  eslint: {
    dirs: ['src'],
  },
});

Our node version is 16.17.1 and we are pulling that specific version for our Github Actions. Please let me know if any of my configuration does not look right. Thanks!

Upvotes: 1

Views: 1001

Answers (2)

Kaustav Ghosh
Kaustav Ghosh

Reputation: 25

I had roughly the same error:

Error: supabaseUrl is required.
    at new pD (.next/server/app/page.js:14:68649)
    at 12869 (.next/server/app/page.js:14:72769)
    at Function.t (.next/server/webpack-runtime.js:1:128)
 ⨯ unhandledRejection:  Error: supabaseUrl is required.
    at new pD (.next/server/app/page.js:14:68649)
    at 12869 (.next/server/app/page.js:14:72769)
    at Function.t (.next/server/webpack-runtime.js:1:128)
 ⨯ Error: supabaseUrl is required.
    at new pD (.next/server/app/page.js:14:68649)
    at 12869 (.next/server/app/page.js:14:72769)
    at Object.t [as require] (.next/server/webpack-runtime.js:1:128)
    at JSON.parse (<anonymous>) {
  digest: '2137665462'
}

I had to update the github actions file with the secrets

name: Run Tests

on:
  pull_request:
    branches: [dev, staging, prod]
    types: [opened, synchronize, reopened]

jobs:
  testing-stuff:
    runs-on: ubuntu-latest

    env:
      NEXTAUTH_SECRET: testing_secret
      NEXTAUTH_URL: http://localhost:3000
      SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
      SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
      NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
      NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.SUPABASE_ANON_KEY }}
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
      REDIS_URL: redis://localhost:6379
      UPSTASH_REDIS_REST_URL: ${{ secrets.UPSTASH_REDIS_REST_URL }}
      UPSTASH_REDIS_REST_TOKEN: ${{ secrets.UPSTASH_REDIS_REST_TOKEN }}

    services:
      redis:
        image: redis
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Run Jest Unit Tests
        run: npm run test

      - name: Run Cypress Tests
        uses: cypress-io/github-action@v6
        with:
          build: npm run build
          start: npm start
          wait-on: "http://localhost:3000"
          record: false
          publish-summary: true
          component: false

Then i had to add the secrets in github secrets enter image description here

Upvotes: 0

IvanM
IvanM

Reputation: 11

This error can have multiple causes. There is an open issue on GitHub with various suggested fixes, including:

  • not exporting default from all your pages
  • having swcMinify set to true (I can see from your config that you have it set to false)

In my case, I got the same error in CI (Ubuntu) as you when running Cypress tests, but not locally (MacOS).

For me, it turned out to be npm-related. The package-lock.json file did not have the operating system and architecture binaries listed for the @swc/core module.

To fix this, I had to run npm install @swc/core. Diffing package-lock.json showed lots of different entries for different permutations of operating systems and architectures. That got things working in CI for me.

All that said, the root cause could be different in your case. If you are still struggling, I would suggest posting in the GitHub issue linked above with a reproducible test case.

Upvotes: 1

Related Questions