使用Cypress before()钩子后仍无法执行第二个it块的问题
解决Cypress中登录后测试用例间会话丢失的问题
我在Cypress中使用before钩子完成站点登录后初始化测试用例,问题在于执行完before钩子和第一个it块后,页面变为空白默认页,第二个it块无法执行。我曾在describe内先编写before钩子再写两个it块,也尝试在describe外初始化before钩子,但均无效。我需要实现登录一次后执行所有测试用例,代码如下:
describe('VerifyLoginFunctionality',() => { const dashbord = new Dashboard() const loginpage = new LoginPage() const createtask = new Createtask() before (() => { cy.viewport(1280,800) // mackbook cy.fixture('example').then(function(data) { // use "This" keyword to access globaly for example.json file this.data1=data cy.wait(2000) // cy.visit("https://app-redesign.taskbuddy.se") cy.visit(Cypress.env('login_url')) //Verify the title of the page cy.title().should('eq',this.data1.Pagetitle) loginpage.SigninMannuallyButton().click() loginpage.TeamSpace().type(this.data1.TeamspaceName) loginpage.NextButton().click() loginpage.Email().type(this.data1.email) loginpage.Password().type(this.data1.Password) loginpage.SigninButton().click() cy.wait(3000) }) }) it('Verify the user profile',() => { dashbord.UserProfileButton().click() cy.wait(2000) dashbord.UserProfilePopupMiddleLayer().should('be.visible') dashbord.Firstname() .invoke('val') // for input or textarea, .invoke('val') .then(text => { const someText = text; cy.log("aaa> "+someText) // BDD style expect(someText).to.equal("Toyota") //TDD style assert.equal(someText,"Toyota") }) cy.wait(3000) dashbord.Givenname().clear() dashbord.Givenname().type("jjjjjjj") dashbord.Firstname().should('have.value',"jjjjjjj") cy.wait(1500) dashbord.CloseIconOnProfile().click() }) it('Verify the create task',() => { // const dashbord = new Dashbord() createtask.CreateNewTaskButton().click() })
问题原因
Cypress默认会在每个it测试块之间重置浏览器状态,包括清除cookies和localStorage,导致登录会话丢失,因此第二个测试执行时会回到未登录的空白页状态。
解决方案
方案1:使用cy.session()(推荐,Cypress 12+)
cy.session()是Cypress官方推荐的会话持久化方案,它会缓存登录状态,仅在会话失效时重新执行登录逻辑。修改代码如下:
describe('VerifyLoginFunctionality', () => { const dashboard = new Dashboard() const loginpage = new LoginPage() const createtask = new Createtask() let data1; // 先加载测试数据 before(() => { cy.fixture('example').then(data => { data1 = data; }); }); // 用cy.session封装登录逻辑,确保会话复用 beforeEach(() => { cy.session('user-login', () => { cy.viewport(1280, 800); cy.visit(Cypress.env('login_url')); cy.title().should('eq', data1.Pagetitle); loginpage.SigninMannuallyButton().click(); loginpage.TeamSpace().type(data1.TeamspaceName); loginpage.NextButton().click(); loginpage.Email().type(data1.email); loginpage.Password().type(data1.Password); loginpage.SigninButton().click(); cy.wait(3000); // 验证登录成功,确保会话有效 dashboard.UserProfileButton().should('be.visible'); }); // 每次测试前跳转到仪表盘页面,保证测试环境一致 cy.visit(Cypress.env('dashboard_url')); // 替换为实际的仪表盘URL }); it('Verify the user profile', () => { dashboard.UserProfileButton().click(); cy.wait(2000); dashboard.UserProfilePopupMiddleLayer().should('be.visible'); dashboard.Firstname() .invoke('val') .then(text => { cy.log("aaa> " + text); expect(text).to.equal("Toyota"); assert.equal(text, "Toyota"); }); cy.wait(3000); dashboard.Givenname().clear(); dashboard.Givenname().type("jjjjjjj"); dashboard.Firstname().should('have.value', "jjjjjjj"); cy.wait(1500); dashboard.CloseIconOnProfile().click(); }); it('Verify the create task', () => { createtask.CreateNewTaskButton().click(); }); });
方案2:使用Cypress.Cookies.preserveOnce()(兼容旧版本)
如果使用Cypress 12以下版本,可以通过保留会话cookie来维持登录状态:
在登录完成后添加以下代码,替换为实际的会话cookie名称(可通过浏览器开发者工具的Application面板查看):
loginpage.SigninButton().click() cy.wait(3000) // 保留会话cookie,多个cookie可传入数组 Cypress.Cookies.preserveOnce('session_id')
注意事项
- 确保测试用例中没有执行注销、清除缓存等会破坏会话的操作
- 使用
cy.session()时,需添加登录成功的验证步骤,确保会话有效 - 若页面路由有变化,每次测试前需跳转到统一的起始页面
内容的提问来源于stack exchange,提问作者Milinda Kariyawasam
相关产品推荐
相关产品推荐

