Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Selenium/WebdriverJs/量角器承诺与页面对象链接_Javascript_Selenium_Promise_Chaining - Fatal编程技术网

Javascript Selenium/WebdriverJs/量角器承诺与页面对象链接

Javascript Selenium/WebdriverJs/量角器承诺与页面对象链接,javascript,selenium,promise,chaining,Javascript,Selenium,Promise,Chaining,我目前正在量角器/selenium中实现页面对象模式 由于量角器中的每个方法都返回一个承诺,为了一致性,我的页面对象中的方法也应该返回承诺 此外,“我的页面”对象可能具有返回另一个页面对象或页面对象自定义(如LeftNavigation、MainContent)的函数。页面对象不应返回页面对象本身,而应在承诺内返回。目前我真的不知道该怎么做 此外,我希望在不使用.then(..)方法的情况下链接我的方法调用。对于WebElements,可以在不调用.then(..)方法的情况下调用其他函数,例如

我目前正在量角器/selenium中实现页面对象模式

由于量角器中的每个方法都返回一个承诺,为了一致性,我的页面对象中的方法也应该返回承诺

此外,“我的页面”对象可能具有返回另一个页面对象或页面对象自定义(如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>
下面是我的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;
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;
var LeftNavigation=require('../../pageobject/LeftNavigation.js');
var MainContent=require('../../pageobject/MainContent.js');
类AdminBasePage{
构造函数(){
这是。_leftNavigation=new leftNavigation();
这。_mainContent=新的mainContent();
}
/**
*@returns{Promise}
*/
静态getPage(){
返回browser.driver.get(“index.php”).then(function(){
返回新的AdminBasePage();
});
}
/**
*@返回
*/
注销(){
this.leftNavigation.logout();
return new LoginPage();//在这里,我想返回一个承诺。
}
/**
*@returns{LeftNavigation}
*/
获取leftNavigation(){
//与其直接返回对象,我想在这里返回一个承诺。
//但是怎么做呢?
返回此项。_leftNavigation;
};
/**
*@返回{MainContent}
*/
获取mainContent(){
//与其直接返回对象,我想在这里返回一个承诺。
//但是怎么做呢?
返回此内容。\u main content;
};
}
module.exports=AdminBasePage;
MainContent.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;
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;
class主内容{
构造函数(){
/**@type{WebElementPromise}*/
this._element_mainContent=this.webDriver.findElement(By.css(“#mainContent”);
}
/**
*获取主要内容的标题
*
*@returns{webdriver.promise.promise}
*/
getMainContentTitle(){
返回此。\u元素\u主内容
.findElement(By.id('moduleTitle'))
.getText();
}
}
/**@type{MainContent}*/
module.exports=MainContent;
你能给我一些建议吗? 我希望我想解释的东西能清楚一些:——)


关于

你不应该试图让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();
    }

}
description('Suite',function(){
它('模块标题应该是…',函数(){
让pageAdmin=AdminBaseBage.get();
让mContent=pageAdmin.mainContent;
让titlePromise=mContent.getModuleTitle();
expect(titlePromise).toEqual(模块标题);
});
});
类主要内容{
构造函数(){
}
获取元素(moduleTitle(){返回元素(By.css('#maincontent#moduleTitle'));}
/**
*获取主要内容的标题
*
*@returns{webdriver.promise.promise}
*/
getModuleTitle(){
返回此.element_module_title.getText();
}
}
感谢您的输入

页面对象不应该约束执行流,这是正确的。我将忘记在这里试图作出承诺:-)。 我还提取了构造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

}
我的主页对象现在由我创建的几个页面元素(LeftNavigation、TopMenu等)组成。 这些页面元素中的每一个现在都可以访问它们所需的WebElement(仅通过getter方法)

类AdminBasePage扩展了BasePage{
建造师{
超级();
/**@type{LeftNavigation}*/
这是。_leftNavigation=new leftNavigation();
/**@type{TopMenu}*/
这是。_topMenu=新建topMenu();
/**@type{PathNavi}*/
这是。_pathNavi=new pathNavi();
/**@type{ContentTopBar}*/
这是。_contentTopBar=新contentTopBar();
/**@type主内容*/
此._mainContent=new mainContent()
}
/**
*@returns{Promise}
*/
静态getPage(){
返回browser.driver.get(“index.php”).then(function(){
返回新的AdminBasePage();
});
}
…getters+其他方法如下
}
现在,我的测试如下所示:

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);
        });
    });
}
描述('module_checklist',函数(){
它('检查列表中元素的数量',函数(){
让page=AdminBasePage.getPage();//返回承诺
//检查列表行数
第页。然后(函数(templateListPage){
返回templateListPage.mainContent.getArrListRows();//返回承诺
})
.then(函数(行){
期望值(arrRows.length)、toEqual(2);
});
//检查分页中的总数
第页。然后(函数(templateListPage){
expect(templateListPage.mainContent.getPagination().getIntPaginationTotalNumber()).toEqual(2);
});
});
}

不需要所有的
。那么
,你应该删除它们。这是我已经尝试过的,但不起作用。这就是为什么我使用
。然后
。当尝试执行此操作时:
期望(page.mainContent.getPagination().getIntPaginationTolNumber()).toEqual(2);
我得到错误
类型错误:无法读取未定义的属性“getPagination”
这是因为