На этой неделе на работе мне пришлось протестировать приложение React с использованием Selenium. Поскольку мы используем Jest для тестирования компонентов / саги React, я подумал, что попробую заставить Jest работать с Selenium WebDriver. Во-первых, давайте npm install что нам понадобится:

npm install [email protected] chromedriver geckodriver jest -D

Если у вас Mac, вы также можете протестировать Safari. Просто убедитесь, что он доступен, набрав эту команду в своем терминале:

safaridriver

Выйдет что-то вроде этого:

Usage: safaridriver [options]
 -h, --help                Prints out this usage information.
[...]

Если вы работаете в Windows и хотите протестировать IE, вам следует начать загрузку драйвера здесь.

Теперь мы можем импортировать то, что нам нужно, из этих пакетов:

// index.test.js
const { Builder, By, Key, until } = require('selenium-webdriver')
require('selenium-webdriver/chrome')
require('selenium-webdriver/firefox')
require('chromedriver')
require('geckodriver')

Затем нам нужно инициализировать Selenium:

const rootURL = 'https://www.mozilla.org/en-US/'
const d = new Builder().forBrowser('firefox').build()
const waitUntilTime = 20000
let driver, el, actual, expected
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5

Из-за того, как работает Selenium, мы должны создать две служебные функции:

async function getElementById(id) {
  const el = await driver.wait(until.elementLocated(By.id(id)), waitUntilTime)
  return await driver.wait(until.elementIsVisible(el), waitUntilTime)
}
async function getElementByXPath(xpath) {
  const el = await driver.wait(until.elementLocated(By.xpath(xpath)), waitUntilTime)
  return await driver.wait(until.elementIsVisible(el), waitUntilTime)
}

Теперь мы можем выбрать элемент на странице, когда он станет «видимым».

Если этот элемент уже должен быть на странице, мы можем использовать:

await driver.findElement({ id: 'someId' }).sendKeys('foo')

Однако, если элемента еще нет на странице, эта команда будет ждать, пока он не станет видимым:

el = await getElementById('someId')

Самое главное, нам нужно написать два теста, которые будут запускать и инициализировать драйвер:

it('waits for the driver to start', () => {
  return d.then(_d => {
    driver = _d
  })
})

it('initialises the context', async () => {
  await driver.manage().window().setPosition(0, 0)
  await driver.manage().window().setSize(1280, 1024)
  await driver.get(rootURL)
})

Посмотрим на страницу, которую мы тестируем:

Зная идентификатор, мы можем настроить таргетинг на первый элемент навигационной панели. Давайте проверим, содержит ли текст первого элемента в ящике «Firefox» (извините, это не очень увлекательный тест 😑).

it('should click on navbar button to display a drawer', async () => {
  el = await getElementById('nav-button-menu')
  el.click()
  el = await getElementByXPath('//*[@id="moz-global-nav-drawer"]/div/div/ul/li[1]/h3/a')
  
  actual = await el.getText()
  expected = 'Firefox'
  expect(actual).toEqual(expected)
})

После запуска npm run test мы должны увидеть что-то подобное в терминале.

Вот и все, ребята! Я надеюсь, что это помогло, и не стесняйтесь оставлять мне любые отзывы, которые могут улучшить мой рабочий процесс тестирования.

Я создал репозиторий github со всем кодом, необходимым для работы: https://github.com/mathieux51/jest-selenium