What's the correct Protractor's syntax for Page Objects?

后端 未结 2 643
自闭症患者
自闭症患者 2021-02-06 15:28

I\'ve come across different types of syntax for Protractor\'s Page Objects and I was wondering, what\'s their background and which way is suggested.

This is the official

2条回答
  •  面向向阳花
    2021-02-06 15:43

    I prefer to use ES6 class syntax (http://es6-features.org/#ClassDefinition). Here, i prepared some simple example how i work with page objects using ES6 classes and some helpful tricks.

    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('batman@gmail.com'); // all logic is hidden in Fragment object
    loginPage.login('superman@gmail.com')
    

提交回复
热议问题