You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cypress集成speakeasy报错:'list'参数必须为Buffer数组

问题:Cypress中使用speakeasy生成TOTP验证码报错"list" argument must be an Array of Buffers

问题背景

在Cypress自动化测试中使用speakeasy库生成TOTP验证码,单独运行验证码生成脚本可正常生成验证码并完成登录,但将其导入到Cypress测试代码时,出现"list" argument must be an Array of Buffers错误。

验证码生成脚本(authcodegen.js)

const token = speakeasy.totp({
    secret: '(my secret key)',
    encoding: 'base32' 
});

getAuthCode = () => {
    return token; 
}

module.exports = { getAuthCode };

Cypress测试代码

const { getAuthCode } = require('../support/authcodegen')
describe('Test', () => {    
    const emailInput = '[id = "email"]' 
    const passInput = '[id = "password"]' 
    const loginBtn = '[type = "submit"]'  
    it('Login Test', () => {     
        cy.on('uncaught:exception', (err, runnable) => {return false})          
        cy.visit('My Website');      
        cy.get(emailInput).type('My email');     
        cy.get(passInput).type('My Password');     
        cy.get(loginBtn).click();      
        const authCode = getAuthCode();     
        cy.log(authCode); 
    })
})

错误堆栈信息

at Function.concat (webpack://automation/../../Library/Caches/Cypress/13.13.0/Cypress.app/Contents/Resources/app/node_modules/buffer/index.js:423)
    at new Hmac (webpack://automation/../../Library/Caches/Cypress/13.13.0/Cypress.app/Contents/Resources/app/node_modules/create-hmac/browser.js:27)
    at Object.createHmac (webpack://automation/../../Library/Caches/Cypress/13.13.0/Cypress.app/Contents/Resources/app/node_modules/create-hmac/browser.js:61)
    at Object.digest (webpack://automation/./node_modules/speakeasy/index.js:56)
    at Object.hotpGenerate (webpack://automation/./node_modules/speakeasy/index.js:95)
    at Object.totpGenerate (webpack://automation/./node_modules/speakeasy/index.js:293)
    at ./cypress/support/authcodegen.js (webpack://automation/./cypress/support/authcodegen.js:3:24)
    at __webpack_require__ (webpack://automation/webpack/bootstrap:19)
    at eval (webpack://automation/./cypress/e2e/cocoshome.cy.js:1:24)
    at eval (http://localhost:49752/__cypress/tests?p=cypress/e2e/cocoshome.cy.js:39694:3)
From previous event:
    at Promise.longStackTracesCaptureStackTrace [as _captureStackTrace] (http://localhost:49752/__cypress/runner/cypress_runner.js:3486:19)
    at Promise._then (http://localhost:49752/__cypress/runner/cypress_runner.js:1239:17)
    at Promise.then (http://localhost:49752/__cypress/runner/cypress_runner.js:11132:17)
    at runScriptsFromUrls (http://localhost:49752/__cypress/runner/cypress_runner.js:111340:136)
    at Object.runScripts (http://localhost:49752/__cypress/runner/cypress_runner.js:111381:12)
    at $Cypress.onSpecWindow (http://localhost:49752/__cypress/runner/cypress_runner.js:40896:67)

解决方案

1. 问题根源

Cypress测试代码运行在浏览器环境,而speakeasy库更适配Node.js环境。报错是因为webpack打包时对Node.js核心模块的模拟存在兼容性问题,导致buffer模块的concat方法接收参数不符合预期。

2. 修复方案

方法一:将验证码生成逻辑移到Cypress Node.js环境(推荐)

利用cy.task()在Node.js端运行验证码生成逻辑,规避浏览器环境的兼容性问题:

  • 在cypress.config.js中注册task:
const { defineConfig } = require("cypress");
const speakeasy = require('speakeasy');

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {
        generateAuthCode() {
          return speakeasy.totp({
            secret: '(my secret key)',
            encoding: 'base32' 
          });
        }
      });
    },
  },
});
  • 修改Cypress测试代码,通过cy.task()获取实时生成的验证码:
describe('Test', () => {    
    const emailInput = '[id = "email"]' 
    const passInput = '[id = "password"]' 
    const loginBtn = '[type = "submit"]'  
    it('Login Test', () => {     
        cy.on('uncaught:exception', (err, runnable) => {return false})          
        cy.visit('My Website');      
        cy.get(emailInput).type('My email');     
        cy.get(passInput).type('My Password');     
        cy.get(loginBtn).click();      
        cy.task('generateAuthCode').then(authCode => {
            cy.log(authCode);
            // 此处可继续使用authCode完成验证码输入操作
        });
    })
})

方法二:修复浏览器环境下的speakeasy兼容性

若必须在浏览器环境运行,需确保buffer模块正确加载:

  • 安装buffer包:
npm install buffer
  • 修改验证码生成脚本,显式引入并挂载buffer到全局:
const { Buffer } = require('buffer');
global.Buffer = Buffer;
const speakeasy = require('speakeasy');

function getAuthCode() {
    // 实时生成验证码,避免模块加载时生成导致过期
    return speakeasy.totp({
        secret: '(my secret key)',
        encoding: 'base32' 
    });
}

module.exports = { getAuthCode };

3. 额外优化点

  • 原代码在模块加载时就生成token,会导致验证码过期,改为调用getAuthCode时实时生成更合理。
  • 将全局函数getAuthCode改为声明式函数,避免作用域问题。

内容的提问来源于stack exchange,提问作者octavio González Censori

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:28:22