E2E测试:如何验证注册流程触发发送确认邮件?
你的场景回顾
我有一个注册表单,需要传入
password、confirmPass以及勾选tc复选框。用户提交后会弹出对话框,同时发送注册确认邮件,功能正常。我写了Protractor E2E测试代码,运行无报错,但测试完成后没收到确认邮件,无法证明测试成功。想问:
- 能否让测试触发发送确认邮件?
- 代码是否存在逻辑错误?
- 是否与未测试提交后弹出的对话框有关?
补充:若用户信息缺失或tc复选框未勾选,提交按钮会禁用。
核心问题:你的测试代码存在逻辑错误!
这段复选框处理的代码是关键坑点:
element( by.tagName('mat-checkbox') ).isSelected().then(function(selected) { if (selected) { element( by.name('mat-checkbox') ).click(); // 这里把已经勾选的复选框取消了! expect( page.getInputFields().userAccept.isSelected() ).toBe(true); page.getInputFields().submitButton.click(); } });
你在代码开头已经点击了mat-checkbox,此时复选框处于选中状态,进入if(selected)分支后,又调用了一次click()——直接把复选框给取消了!
结合你补充的业务规则:tc未勾选时提交按钮是禁用的,这时候点击禁用的按钮根本不会触发任何提交操作,自然不会触发邮件发送逻辑。
另外,你一会儿用by.tagName定位复选框,一会儿又用by.name,还混用了page.getInputFields().userAccept,定位器不统一很容易出问题,建议全程用page对象里的userAccept来定位复选框。
如何让测试真正触发邮件发送?
要触发邮件,得先确保测试正确完成了表单提交,分三步调整:
1. 修复复选框逻辑,确保提交按钮可用
去掉分支里多余的click(),直接验证复选框状态后提交:
// 开头已经通过page对象点击了复选框,这里直接验证状态 expect(page.getInputFields().userAccept.isSelected()).toBe(true); // 先确认提交按钮是可用的(符合你的业务规则) expect(page.getInputFields().submitButton.isEnabled()).toBe(true); // 再点击提交 page.getInputFields().submitButton.click();
2. 处理提交后的对话框
提交后弹出的对话框必须处理,否则页面会停留在对话框状态,后续的请求(比如邮件发送)可能无法完成。你需要等待对话框出现并确认:
// 等待对话框的确认按钮出现 const dialogConfirmBtn = element(by.css('.mat-dialog-actions button')); browser.wait(protractor.ExpectedConditions.visibilityOf(dialogConfirmBtn), 5000, "注册成功对话框未出现"); // 点击确认关闭对话框 dialogConfirmBtn.click(); // 可选:等待页面跳转到注册成功页,确保流程完成 browser.wait(protractor.ExpectedConditions.urlContains('registration-success'), 5000, "注册成功页面未加载");
3. 确认测试环境的邮件配置
有时候测试环境不会真的发送邮件到你的个人邮箱,而是用工具捕获邮件(比如Mailhog)或者把邮件日志存到后端。你可以:
- 查看测试环境的后端日志,确认邮件发送接口是否被调用
- 如果用了邮件捕获工具,去工具界面查看是否收到测试邮件
和未测试对话框有关吗?
有关系,但不是直接原因。未测试对话框可能导致页面流程卡住,但核心问题还是你的代码逻辑错误导致根本没触发提交。不过对话框是注册流程的一部分,必须加入测试,否则无法确保整个流程的完整性。
优化后的完整测试代码参考
it("Should register the user and send confirmation email", () => { const inputFields = page.getInputFields(); // 填写表单 inputFields.userEmailInput.sendKeys("myFirstName.myLastName@domain-xxx.com"); inputFields.userPassInput.sendKeys('!Q2w3e4r'); inputFields.userConfirmPass.sendKeys('!Q2w3e4r'); inputFields.userAccept.click(); // 统一用page对象的定位器 // 验证表单填写正确 expect(inputFields.userEmailInput.getAttribute("value")).toEqual("myFirstName.myLastName@domain-xxx.com"); expect(inputFields.userPassInput.getAttribute("value")).toEqual('!Q2w3e4r'); expect(inputFields.userConfirmPass.getAttribute('value')).toEqual('!Q2w3e4r'); expect(inputFields.userAccept.isSelected()).toBe(true); // 验证提交按钮可用(符合业务规则) expect(inputFields.submitButton.isEnabled()).toBe(true); // 提交表单 inputFields.submitButton.click(); // 处理提交后的对话框 const dialogConfirmBtn = element(by.css('.mat-dialog-actions button')); browser.wait(protractor.ExpectedConditions.visibilityOf(dialogConfirmBtn), 5000, "注册成功对话框超时未出现"); dialogConfirmBtn.click(); // 验证注册流程完成(比如跳转成功页) browser.wait(protractor.ExpectedConditions.urlContains('registration-success'), 5000, "注册成功页面超时未加载"); });
内容的提问来源于stack exchange,提问作者k.vincent

