Reputation: 21
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
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
Upvotes: 0
Reputation: 11
This error can have multiple causes. There is an open issue on GitHub with various suggested fixes, including:
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