量角器页面对象继承

Posted

技术标签:

【中文标题】量角器页面对象继承【英文标题】:Protractor Page Objects Inheritance 【发布时间】:2014-02-23 08:19:43 【问题描述】:

鉴于我正在利用页面对象模式构建我的 angularjs 量角器 e2e 测试套件。

并且我尽可能合理地将页面对象代码分开在不同的文件中。

    什么是启用页面对象继承的好方法? javascript经典继承?基于 Object.create() 的继承?其他?

    我应该在页面对象中保留期望吗?还是支持 Martin Fowler optinion by moving them to an assertion library?在这种情况下,在这个 javascript-nodejs 技术堆栈中究竟会是什么样子?

我准备了一个live jsfiddle playground here,以便您尝试改进。

或者只是在答案中粘贴代码,为了清楚起见,我将在下面粘贴 jsfiddle 内容:

loginPage.js

"use strict";

// A Page Object is a Singleton, so no need to constructors or classic js inheritance,
// please tell me if I'm wrong or what's the utility of creating a (new LoginPage())
// every time a spec need to use this login page.
var loginPage = 
    // Page Object Elements
    userElm: $('.user.loginPage'),

    // Page Object Assertions
    // Martin Fowler [doesn't favor](http://martinfowler.com/bliki/PageObject.html)
    // assertions in page objects, I'm open to suggestions on how to move 
    // the assertions away from the Page Object and see how an assertion library 
    // could like like in protractor.
    assertInputsDisplayed: function() 
        return ('Assertion: this.userElm: '+this.userElm);
    ,

    // Page Object Actions
    get: function () 
        return ('navigating to LoginPage with userElm: '+this.userElm);
    
;

module.exports.loginPage = loginPage;

loginDialog.js

"use strict";

var loginPage = require('./loginPage.js').loginPage;
var helpers = require('./helpers.js');

// Inherit properties from another Page Object
var loginDialog = helpers.extend(, Object.create(loginPage), 
    // Page Object Elements
    userElm: $('.user.loginDialog'),

    // Page Object Actions
    get: function () 
        return ('navigating to LoginDialog with userElm: '+this.userElm);
    ,

    logout: function () 
        return ('logging out of Dialog. user was: '+this.userElm);
    
);

module.exports.loginDialog = loginDialog;

helpers.js

"use strict";

// some helper to avoid adding an external dependency for now
var extend = function(target) 
    var sources = [].slice.call(arguments, 1);
    sources.forEach(function (source) 
        for (var prop in source) 
            target[prop] = source[prop];
        
    );
    return target;
;

usage.js

"use strict";

// Mock $() for easy unit testing this on nodejs REPL
global.$ = function(args)  return ('$BUILT '+args); ;

var loginPage   = require('./loginPage.js').loginPage;
var loginDialog = require('./loginDialog.js').loginDialog;

console.log(loginPage.userElm);    //=> '$BUILT .user.loginPage'
console.log(loginDialog.userElm);  //=> '$BUILT .user.loginDialog'
console.log(loginPage.get());      //=> 'navigating to LoginPage with userElm: $BUILT .user.loginPage'
console.log(loginDialog.get());    //=> 'navigating to LoginPage with userElm: $BUILT .user.loginDialog'
console.log(loginPage.assertInputsDisplayed());   //=> 'LoginPage assertion: this.userElm: $BUILT .user.loginPage'
console.log(loginDialog.assertInputsDisplayed()); //=> 'LoginPage assertion: this.userElm: $BUILT .user.loginDialog'

//loginPage.logout();   //=> TypeError: Object #<Object> has no method 'logout'
console.log(loginDialog.logout()); //=> 'logging out of Dialog. user was: $BUILT .user.loginDialog'

【问题讨论】:

这些人是怎么回事,如此轻易地否决了一个问题?这是一个完美的问题,海报设置了一切以提供帮助。来自我的 +1。 Leo,发现这个话题很有趣。感谢您发布。我也很高兴看到您的见解here - 您对我提出的想法有何看法?谢谢。 【参考方案1】:

这是我为培训我的一些同事创建好的量角器测试套件而设置的教程的链接。

一切都是实时的,您可以访问、探索等演示站点。

https://github.com/Droogans/ProtractorPageObjects

这将为您设置安装、大纲、组织技术等。

如果您有任何问题,请随时提出问题。

【讨论】:

哇,你写的教程真棒!谢谢!!但是我不喜欢将星盘添加到堆栈中的想法,我觉得没有它也可以完成【参考方案2】:

我的意见以及我们如何构建测试...

一种通用页面模型,其中包含一些我们希望大多数页面使用的方法,例如 go(),或者我们有与一些常见自定义元素交互的方法。

许多特定于页面的模型继承自该通用页面。这些模型上的大多数方法都与获取页面上的各种元素或与该页面的 ui 交互有关。这些模型上没有断言方法。

用于与某些更复杂的小部件交互的 UI 模型。类似于页面模型,但它们不绑定到页面。它们与 UI/小部件相关联。这些模型上没有断言方法。

对于通用和可重用的断言,我们有利用各种页面模型和 UI 模型交互方法的断言模型。它们按页面或 UI 组织。对于不常见且不能真正重用的断言,我们只是将它们放入规范本身。

虽然我们确实有某些 UI/小部件的规范,但规范通常按页面组织。

【讨论】:

嘿@wlingke 感谢您分享您的标准,您能提供一些代码吗?那太棒了;) @elgalu,我认为我真的没有可以分享的代码。但是,我认为量角器示例非常好,因此我建议以这些示例为基础。 github.com/angular/protractor/tree/master/spec 这些示例适用于一个非常基本的 Angular 网站,但无论如何感谢

以上是关于量角器页面对象继承的主要内容,如果未能解决你的问题,请参考以下文章

量角器+黄瓜等待和超时而不执行完整测试

量角器:单击按钮后如何等待页面完成?

执行量角器测试时“失败:等待量角器与页面同步时出错”

错误超时等待量角器在 11 秒后与页面同步

使用量角器在页面加载期间阻止第三方URL

量角器JS chai - 我如何使用getText()断言数组中的元素文本包含字符串?