Подтвердить что ты не робот

Наследование объектов страницы-экспонента

Учитывая, что я строю свой ангарный переводчик angularjs e2e, используя шаблон объектов страницы.

И я отдельно выделяю код объекта страницы в разных файлах.

  • Что было бы хорошим подходом к включению наследования объектов страницы? классическое наследование javascript? Наследование на основе Object.create()? Другое?

  • Должен ли я поддерживать ожидания в объекте страницы? Или одобрить Martin Fowler optinion, переместив их в библиотеку утверждений? в каком случае, как именно это выглядело бы в этом стеке технологий javascript-nodejs?

Я подготовил игровую площадку jsfiddle здесь, чтобы вы могли попробовать свои улучшения.

Или просто вставьте код в ответ, я буду вставлять содержимое 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 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'
4b9b3361

Ответ 1

Вот ссылка на учебное пособие, которое я создал для обучения некоторых моих коллег по созданию хороших тестовых наборов Protractor.

Все вживую, с демо-сайтом, который вы можете посетить, изучить и т.д.

https://github.com/Droogans/ProtractorPageObjects

Это установит вас с установкой, очертаниями, организационными методами и т.д.

Не стесняйтесь оставлять проблему, если у вас есть проблемы.

Ответ 2

Мое мнение и то, как мы структурируем наш тест...

  • Одна общая модель страницы, которая содержит некоторые методы, мы ожидаем, что большинство страниц будут использоваться как go() или у нас есть методы для взаимодействия с некоторыми общими настраиваемыми элементами.

  • Множество моделей, которые наследуются от этой общей страницы. Большинство методов на этих моделях связаны с получением различных элементов на странице или взаимодействием с этой страницей ui. На этих моделях нет методов утверждения.

  • Модели пользовательского интерфейса для взаимодействия с некоторыми более сложными виджетами. Подобно страницам, но они не привязаны к странице. Они привязаны к пользовательскому интерфейсу/виджетам. На этих моделях нет методов утверждения.

  • Для общих и многоразовых утверждений мы имеем модели утверждений, в которых используются методы взаимодействия различных моделей страниц и моделей пользовательских интерфейсов. Они организованы по страницам или пользовательскому интерфейсу. Для утверждений, которые являются необычными и не могут использоваться повторно, мы просто помещаем их в саму спецификацию.

  • Спецификации обычно организованы по страницам, хотя у нас есть спецификации для определенных пользовательских интерфейсов/виджета.