Cypress 11配置文件评估脚本失效及替代方案咨询
问题描述
我在构建脚本中用Node.js脚本评估Cypress配置文件,该脚本在Cypress 10中运行正常,但适配路径后在Cypress 11(版本11.0.1)中报错:
Error: Cannot find module 'C:\Users\mbolotov\AppData\Local\Cypress\Cache\11.0.1\Cypress\resources\app\node_modules\graphql/index'. Please verify that the package.json has a valid "main" entry
需求:在不修改Cypress安装文件的前提下修复该问题,或者提供其他从命令行评估Cypress配置文件并获取其值的方法。
使用的脚本如下:
let appdata = process.env.LOCALAPPDATA; let version = `11.0.1`; let src = `${appdata}/Cypress/Cache/${version}/Cypress/resources/app/node_modules/@packages/data-context/src`; const DataContext = require(`${src}/DataContext.js`).DataContext; const ProjectConfigManager = require(`${src}/data/ProjectConfigManager.js`).ProjectConfigManager; (async() => { const ctx = new DataContext({ schema: null, schemaCloud: null, modeOptions: "run", appApi: {}, localSettingsApi: {}, authApi: {}, configApi: {}, projectApi: {}, electronApi: {}, browserApi: {}, }) let configManager = new ProjectConfigManager({ ctx, configFile: 'C:\\work\\sample\\sample.config.ts', projectRoot: 'C:\\work\\sample', handlers: [], hasCypressEnvFile: false, eventRegistrar: null/*new EventRegistrar()*/, onError: (error) => {}, onInitialConfigLoaded: () => {}, onFinalConfigLoaded: () => Promise.resolve(), refreshLifecycle: () => Promise.resolve(), }) configManager.configFilePath = "sample.config.ts" configManager.setTestingType('e2e') let cfg = await configManager.getConfigFileContents() console.log(JSON.stringify(cfg)); })();
解决方案
方案一:修复现有脚本(不修改Cypress安装)
报错原因是Cypress 11中graphql包的入口文件结构变化,导致内部require时找不到指定路径。可以在脚本开头添加模块解析补丁,手动修正graphql的模块路径:
// 在脚本最顶部添加以下代码 const path = require('path'); const appdata = process.env.LOCALAPPDATA; const cypressVersion = '11.0.1'; const cypressNodeModules = path.join(appdata, 'Cypress', 'Cache', cypressVersion, 'Cypress', 'resources', 'app', 'node_modules'); // 拦截require,修正graphql的路径 const originalRequire = require; require = function (modulePath) { if (modulePath === 'graphql/index') { // 指向graphql包实际的入口文件 return originalRequire(path.join(cypressNodeModules, 'graphql', 'index.js')); } return originalRequire(modulePath); }; // 原脚本内容... let version = `11.0.1`; let src = `${appdata}/Cypress/Cache/${version}/Cypress/resources/app/node_modules/@packages/data-context/src`; const DataContext = require(`${src}/DataContext.js`).DataContext; const ProjectConfigManager = require(`${src}/data/ProjectConfigManager.js`).ProjectConfigManager; // ...原脚本剩余部分
原理是通过覆盖require函数,当Cypress内部代码尝试加载graphql/index时,自动重定向到实际存在的graphql/index.js文件,无需修改Cypress安装文件。
方案二:使用Cypress官方命令行工具(推荐)
无需依赖内部API,直接用Cypress提供的命令行命令解析并输出配置,稳定性和版本兼容性更好:
方法1:使用cypress config命令
指定配置文件路径,直接打印解析后的完整配置:
cypress config --file C:\work\sample\sample.config.ts --project C:\work\sample
若需要JSON格式输出,可添加--json参数:
cypress config --file C:\work\sample\sample.config.ts --project C:\work\sample --json
方法2:调用Cypress公开API加载配置
编写简单的Node.js脚本,使用Cypress官方公开的loadConfigAPI加载配置:
const { loadConfig } = require('cypress'); (async () => { const config = await loadConfig({ projectRoot: 'C:\\work\\sample', configFile: 'C:\\work\\sample\\sample.config.ts', testingType: 'e2e' }); console.log(JSON.stringify(config)); })();
该方法依赖官方公开API,比调用内部模块更可靠,适配后续Cypress版本的概率更高。
内容的提问来源于stack exchange,提问作者Mikhail Bolotov
相关产品推荐
相关产品推荐

