Protractor页面对象继承

19

假设我正在使用页面对象模式来构建我的angularjs protractor e2e测试套件。

我会尽可能地将页面对象代码分开放在不同的文件中。

  1. 实现页面对象继承有哪些好的方法?经典的javascript继承?基于Object.create()的继承?其他?

  2. 应该将期望值保留在页面对象中吗?还是更喜欢Martin Fowler optinion通过将它们移动到一个断言库?在这种情况下,这个JavaScript-Node.js技术栈会是什么样子?

我已经准备了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'

2
这些人为什么那么容易就会给一个问题踩票呢?? 这是一个完美的问题,发布者已经做好了一切来帮助解决。我的评价是+1。 - Beyers
2
Leo,对这个主题很感兴趣。谢谢你的发帖。我也很乐意看到你在这里的见解 - 你对我提出的想法有什么看法?谢谢。 - alecxe
2个回答

8

这里是我为了培训同事如何创建良好的Protractor测试套件而设置的教程链接。

它是所有实时的,您可以访问演示站点并进行探索等操作。

https://github.com/Droogans/ProtractorPageObjects

这将为您提供安装、概述、组织技巧等内容。

如果您有任何问题,请随时留下评论。


2
哇,你写的教程非常好!谢谢!不过,我不喜欢将星盘添加到堆栈中的想法,我的直觉告诉我可以在没有它的情况下完成这个。 - Leo Gallucci

5

我的观点以及我们如何构建测试...

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

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

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

  • 对于常见且可重复使用的断言,我们有使用各种页面模型和 UI 模型交互方法的断言模型。它们按页面或 UI 组织。对于不常见且不可重复使用的断言,我们将其放入规范本身。

  • 规范通常按页面组织,尽管我们确实针对某些 UI/小部件拥有规范。


2
嘿 @wlingke,感谢分享你的标准,请提供一些代码吗?那太棒了 ;) - Leo Gallucci
1
@elgalu,我认为我没有可以分享的代码片段。不过,我认为 Protractor 的示例非常好,所以我建议在这些示例的基础上进行构建。https://github.com/angular/protractor/tree/master/spec - wlingke
2
这些示例是针对非常基本的Angular网站的,但无论如何还是谢谢。 - Leo Gallucci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接