如何在Cypress.io中通过SSH连接服务器并执行命令?
解决方案:Cypress中执行SSH命令并验证页面状态
问题原因分析
你遇到的fs.readFileSync is not a function错误,是因为Cypress的测试代码运行在浏览器上下文中,而Node.js的fs模块仅在Node环境可用,直接在测试命令中调用fs会导致报错。
可行实现方案
要实现「执行服务器命令前后检查页面状态」的测试,核心是把SSH操作放到Cypress的task中执行(task运行在Node环境,可直接调用Node模块),以下是两种具体实现方式:
方式一:基于simple-ssh实现
- 配置Cypress任务(cypress.config.js)
const { defineConfig } = require("cypress"); const SSH = require('simple-ssh'); const fs = require('fs'); module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { // 定义执行SSH命令的task on('task', { executeSSH(command) { return new Promise((resolve, reject) => { // 从配置中读取SSH基础信息,添加密钥(Node环境可正常使用fs) const sshConfig = { ...config.env.ssh, key: fs.readFileSync('path/to/key/file') }; const ssh = new SSH(sshConfig); ssh.exec(command, { out: (stdout) => resolve(stdout.trim()), err: (stderr) => reject(new Error(stderr)) }).start(); // 捕获SSH连接错误 ssh.on('error', (err) => reject(err)); }); } }); }, // 配置SSH基础信息(可通过环境变量覆盖) env: { ssh: { host: '你的服务器地址', user: '你的用户名', port: 22 // 默认SSH端口,可根据实际修改 } } } });
- 编写测试用例
describe('服务器命令与页面状态联动测试', () => { it('执行命令前后验证页面状态变化', () => { // 1. 访问目标页面,检查初始状态 cy.visit('/目标页面路径'); cy.get('.状态元素选择器').should('have.text', '初始状态值'); // 2. 调用task执行服务器命令 cy.task('executeSSH', '你的目标命令').then((commandOutput) => { console.log('命令执行结果:', commandOutput); // 可选:验证命令执行结果是否符合预期 }); // 3. 等待命令生效(根据业务调整,建议用智能等待替代固定时长) cy.wait(2000); // 4. 检查命令执行后的页面状态 cy.get('.状态元素选择器').should('have.text', '更新后的状态值'); }); });
方式二:基于ssh2实现(更灵活的底层库)
如果simple-ssh无法满足需求,推荐使用更主流的ssh2库:
- 配置Cypress任务(cypress.config.js)
const { defineConfig } = require("cypress"); const { Client } = require('ssh2'); const fs = require('fs'); module.exports = defineConfig({ e2e: { setupNodeEvents(on, config) { on('task', { executeSSH(command) { return new Promise((resolve, reject) => { const conn = new Client(); conn.on('ready', () => { conn.exec(command, (err, stream) => { if (err) return reject(err); let stdout = ''; let stderr = ''; stream.on('close', (code) => { conn.end(); if (code === 0) { resolve(stdout.trim()); } else { reject(new Error(`命令执行失败,退出码: ${code}, 错误信息: ${stderr}`)); } }) .on('data', (data) => stdout += data) .stderr.on('data', (data) => stderr += data); }); }) .on('error', (err) => reject(err)) .connect({ host: config.env.ssh.host, port: config.env.ssh.port || 22, username: config.env.ssh.user, privateKey: fs.readFileSync('path/to/key/file') }); }); } }); }, env: { ssh: { host: '你的服务器地址', user: '你的用户名' } } } });
- 测试用例写法和方式一完全一致,直接调用
cy.task('executeSSH', '命令')即可。
注意事项
- 确保SSH密钥文件路径正确(相对于cypress.config.js的位置),建议使用绝对路径或通过环境变量配置
- 避免在测试代码中硬配置敏感信息(如服务器地址、密钥),可通过Cypress环境变量或.env文件管理
- 命令执行后的等待逻辑,优先使用
cy.intercept等待接口请求完成,或cy.get等待元素变化,替代固定时长等待
内容的提问来源于stack exchange,提问作者Denyson Grellert
相关产品推荐
相关产品推荐

