Javascript 测试选项卡导航顺序

Javascript 测试选项卡导航顺序,javascript,testing,selenium,protractor,end-to-end,Javascript,Testing,Selenium,Protractor,End To End,在我们的一个测试中,我们需要确保表单中的选项卡键盘导航按正确的顺序执行 问题:使用量角器检查选项卡导航顺序的常规方法是什么 目前,我们通过对表单中存在的尽可能多的输入字段重复以下步骤来解决此问题(代码如下): 检查当前聚焦元素的ID(使用) 将选项卡键发送到当前关注的元素 以下是示例规范: it("should navigate with tab correctly", function () { var regCodePage = new RegCodePage(); b

在我们的一个测试中,我们需要确保表单中的选项卡键盘导航按正确的顺序执行

问题:使用量角器检查选项卡导航顺序的常规方法是什么


目前,我们通过对表单中存在的尽可能多的输入字段重复以下步骤来解决此问题(代码如下):

  • 检查当前聚焦元素的
    ID
    (使用)
  • 选项卡
    键发送到当前关注的元素
以下是示例规范:

it("should navigate with tab correctly", function () {
    var regCodePage = new RegCodePage();
    browser.wait(protractor.ExpectedConditions.visibilityOf(regCodePage.title), 10000);

    // registration code field has focus by default
    expect(regCodePage.registrationCode.getId()).toEqual(browser.driver.switchTo().activeElement().getId());

    // focus moved to Remember Registration Code
    regCodePage.registrationCode.sendKeys(protractor.Key.TAB);
    expect(regCodePage.rememberRegistrationCode.getId()).toEqual(browser.driver.switchTo().activeElement().getId());

    // focus moved to Request Code
    regCodePage.rememberRegistrationCode.sendKeys(protractor.Key.TAB);
    expect(regCodePage.requestCode.getId()).toEqual(browser.driver.switchTo().activeElement().getId());

    // focus moved to Cancel
    regCodePage.requestCode.sendKeys(protractor.Key.TAB);
    expect(regCodePage.cancelButton.getId()).toEqual(browser.driver.switchTo().activeElement().getId());

    // focus moved back to the input
    regCodePage.cancelButton.sendKeys(protractor.Key.TAB);
    expect(regCodePage.registrationCode.getId()).toEqual(browser.driver.switchTo().activeElement().getId());
});
其中,
regCodePage
是页面对象:

var RegCodePage = function () {
    this.title = element(by.css("div.modal-header b.login-modal-title"));
    this.registrationCode = element(by.id("regCode"));

    this.rememberRegistrationCode = element(by.id("rememberRegCode"));
    this.requestCode = element(by.id("forgotCode"));

    this.errorMessage = element(by.css("div.auth-reg-code-block div#message"));

    this.sendRegCode = element(by.id("sendRegCode"));
    this.cancelButton = element(by.id("cancelButton"));
    this.closeButton = element(by.css("div.modal-header button.close"));
};

module.exports = RegCodePage;
它是有效的,但它不是真正明确和可读的,这使得它很难维护。此外,当前方法中的另一个“气味”是代码复制


如果当前的方法是您也可以这样做的话,我将非常感谢您对如何使其可重用的任何见解。

我认为PageObject应该定义一个选项卡顺序列表,因为这实际上是页面的一个直接属性,并且应该可以表示为简单的数据。项目数组似乎是一个足够的表示形式,因此类似于:

this.tabOrder = [ this.registrationCode, this.rememberRegistrationCode, this.requestCode, this.cancelButton ];
it('has correct tab order', function() {
    var regCodePage = new RegCodePage();  // this should probably be in the beforeEach
    testTabOrder(regCodePage.tabOrder);
});
然后,您需要一些可以检查选项卡顺序的通用代码

function testTabOrder(tabOrder) {
    // Assumes TAB order hasn't been messed with and page is on default element
    tabOrder.forEach(function(el) {
       expect(el.getId()).toEqual(browser.driver.switchTo().activeElement().getId());
       el.sendKeys(protractor.Key.TAB);
    });
}
那么您的测试将类似于:

this.tabOrder = [ this.registrationCode, this.rememberRegistrationCode, this.requestCode, this.cancelButton ];
it('has correct tab order', function() {
    var regCodePage = new RegCodePage();  // this should probably be in the beforeEach
    testTabOrder(regCodePage.tabOrder);
});
当然,这假设每个元素都有一个有效的“getId()”方法。(对我来说,这似乎是一个合理的假设,但某些环境可能不支持这一假设。)

我认为这样可以很好地将选项卡顺序隔离在PageObject上(因此很容易与页面内容保持同步,并且不会在验证顺序的代码中丢失)。测试代码似乎是“乐观的”(我怀疑现实世界会引入足够多的问题,最终会稍微扩展此代码)

我还没有尝试过这些方法,所以如果不起作用,请随意否决


此外,我相信
forEach
循环将按原样工作,但如果它需要一些更明确的承诺处理来明确依赖关系,我也不会感到惊讶。

更干净,而且肯定是可重用的,谢谢!我仍然需要在实践中尝试这一点——如果答案不能正常工作,我会编辑它。但是,再一次,看起来很棒!工作很好。我已经将testTabOrder添加到我的助手测试库中,它在测试中看起来非常干净。本周我们还要感谢您:)随着从
2.1.0
(从
1.7.0
升级)起对量角器的一些更改,显然必须使用
browser.driver.switch().activeElement()。然后(…)
,即
activeElement
调用现在是基于承诺的。