Структура объектной модели страницы для сложного приложения - PullRequest
0 голосов
/ 12 сентября 2018

В последние пару месяцев я использовал 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 для инициализациив теле метода для этой конкретной страницы.

Например, если у меня есть поле ввода на странице 1, я хочу определить метод внутри 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.Я могу скопировать и вставить ошибки, если это необходимо.

Что я могу сделать, чтобы я

  • Я смог добиться такого рода модульности.
  • Если яможет улучшить эту структуру, какой должен быть мой подход.

1 Ответ

0 голосов
/ 13 сентября 2018

Вы можете вернуть функцию стрелки, которая будет возвращать модули / набор функций с переменной 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)

Вот и все.Теперь все функции имеют доступ к переменной страницы.Существуют и другие способы, такие как расширение классов, связывание страниц и т. Д. Но это будет самый простой способ, как вы можете видеть.Вы можете разделить его, если вам нужно.

Мы на полпути.Это само по себе не решит эту проблему.Модуль по-прежнему не будет работать из-за асинхронного ожидания и проблемы с классами.

Вот полный рабочий пример,

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