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

如何在Cypress自定义命令间共享Base64编码的会话Cookie值?

解决Cypress自定义命令间共享Cookie值的问题

你的问题核心在于**getSession中生成的cookie是局部变量,且Cypress命令是异步执行的**,导致createThing无法直接获取到这个值。下面提供两种简洁可靠的解决方案:

方案1:通过命令链式传递Cookie值

这是最直接的方式,让getSession返回处理后的Cookie,再在测试用例中把它传递给createThing。

步骤1:修改getSession命令,返回Base64编码后的Cookie

去掉不必要的文件读写操作,直接用Cypress.Buffer完成Base64编码并返回结果:

Cypress.Commands.add('getSession', (email, password) => { 
  return cy.request({ 
    url: 'xxx', 
    method: 'POST', 
    body: { email, password } 
  }) 
  .then((response) => { 
    expect(response.status).to.eq(200); 
    const body = response.body;
    cy.log('Id - ' + body.customerId); 
    // 补全你的完整Cookie字符串
    const rawSession = `SESSIONID=${body.Cookies.SESSIONID};`; 
    cy.log('raw session data - ' + rawSession);
    // 直接返回Base64编码后的字符串
    return Cypress.Buffer.from(rawSession, 'utf8').toString('base64');
  });
});

步骤2:修改createThing命令,接受Cookie参数

让命令支持传入Cookie值:

Cypress.Commands.add('createThing', (name, cookie) => { 
  return cy.request({ 
    url: 'xxx', 
    method: 'POST', 
    headers: { 
      'Cookie' : `client_token=${cookie}`, 
      'Content-Type' : 'application/json' 
    }, 
    body: { name } 
  }) 
  .then((response) => { 
    expect(response.status).to.eq(200); 
    cy.log(response.body); 
    return response.body; // 可选,方便后续测试用例使用返回结果
  }); 
});

步骤3:在测试用例中链式调用

利用Cypress的异步链式特性,确保getSession完成后再执行createThing:

/// <reference types="Cypress" /> 
describe('deletes a user thing', function() { 
  it('create a thing via the api', function() { 
    cy.getSession('xxxx', 'xxxxx')
      .then((encodedCookie) => {
        cy.createThing('thing', encodedCookie);
      });
  }) 
})

方案2:使用Cypress环境变量存储Cookie

如果希望createThing不需要显式接收参数,可以把Cookie存到Cypress的环境变量中,让命令直接读取。

步骤1:修改getSession命令,将Cookie存入环境变量

Cypress.Commands.add('getSession', (email, password) => { 
  return cy.request({ 
    url: 'xxx', 
    method: 'POST', 
    body: { email, password } 
  }) 
  .then((response) => { 
    expect(response.status).to.eq(200); 
    const body = response.body;
    cy.log('Id - ' + body.customerId); 
    const rawSession = `SESSIONID=${body.Cookies.SESSIONID};`; 
    const encodedCookie = Cypress.Buffer.from(rawSession, 'utf8').toString('base64');
    cy.log('base64 string - ' + encodedCookie);
    // 将Cookie存入Cypress环境变量
    Cypress.env('SESSION_COOKIE', encodedCookie);
    return encodedCookie;
  });
});

步骤2:修改createThing命令,读取环境变量

Cypress.Commands.add('createThing', (name) => { 
  const cookie = Cypress.env('SESSION_COOKIE');
  // 提前校验,避免无Cookie时执行请求
  if (!cookie) {
    throw new Error('请先调用getSession生成会话Cookie!');
  }
  return cy.request({ 
    url: 'xxx', 
    method: 'POST', 
    headers: { 
      'Cookie' : `client_token=${cookie}`, 
      'Content-Type' : 'application/json' 
    }, 
    body: { name } 
  }) 
  .then((response) => { 
    expect(response.status).to.eq(200); 
    cy.log(response.body); 
  }); 
});

步骤3:测试用例中调用(可使用钩子提前生成Cookie)

/// <reference types="Cypress" /> 
describe('deletes a user thing', function() { 
  // 在所有测试用例前生成一次会话
  before(() => {
    cy.getSession('xxxx', 'xxxxx');
  });
  
  it('create a thing via the api', function() { 
    cy.createThing('thing');
  }) 
})

为什么你的原代码会报错?

  1. 变量作用域问题:getSession中cy.readFile回调里的cookie是局部变量,外部的createThing根本访问不到。
  2. 异步执行顺序:Cypress命令是异步的,原测试用例中cy.getSession和cy.createThing是顺序触发,但createThing可能在getSession完成前就执行了,此时Cookie还未生成。
  3. 不必要的文件IO:通过读写文件来做Base64编码完全多余,直接用Cypress.Buffer就能完成,还能避免文件操作带来的性能问题和异步复杂度。

内容的提问来源于stack exchange,提问作者Jason

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:42:47