2016-05-09 46 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