【问题标题】:Protractor element handling量角器元件处理
【发布时间】:2016-02-08 14:21:22
【问题描述】:

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

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

我用一个例子来演示

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

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

调试时 servicePage.getService() 返回未定义。 是不是因为 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;

提前谢谢你。 问候

【问题讨论】:

    标签: protractor


    【解决方案1】:

    基本上,element() 是一个“元素查找器”,除非您调用诸如 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(); 之类的操作或在您的测试文件中实例化它。

    【讨论】:

    • 这解决了问题,非常感谢您的明确指示。
    【解决方案2】:

    当您浏览另一个页面时,您选择的网络元素将一目了然。所以你必须再次选择。您可以选择 HTML 页面中的所有元素。你可以点击你看到的。所以 protactor + Selenium 可以决定显示什么。

    你的代码有错误,试试这个:

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

    【讨论】:

    • 好吧,我太傻了,我忘记带牙套了。但这并没有解决问题。现在我得到'Expected undefined to match ...',所以似乎存在初始化问题。我在原始帖子中添加了页面对象。
    猜你喜欢
    • 2014-07-01
    • 2017-01-16
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 2021-02-13
    • 2019-02-22
    • 1970-01-01
    相关资源
    最近更新 更多