2016-05-09 4 views
3

В настоящее время я реализую шаблон объекта страницы в транспортирторе/селене.Selenium/WebdriverJs/Protractor chain chain with page objects

Поскольку каждый метод в транспортирщике возвращает обещание, для удобства методы в моем объекте страницы также должны возвращать обещания.

Далее мои объекты страницы могут иметь функции, которые возвращают объект другой страницы или пользовательский объект страницы (например, LeftNavigation, MainContent). Вместо того, чтобы возвращать сам объект страницы, объект страницы должен быть возвращен в рамках обещания. В настоящее время я действительно не понимаю, как это сделать.

Кроме того, я хотел бы связать свои вызовы методов без использования метода .then (..). Для WebElements можно вызвать дополнительные функции, не вызывая метод .then (..), например.

browser.driver.findElement(By.css('#someid')).findElement(By.css('#somebutton')).click(); 

Я также хотел бы добиться этого с шаблоном страницы объекта:

let pagePromise = AdminBaseBage.get(); // returns a Promise<AdminBasePage> 
let mContent = page.mainContent;// should return a Promise<MainContent> 
let titlePromise = mContent.getModuleTitle(); // returns a Promise<string> 

или даже лучше

AdminBaseBage.get().mainContent.getModuleTitle(); 

Ниже выпиской из моих PageObjects с некоторыми вопросами здесь:

AdminBasePage.js

var LeftNavigation = require('../../pageobject/LeftNavigation.js'); 
var MainContent = require('../../pageobject/MainContent.js'); 

class AdminBasePage { 

    constructor() { 
     this._leftNavigation = new LeftNavigation(); 
     this._mainContent = new MainContent(); 
    } 

    /** 
    * @returns {Promise<AdminBasePage>} 
    */ 
    static getPage() { 
     return browser.driver.get("index.php").then(function() { 
      return new AdminBasePage(); 
     }); 
    } 

    /** 
    * @returns <LoginPage> 
    */ 
    logout() { 
     this.leftNavigation.logout(); 
     return new LoginPage(); //also here I would like to return a promise. 
    } 

    /** 
    * @returns {LeftNavigation} 
    */ 
    get leftNavigation() { 
     //Instead of return the object directly, I would like to return a promise here. 
     //But how? 
     return this._leftNavigation; 
    }; 

    /** 
    * @returns {MainContent} 
    */ 
    get mainContent() { 
     //Instead of return the object directly, I would like to return a promise here. 
     //But how? 
     return this._mainContent; 
    }; 
} 

module.exports = AdminBasePage; 

MainContent.js

class MainContent { 

    constructor() { 

     /** @type {WebElementPromise} */ 
     this._element_mainContent = this.webDriver.findElement(By.css('#maincontent')); 

    } 


    /** 
    * Gets the title of the main content 
    * 
    * @returns {webdriver.promise.Promise<string>} 
    */ 
    getMainContentTitle() { 
     return this._element_mainContent 
        .findElement(By.id('moduleTitle')) 
        .getText(); 
    } 

} 

/** @type {MainContent} */ 
module.exports = MainContent; 

Можете ли вы дать какие-либо рекомендации? Я надеюсь, что это как-то понятно, что я пытаюсь объяснить :-)

С уважением

ответ

1

Вы не должны пытаться сделать PageObject Обещание. Предполагается, что объект PageObject является фабрикой method/property и, следовательно, не должен быть ограничением в потоке выполнения. Я хотел бы сохранить его простым, возвращая элемент со свойством, а не пытаться найти все элементы конструктора:

describe('Suite', function() { 

    it('should module title be ...', function() { 
     let pageAdmin = AdminBaseBage.get(); 
     let mContent = pageAdmin.mainContent; 
     let titlePromise = mContent.getModuleTitle(); 
     expect(titlePromise).toEqual('module title'); 
    }); 

}); 


class MainContent { 

    constructor() { 

    } 

    get element_module_title() { return element(By.css('#maincontent #moduleTitle')); } 

    /** 
    * Gets the title of the main content 
    * 
    * @returns {webdriver.promise.Promise<string>} 
    */ 
    getModuleTitle() { 
     return this.element_module_title.getText(); 
    } 

} 
0

спасибо за вход.

Вы правы, что объекты страницы не должны ограничивать поток выполнения. Я забуду о попытке сделать обещание здесь :-). Я также извлек инициализацию элемента в методах constrcturos для getter.

Объект моей главной страницы теперь состоит из нескольких элементов страницы (LeftNavigation, TopMenu и т. Д.), Которые я создал. Каждый из этих элементов страницы теперь получает доступ к нуждам WebElements (только с помощью методов getter).

class AdminBasePage extends BasePage { 

    constructor{ 
     super(); 

     /** @type {LeftNavigation} */ 
     this._leftNavigation = new LeftNavigation(); 

     /** @type {TopMenu} */ 
     this._topMenu = new TopMenu(); 

     /** @type {PathNavi} */ 
     this._pathNavi = new PathNavi(); 

     /** @type {ContentTopBar} */ 
     this._contentTopBar = new ContentTopBar(); 

    /** @type MainContent*/ 
     this._mainContent = new MainContent() 
    } 

    /** 
    * @returns {Promise<AdminBasePage>} 
    */ 
    static getPage() { 
     return browser.driver.get("index.php").then(function() { 
      return new AdminBasePage(); 
     }); 
    } 

    ....getters + other methods follow 

} 

Мой тест теперь выглядит как следует:

describe('module_checklist', function() { 
    it('Check number of elements in list', function() { 
     let page = AdminBasePage.getPage();//returns Promise<AdminBage> 

     // check number of list rows 
     page.then(function (templateListPage) { 
       return templateListPage.mainContent.getArrListRows();//returns Promise<ListRow[]> 
      }) 
      .then(function (arrRows) { 
       expect(arrRows.length).toEqual(2); 
      }); 


     //check total number in pagination 
     page.then(function (templateListPage) { 
      expect(templateListPage.mainContent.getPagination().getIntPaginationTotalNumber()).toEqual(2); 
     }); 
    }); 
} 
+0

Там нет необходимости для всех '.then', вы должны удалить их. –

+0

Вот что я уже пробовал, но он не работает. Вот почему я использую '.then'. При попытке выполнить это: 'ожидать (page.mainContent.getPagination() getIntPaginationTotalNumber().) ToEqual (2);' Я получаю ошибку 'TypeError:. Не удается прочитать свойство" getPagination 'of undefined' Это потому, что 'page' в этом случае является обещанием (см. метод' AdminBasePage.getPage() '). – Stefan