2016-08-03 14 views
4

Ich habe verschiedene Arten von Syntax für die Seitenobjekte von Protractor gefunden und ich frage mich, was ist ihr Hintergrund und welche Art wird vorgeschlagen.Wie lautet die korrekte Winkelmessersyntax für Seitenobjekte?

Dies ist die offizielle PageObject-Syntax aus dem Tutorial von Protractor. Ich mag es am meisten, weil es klar und lesbar:

use strict; 

var AngularHomepage = function() { 
    var nameInput = element(by.model('yourName')); 
    var greeting = element(by.binding('yourName')); 

    this.get = function() { 
    browser.get('http://www.angularjs.org'); 
    }; 

    this.setName = function(name) { 
    nameInput.sendKeys(name); 
    }; 

    this.getGreeting = function() { 
    return greeting.getText(); 
    }; 
}; 
module.exports = AngularHomepage; 

Allerdings habe ich auch festgestellt, diese Art:

'use strict'; 

var AngularPage = function() { 
    browser.get('http://www.angularjs.org'); 
}; 

    AngularPage.prototype = Object.create({}, { 
     todoText: { get: function()  { return element(by.model('todoText'));    }}, 
     addButton: { get: function()  { return element(by.css('[value="add"]'));   }}, 
     yourName: { get: function()  { return element(by.model('yourName'));    }}, 
     greeting: { get: function()  { return element(by.binding('yourName')).getText(); }}, 
     todoList: { get: function()  { return element.all(by.repeater('todo in todos')); }}, 
     typeName: { value: function (keys) { return this.yourName.sendKeys(keys);    }} , 
     todoAt: { value: function (idx) { return this.todoList.get(idx).getText();   }}, 
     addTodo: { value: function (todo) { 
     this.todoText.sendKeys(todo); 
     this.addButton.click(); 
     }} 
    }); 

    module.exports = AngularPage; 

Was sind die Vor/Nachteile der beiden Ansätze (abgesehen von Lesbarkeit) Ist der zweite aktuell? Ich habe gesehen, dass WebdriverIO dieses Format verwendet.

Ich habe auch von einem Mann auf Gitter gehört, dass der erste Eintrag ineffizient ist. Kann mir jemand erklären warum?

Antwort

5

Seite Object Model Rahmen wegen beliebt vor allem wird:

  1. Weniger Code duplizieren
  2. Einfach für lange
  3. Hohe Lesbarkeit

So wir, in der Regel zu halten Entwickeln Sie Test Framework (POM) für unsere Bequemlichkeit basierend auf Testumfang und Bedürfnisse von Follo Flügel geeignete Rahmen (Pom) Muster. Es gibt KEINE solchen Regeln, die besagen, dass wir strikt jedem Rahmen folgen sollten.

HINWEIS: orientiert und effektiv

In Ihrem Fall sieht 1. eine gute und einfache Framework ist unsere Aufgabe einfach zu machen, führen. Und es führt nicht zu Verwirrung oder Konflikt während der Wartungsphase davon.

Beispiel: 1. Fall -> Element Locator Erklärung auf jeder Seite oben passiert. Es wäre leicht zu ändern, falls sich ein Element-Locator in Zukunft ändern sollte.

Während in 2. Fall, Locators deklariert in Blockebene (über die Seite streuen). Es wäre ein zeitaufwendiger Prozess, um die Lokalisierer zu identifizieren und zu ändern, falls dies in Zukunft erforderlich sein sollte.

Also, wählen Sie, welche Sie sich wohl fühlen basierend auf den oben genannten Punkten.

+0

Vielen Dank, das tut Sinn macht :) – anks

+0

@anks, wenn Sie das Gefühl, meine Post helfen Ihnen und richtig, es bitte als richtig ticken. –

3

Ich bevorzuge ES6 Klassensyntax (http://es6-features.org/#ClassDefinition). Hier habe ich ein einfaches Beispiel für die Arbeit mit Seitenobjekten mit ES6-Klassen und einigen hilfreichen Tricks vorbereitet.

var Page = require('../Page') 
var Fragment = require('../Fragment') 

class LoginPage extends Page { 
    constructor() { 
     super('/login'); 
     this.emailField = $('input.email'); 
     this.passwordField = $('input.password'); 
     this.submitButton = $('button.login'); 

     this.restorePasswordButton = $('button.restore'); 
    } 

    login(username, password) { 
     this.email.sendKeys(username); 
     this.passwordField.sendKeys(password); 
     this.submit.click(); 
    } 

    restorePassword(email) { 
     this.restorePasswordButton.click(); 
     new RestorePasswordModalWindow().submitEmail(email); 
    } 
} 

class RestorePasswordModalWindow extends Fragment { 
    constructor() { 
     //Passing element that will be used as this.fragment; 
     super($('div.modal')); 
    } 

    submitEmail(email) { 
     //This how you can use methods from super class, just example - it is not perfect. 
     this.waitUntilAppear(2000, 'Popup should appear before manipulating'); 
     //I love to use fragments, because they provides small and reusable parts of page. 
     this.fragment.$('input.email').sendKeys(email); 
     this.fragment.$('button.submit')click(); 
     this.waitUntilDisappear(2000, 'Popup should disappear before manipulating'); 
    } 
} 
module.exports = LoginPage; 

// Page.js 
class Page { 
    constructor(url){ 
     //this will be part of page to add to base URL. 
     this.url = url; 
    } 

    open() { 
     //getting baseURL from params object in config. 
     browser.get(browser.params.baseURL + this.url); 
     return this; // this will allow chaining methods. 
    } 
} 
module.exports = Page; 

// Fragment.js 
class Fragment { 
    constructor(fragment) { 
     this.fragment = fragment; 
    } 

    //Example of some general methods for all fragments. Notice that default method parameters will work only in node.js 6.x 
    waitUntilAppear(timeout=5000, message) { 
     browser.wait(this.EC.visibilityOf(this.fragment), timeout, message); 
    } 

    waitUntilDisappear(timeout=5000, message) { 
     browser.wait(this.EC.invisibilityOf(this.fragment), timeout, message); 
    } 
} 
module.exports = Fragment; 

// Then in your test: 
let loginPage = new LoginPage().open(); //chaining in action - getting LoginPage instance in return. 
loginPage.restorePassword('[email protected]'); // all logic is hidden in Fragment object 
loginPage.login('[email protected]') 
+0

Nachdem ich dies gepostet habe, riet mir mein Freund, ES6 zu benutzen und ich stimme zu, dass es mir sehr nett und vertrauter erscheint (ich habe schon vorher Seitenobjekte in Ruby geschrieben). Eine Frage allerdings - Sie verwenden die Winkelmesser-Syntax nicht für Elemente (wie 'element (by.css ('someclass') ') - liegt das daran, dass $ ('') kürzer ist oder aus anderen Gründen? – anks

+0

Ja, ich benutze Element (by.css ('')) eine Menge, und $/$$ ist nette globale Abkürzung dafür. Kein funktioneller Unterschied. – Xotabu4

Verwandte Themen