Multiple browsers and the Page Object pattern

后端 未结 2 649
别那么骄傲
别那么骄傲 2020-12-31 07:31

We are using the Page Object pattern to organize our internal AngularJS application tests.

Here is an example page object we have:

var Logi         


        
2条回答
  •  生来不讨喜
    2020-12-31 08:27

    Look at my solution. I simplified example, but we are using this approach in current project. My app has pages for both user permissions types, and i need to do some complex actions same time in both browsers. I hope this might show you some new, better way!

    "use strict";
    
    //In config, you should declare global browser roles. I only have 2 roles - so i make 2 global instances
    //Somewhere in onPrepare() function
    global.admin = browser;
    admin.admin = true;
    
    global.guest = browser.forkNewDriverInstance();
    guest.guest = true;
    
    //Notice that default browser will be 'admin' example:
    // let someElement = $('someElement'); // this will be tried to be found in admin browser.
    
    
    
    class BasePage {
        //Other shared logic also can be added here.
        constructor (browser = admin) {
            //Simplified example
            this._browser = browser
        }
    }
    
    class HomePage extends BasePage {
        //You will not directly create this object. Instead you should use .getPageFor(browser)
        constructor(browser) {
            super(browser);
    
            this.rightToolbar = ToolbarFragment.getFragmentFor(this._browser);
            this.chat = ChatFragment.getFragmentFor(this._browser);
            this.someOtherNiceButton = this._browser.$('button.menu');
        }
    
        //This function relies on params that we have patched for browser instances in onPrepare();
        static getPageFor(browser) {
            if (browser.guest) return new GuestHomePage(browser);
            else if (browser.admin) return new AdminHomePage(browser);
        }
    
        openProfileMenu() {
            let menu = ProfileMenuFragment.getFragmentFor(this._browser);
            this.someOtherNiceButton.click();
    
            return menu;
        }
    }
    
    
    class GuestHomePage extends RoomPage {
        constructor(browser) {
            super(browser);
        }
    
        //Some feature that is only available for guest
        login() {
            // will be 'guest' browser in this case.
            this._browser.$('input.login').sendKeys('sdkfj'); //blabla
            this._browser.$('input.pass').sendKeys('2345'); //blabla
            this._browser.$('button.login').click();
        }
    }
    
    
    class AdminHomePage extends RoomPage {
        constructor(browser) {
            super(browser);
        }
    
        acceptGuest() {
            let acceptGuestButton = this._browser.$('.request-admission .control-btn.admit-user');
            this._browser.wait(EC.elementToBeClickable(acceptGuestButton), 10000,
                    'Admin should be able to see and click accept guest button. ' +
                    'Make sure that guest is currently trying to connect to the page');
    
            acceptGuestButton.click();
            //Calling browser directly since we need to do complex action. Just example.
            guest.wait(EC.visibilityOf(guest.$('.central-content')), 10000, 'Guest should be dropped to the page');
        }
    
    }
    
    //Then in your tests
    let guestHomePage = HomePage.getPageFor(guest);
    guestHomePage.login();
    let adminHomePage = HomePage.getPageFor(admin);
    adminHomePage.acceptGuest();
    adminHomePage.openProfileMenu();
    guestHomePage.openProfileMenu();
    

提交回复
热议问题