Canonical way to define page objects in Protractor

2019-02-16 09:14发布

We've been using the Page Object pattern for quite a while. It definitely helps to organize the end-to-end tests and makes tests more readable and clean.

As Using Page Objects to Organize Tests Protractor documentation page shows us, we are defining every page object as a function and use new to "instantiate" it:

"use strict";

var HeaderPage = function () {
    this.logo = element(by.css("div.navbar-header img"));
}

module.exports = HeaderPage;

Usage:

"use strict";

var HeaderPage = require("./../po/header.po.js");

describe("Header Look and Feel", function () {
    var header;

    beforeEach(function () {
        browser.get("/#login");
        header = new HeaderPage();
    });

    it("should show logo", function () {
        expect(header.logo.isDisplayed()).toBe(true);
    });

});

But, recently in the Protractor: Angular testing made easy Google Testing Blog post, I've noticed that a page object is defined as an object:

var angularHomepage = {
    nameInput : element(by.model('yourName')),
    greeting : element(by.binding('yourName')),
    get : function() {
        browser.get('index.html');
    },
    setName : function(name) {
        this.nameInput.sendKeys(name);
    }
};

What is the difference between these two ways to introduce Page Objects? Should I prefer one against the other?

2条回答
2楼-- · 2019-02-16 09:52

Ultimately, I think it is a question of personal preference.

Yes, you can use the constructor pattern and instantiate a singleton in each test suite... yes you could use a simple object literal as above... yes you could use a factory function...

Structuring code using inheritance via "classes" (whether pseudo- or ES2015 syntax) vs objects extended via mixins is a much wider debate within application development in general, never mind e2e tests!

The main thing is clear, consistent practice across your test suites and promoting code reusability wherever possible.

查看更多
Explosion°爆炸
3楼-- · 2019-02-16 09:56

Alecxe, I had this same question. The answer for me came down to the ability to extend constructor-based page objects. For things I don't need to extend (with a basePage, for example), I use an object literal.

This is just based on the things I've read and tried... I'd be happy to learn about a better/different pattern.

I look forward to reading the style guide, Andres.

查看更多
登录 后发表回答