页面对象复杂应用程序的模型结构

问题描述 投票:0回答:1

在过去的几个月里,我使用Puppeteer来推动几个小型项目的自动化。现在我想扩展中/大型复杂应用程序的框架。

我想使用着名的页面对象模型,我在其中分离了定位器,页面方法在单独的文件中,我在相应的页面执行代码中调用它们。

我的目录结构是这样的

e2e_tests
    - locators
        - common-locators.js
        - page1locators.js
        - page2locators.js

    - constants
        - config.js

    - utils
        - base_functions.js
        - page1methods.js
        - page2methods.js

    - urls
        - urls.json

    - screenshots

    - test
        - bootstrap.js
        - page1.js
        - page2.js

我现在面临的问题是,我无法在该特定页面的方法体中初始化page

对于例如如果我在page1中有一个输入框,我想在utils/page1methods.js中定义一个可以处理这个问题的方法 - 比如

module.exports = {
    fillFirstInputBox(){
        await page.type(locator, "ABCDEFG");
     }
}

然后我想在page1.js it区块中调用这个 - 就像这样

const firstPage = require('../utils/page1methods.js').
.
.
.
it('fills first input box', async function (){
   firstPage.fillFirstInputBox();
});

我尝试过这种方法并遇到各种.js错误,因为page没有在page1methods.js文件中定义。如果有必要,我可以复制粘贴错误。

我能做些什么呢?

  • 我能够实现这种模块化。
  • 如果我可以改进这种结构,我的方法应该是什么。
javascript puppeteer pageobjects
1个回答
2
投票

您可以返回一个箭头函数,该函数将使用page变量返回模块/函数集。务必将整个东西包裹在第一个支撑中,或手动返回。

module.exports = (page) => ({ // <-- to have page in scope
    async fillFirstInputBox(){ // <-- make this function async
        await page.type(locator, "ABCDEFG");
     }
})

然后将变量传递到那里,

// make page variable
const firstPage = require('../utils/page1methods.js')(page)

而已。现在所有函数都可以访问页面变量。还有其他方法,如扩展类,绑定页面等。但这将是你能看到的最简单的方法。如果需要,您可以拆分它。

我们到了一半。这本身不会解决这个问题。由于async-await和类问题,该模块仍然无法工作。

这是一个完整的工作示例,

const puppeteer = require("puppeteer");
const extras = require("./dummy"); // call it

puppeteer.launch().then(async browser => {
    const page = await browser.newPage();
    await page.goto("https://www.example.com");

    const title = await extras(page).getTitle(); // use it here
    console.log({ title }); // prints { title: 'Example Domain' }

    await browser.close();
});
© www.soinside.com 2019 - 2024. All rights reserved.