简体   繁体   English

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

[英]Page Object Model structure for a complex application

I've in the past couple of months used Puppeteer to drive an automation for a couple of small level projects. 在过去的几个月中,我曾使用Puppeteer来驱动几个小型项目的自动化。 Now I want to scale the framework for a medium/large complex application. 现在,我想扩展适用于大中型复杂应用程序的框架。

I want to use the famed Page Object Model, where in I have separated the locators, page methods in separate files and I'm calling them in the corresponding page execution code. 我想使用著名的页面对象模型,在其中我将定位器和页面方法分离在单独的文件中,并在相应的页面执行代码中调用它们。

My directory structure is like this 我的目录结构是这样的

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

The problem I'm facing right now is that I am not able to get the page to initialise in the method body for that particular page. 我面对现在的问题是,我不能够获得page的方法体初始化对特定页面。

For eg if I have an input box in page1, I want to define a method inside utils/page1methods.js which can take care of this - something like 例如,如果我在page1中有一个输入框,我想在utils/page1methods.js定义一个方法来解决这个问题-类似

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

And then I want to call this inside the page1.js it block - something like this 然后我想在page1.js块内调用it -像这样

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

I've tried this approach and ran into all kinds of .js errors regarding page being not defined in the page1methods.js file. 我尝试了这种方法,并遇到了有关page1methods.js文件中未定义page所有.js错误。 I can copy paste the errors if that's necessary. 如果有必要,我可以复制粘贴错误。

What can I do so that I 我该怎么办

  • I am able to achieve this kind of modularisation. 我能够实现这种模块化。
  • If I can improve on this structure, what should be my approach. 如果我可以改善这种结构,那我应该怎么做。

You can return an arrow function that will return the modules/set of functions with page variable. 您可以返回箭头函数,该函数将返回带有page变量的模块/函数集。 Be sure to wrap the whole thing in first braces, or manually return it. 确保将整个东西放在大括号中,或手动将其退回。

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

And then pass the variable up there, 然后将变量传递到那里

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

That's it. 而已。 Now all functions have access to page variable. 现在,所有功能都可以访问页面变量。 There are other ways like extending classes, binding page etc. But this will be the easiest way as you can see. 还有其他方法,例如扩展类,绑定页面等。但这将是您所看到的最简单的方法。 You can split it if you need. 您可以根据需要将其拆分。

We are halfway there. 我们到了一半。 That itself won't solve this problem. 那本身并不能解决这个问题。 The module still won't work due to async-await and class issue. 由于异步等待和类问题,该模块仍然无法正常工作。

Here is a full working example, 这是一个完整的工作示例,

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();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM