2016-05-09 41 views
3

我目前在量角器/硒中實現頁面對象模式。Selenium/WebdriverJs /量角器承諾鏈接頁面對象

由於量角器中的每個方法都會返回一個promise,因此Constelency中的頁面對象中的方法也應該返回promise。

此外,我的頁面對象可能具有返回另一個頁面對象或頁面對象的自定義(如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應該是一個方法/屬性工廠,因此不應該是執行流程中的一個約束。 我會保持簡單通過一個屬性返回一個元素,而不是試圖找到在構造函數中的所有元素:

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);' 我得到的錯誤 '類型錯誤:無法讀取屬性「 getPagination'undefined' 這是因爲本例中的'page'是一個promise(參見'AdminBasePage.getPage()'方法)。 – Stefan