量角器元件处理

时间:2016-02-08 14:21:23

标签: protractor

我有一个关于量角器如何处理元素定位的问题。 我正在使用页面对象,就像我在Webdriver中一样。 与Webdriver的最大区别在于,仅在对该元素调用函数时才会定位元素。

使用页面对象时,建议在测试之前实例化对象。但后来我想知道,如果你实例化你的对象并且页面发生了变化,那么元素的状态会发生什么?

我将用一个例子来证明

  it('Change service', function() {
      servicePage.clickChangeService();
      serviceForm.selectService(1);
      serviceForm.save();

      expect(servicePage.getService()).toMatch('\bNo service\b');
  });

调试servicePage.getService()时返回undefined。 这是因为serviceForm是另一个页面而且servicePage的状态已经改变了吗?

这是我的网页对象:

var servicePage = function() { 
  this.changeServiceLink = element(by.id('serviceLink')); 
  this.service = element(by.id('service'));

  this.clickChangeService = function() { 
    this.changeServiceLink.click(); 
  };

this.getService = function() { 
  return this.service.getAttribute('value'); 
}; 
}; 
module.exports = servicePage;

提前谢谢你。 此致

2 个答案:

答案 0 :(得分:2)

导航其他页面时,您选择的网络元素将清晰。所以你必须再次选择。您可以选择HTML页面中的所有元素。您可以单击您看到的内容。所以protactor + Selenium可以决定显示什么。

您的代码中有错误,请尝试以下操作:

 expect(servicePage.getService()).toMatch('\bNo service\b');

答案 1 :(得分:2)

基本上,element()是一个' elementFinder'除非你调用像getAttribute()这样的动作,否则它不会做任何工作。

因此,您可以将element(by.id('service'))视为占位符。

如果你想真正找到元素并做一些动作,那么你就像element(by.id('service')).getAttribute('value')一样组合它,但这本身并不是你要寻找的价值,它是一个承诺获得价值。您可以阅读有关如何在其他地方处理承诺的所有内容。

量角器特别做的另一件事是在应用动作时在waitForAngular()中进行修补,以便它在实际外出找到元素并应用动作之前等待任何未完成的http调用和超时。所以当你致电.getAttribute()时,它看起来真的像

return browser.waitForAngular().then(function() { 
    return element(by.id('service')).getAttribute('value');
 });

因此,在您的示例中,如果您的角度页面未正确设置或根据您使用的控件设置,您可能会尝试在页面使用元素中的新值确定之前获取值

要调试您的示例,您应该执行类似

的操作
it('Change service', function() {
    servicePage.getService().then(function(originalService) {
        console.log('originalService: ' + originalService);
    });

    servicePage.clickChangeService();
    serviceForm.selectService(1);
    serviceForm.save();

    servicePage.getService().then(function(newService) {
        console.log('newService: ' + newService);
    });

    expect(servicePage.getService()).toMatch('\bNo service\b');
});

我看到的另一件事是,当你只能使用一个对象时,你的pageObject似乎是一个构造函数:

// name this file servicePage.js, and use as 'var servicePage = require('./servicePage.js');'
module.exports = {
    changeServiceLink: element(by.id('serviceLink')), 
    service: element(by.id('service')),

    clickChangeService: function() { 
        this.changeServiceLink.click(); 
    },

    getService: function() { 
        return this.service.getAttribute('value'); 
    }  
};

否则你必须做module.exports = new servicePage();之类的事情或在你的测试文件中实例化它。