Search code examples
javascriptpromiseinternpageobjects

Intern js :How to return PageObject of the page from the function which opens it ?


I'm working on a UI automation project using Intern js . And I'm implementing it using page object model . I have a simple scenario where user enters credentials in login page and is navigated to welcome page. In my script i have a 'doLogin()' function in LoginPage which is responsible for entering credentials and clicking submit button. Now the problem is i want doLogin() to return WelcomePage and i'm unable to figure out the way to do this.

Heres my code setUp:

LoginPage.js

             define([],
                   function () {

                     function LoginPage(remote) {
                     this.remote = remote;

                  }

                 LoginPage.prototype = {
                    constructor: LoginPage,
                  // Login Page related Methods

                   doLogin: function(username,password){
                    this
                    .findById(json.locators.username).
                    .type(username).end()
                    .findById(json.locators.password)
                    .type(username).end()
                    .findByXpath(json.locators.sumit).click().end()
                    .sleep(1000).then(function(){
                     return welcomePage// this is not working
                    })
                 }
             };

            return LoginPage;
        });

WelcomePage.js

             define([],
              function () {

                 function WelcomePage(remote) {
                    this.remote = remote;

                  }

               WelcomePage.prototype = {
                    constructor: WelcomePage,

                   doSomething: function(){
               //welcome page related method
                }
             };

        return WelcomePage;
    });

Now what i actually want to achive is to do something like:

loginpage.doLogin(usrname,password).doSomething();

can somebody help on this??


Solution

  • A more flexible way to implement page objects is to make them groups of helper functions (like Leadfoot's pollUntil) rather than Command-like objects.

    Using that model, your LoginPage object might look like:

    define([], function () {
        return {
            doLogin: function (username, password) {
                return function () {
                    return this.parent
                        .findById(json.locators.username).
                        .type(username).end()
                        .findById(json.locators.password)
                        .type(username).end()
                        .findByXpath(json.locators.sumit).click().end()
                        .sleep(1000).then(function(){
                            return welcomePage// this is not working
                        });
                }
            }
        };
    });
    

    WelcomePage might look like

    define([], function () {
        return {
            doSomething: function () {
                return function () {
                    return this.parent
                        // more stuff
                }
            }
        };
    });
    

    You can call this.parent in the returned function because when the helper function is called (as a Command then callback) it's context will be set to the Command that's calling it.

    You would use them like

    define([
        './WelcomePage',
        './LoginPage',
        // ...
    ], function (
        welcomePage,
        loginPage,
        // ...
    ) {
        // ...
    
        this.remote
            .get('some page')
            .then(loginPage.doLogin('username', 'password'))
            .then(welcomePage.doSomething())
            // other stuff
    
        // ...
    });