Прошло довольно много времени с тех пор, как я обещал сделать третью часть на страницах Nightwatch.js. Я хочу поблагодарить Мариссу, которая нашла время в своем плотном графике, чтобы связаться со мной по поводу этой части руководства. В последнее время у меня на столе было много вещей, которые я не написал за три месяца. Я сожалею о том, что. Двигаемся дальше…
В этой статье я буду говорить о Page Objects
. Без лишних слов, приступим.
Примечание. Большинство вещей, которые я здесь пишу, в основном то, что вы найдете в документации Nightwatch.js.
Что такое объект страницы?
Объект страницы позволяет программному клиенту делать что угодно и видеть все, что может сделать человек, путем абстрагирования от базовых действий HTML, необходимых для доступа к странице и управления ею.
Подробное введение в объекты страницы можно найти в этой статье.
Настроить объекты страницы
Чтобы настроить объекты страницы в nightwatch, нам нужно добавить свойство page_objects_path
в наш nightwatch.json
файл. Если вы посмотрите на это сейчас, то увидите, что мы это уже сделали. Если это не так, продолжайте и добавьте его в свой nightwatch.json
файл конфигурации. Мы назначили ”pages”
свойству page_objects_path
в нашей конфигурации, при этом мы говорим Nightwatch читать объекты страницы из папки (или папок), указанной в свойстве конфигурации page_objects_path
.
Вы также можете передать массив папок свойству page_objects_path
, что позволяет разделить объекты страницы на более мелкие группы.
Есть несколько свойств, которые можно использовать, когда мы используем объекты страницы, мы рассмотрим их в ближайшее время.
Свойство Url
Это свойство является необязательным, поскольку вы можете или не должны его указывать. Если предоставлен, он обозначает URL-адрес страницы. Вызовите метод navigate
для объекта страницы, чтобы перейти на страницу.
URL-адрес обычно определяется как строка:
export default { url: 'https://cjdocs.herokuapp.com', };
Вы также можете передать ему функцию в случае динамического URL-адреса. Один вариант использования - когда вы хотите поддерживать разные тестовые среды. Вы можете создать функцию, которая будет вызываться в контексте страницы, что позволит вам:
export default { url: function() { return this.api.launchUrl + ‘auth/signin’; }, };
Свойство Elements
Свойство elements
используется для определения элементов на вашей странице, с которыми ваши тесты будут взаимодействовать с помощью команд и утверждений. Это помогает сохранить ваш код СУХИМ, особенно в больших интеграционных тестах.
В наших тестах нам не нужно вызывать useXpath
или useCss
, чтобы переключаться между стратегиями определения местоположения, поскольку это делается для нас внутри компании. По умолчанию для locateStrategy
установлено значение CSS, но вы также можете указать XPath:
export default { elements: { searchBar: { selector: ‘input[type=text]’ }, submit: { selector: ‘//[@name=”q”]’, locateStrategy: ‘xpath’ } } };
Вы можете использовать сокращение, если вы создаете элементы с той же стратегией определения местоположения, что и по умолчанию:
export default { elements: { searchBar: ‘input[type=text]’ } };
Используя свойство elements
, мы можем ссылаться на элемент, добавляя префикс «@» к его имени, а не к селектору, при вызове команд и утверждений элемента (например, click
и т. Д.).
При желании вы можете определить массив объектов:
var sharedElements = { mailLink: ‘a[href*=”mail.google.com”]’ }; export default { elements: [ sharedElements, { searchBar: ‘input[type=text]’ } ] };
Свойство Sections
Свойство sections
позволяет определять разделы страницы. Это может быть полезно для двух вещей:
- Обеспечивает некоторый уровень пространства имен под страницей
- Он обеспечивает вложение на уровне элементов, так что любой элемент, определенный в разделе, является потомком своего родительского раздела в DOM
Создание раздела выглядит так:
export default { sections: { menu: { selector: ‘#gb’, elements: { mail: { selector: ‘a[href=”mail”]’ }, images: { selector: ‘a[href=”imghp”]’ } } } } };
Обратите внимание, что каждая команда и утверждение в разделе (кроме утверждений `expect`) возвращает этот раздел для объединения в цепочку. При желании вы можете вкладывать разделы в другие разделы для сложных структур DOM.
Свойство Commands
Свойство commands
позволяет добавлять команды к объекту страницы. Это полезный способ инкапсулировать логику страницы, которая в противном случае жила бы в тесте или нескольких тестах.
Nightwatch вызовет команду в контексте страницы или раздела. Вы можете вызывать клиентские команды, например pause
, через this.api
. При связывании каждая функция должна возвращать объект или раздел страницы.
В приведенном ниже примере используется команда для инкапсуляции логики нажатия кнопки отправки:
const googleCommands = { submit: function() { this.api.pause(1000); return this.waitForElementVisible(‘@submitButton’, 1000) .click(‘@submitButton’) .waitForElementNotPresent(‘@submitButton’); } }; export default { commands: [googleCommands], elements: { searchBar: { selector: ‘input[type=text]’ }, submitButton: { selector: ‘button[name=btnG]’ } } };
Это все свойства, доступные для объектов страницы. Пришло время увидеть некоторые из этих свойств в действии. Ура!
Я бы использовал свое приложение все еще в разработке здесь.
Написание тестов
Я буду тестировать страницу входа в приложение. Давайте продолжим и сделаем это.
Нам нужно будет создать файл подкачки в каталоге pages
, который мы создали ранее. Я назвал свой signinPage.js
и добавил его в каталог pages
.
signinPage.js
:
const signinCommands = { signin(email, password) { return this .waitForElementVisible('@emailInput') .setValue('@emailInput', email) .setValue('@passwordInput', password) .waitForElementVisible('@signinButton') .click('@signinButton') } }; export default { url: 'https://cjdocs.herokuapp.com/auth/signin', commands: [signinCommands], elements: { emailInput: { selector: 'input[type=email]' }, passwordInput: { selector: 'input[name=password]' }, signinButton: { selector: 'button[type=submit]' } } };
Затем мы создаем еще один объект страницы с именем instancesPage.js
. Это будет использоваться, чтобы абстрагироваться от того, что мы будем искать, когда тест пройдет фазу аутентификации.
instancesPage.js
:
export default { elements: { homepageWelcomeTitle: { selector: '//div/h1', locateStrategy: 'xpath' } } };
Наконец, мы должны создать наш тестовый файл с именем signin.spec.js
. signin.spec.js
:
'User can sign in'(client) { const signinPage = client.page.signinPage(); const instancesPage = client.page.instancesPage(); signinPage .navigate() .signin(process.env.EMAIL, process.env.PASSWORD); instancesPage.expect.element('@homepageWelcomeTitle').text.to.contain('Welcome to the CJDocs Home!'); client.end(); }
После этого вы можете запускать тесты с помощью команды npm test
или yarn test
.
Вот и все, что нужно для использования объектов страницы. Полагаю, не так уж и сложно?
Заключение
Объекты страницы действительно помогают сделать наш код СУХИМ, тем самым абстрагируя некоторые общие функции в одном месте и просто вызывая эти определенные методы / свойства, и мы можем иметь полностью функциональные тесты без повторяющегося кода.
Надеюсь, вы узнали что-то новое сегодня. Если вам понравилось, нажмите кнопку «Нравится». Дайте мне знать в комментариях, если у вас есть вопросы или вы хотите, чтобы я что-то ответил.
О чем бы вы хотели, чтобы я написал? Имейте в виду то, что вы давно хотели узнать, напишите мне в личку, и я обязательно отвечу.
Вы можете найти меня в Twitter @codejockie.