Next.js Cypress 測試在 Github Actions 中失敗(無法讀取未定義的屬性(閱讀 'getInitialProps))



我正试图通过Github Actions在Next.js React应用程序上运行无头Cypress测试。当我在本地构建和启动我的应用程序时,Cypress测试运行良好;然而,当我在Github Actions中运行相同的命令时,我似乎得到了一个Next.js错误,表明属性getInitialProps抛出了一个错误。

以下是我的Cypress测试的Github Action定义:

- 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

其中我的e2e命令是:

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

我只在Next.js项目的根文档中引用了getInitialProps

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],
};
};

当我在构建项目后在本地运行e2e命令时,我可以运行并通过所有测试,但我在Github中获得的测试输出如下:

====================================================================================================
(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.

我们相信这个错误源于Next.js,但仍然不确定为什么在本地运行相同的步骤会产生积极的结果,而在CI中运行会产生错误。下面是next.config.js配置,显示我们正在使用独立模式:

/** @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'],
},
});

我们的节点版本是16.17.1,我们正在为Github操作提取特定版本。如果我的任何配置看起来不正确,请告诉我。谢谢

此错误可能有多种原因。GitHub上有一个悬而未决的问题,建议进行各种修复,包括:

  • 不从所有页面导出默认值
  • 将swcMinify设置为true(我可以从您的配置中看到,您将其设置为false(

在我的情况下,在运行Cypress测试时,我在CI(Ubuntu(中遇到了与您相同的错误,但在本地(MacOS(中没有。

对我来说,事实证明它与npm有关。package-lock.json文件没有列出@swc/core模块的操作系统和体系结构二进制文件。

为了解决这个问题,我必须运行npm install @swc/core。diffingpackage-lock.json为不同的操作系统和体系结构排列显示了许多不同的条目。这让CI对我起到了作用。

尽管如此,在你的情况下,根本原因可能会有所不同。如果你还在挣扎,我建议你在上面链接的GitHub问题中发布一个可复制的测试用例。

最新更新