IDE. Web Driver. Server. Grid. Gemini
Жигалов Сергей
это инструмент для автоматизированного управления браузерами
![]() |
Selenium IDE |
![]() |
Selenium WebDriver |
![]() |
Selenium Server + Selenium Grid |
В 2004 году, Джейсон Хаггис ... ядро было реализовано на JavaScript, многие вещи было невозможно осуществить из-за ограничений безопасности браузеров ... Selenium
В 2006 году, Саймон Стюарт ... инструмент для тестирования, который бы общался с браузером используя нативные методы операционной системы и браузера ... WebDriver
В 2008 году, слияние Selenium и WebDriver ... Selenium 2 (или Selenium Webdriver)
(Integrated Development Environment, интегрированная среда разработки) — это инструмент, используемый для разработки тестовых сценариев.
lodash | ||
open | /docs/4.17.4 | |
sendKeys | css=input[type="search"] | filter |
click | css=.react-menu-container li:not(.hidden)>a | |
assertLocation | https://lodash.com/docs/4.17.4#filter |
expert-hello-test | ||
open | /adv/expert/exam/hello | |
click | css=.checkbox__control | |
clickAndWait | link=Начать тестирование | |
click | css=.radiobox__control | |
click | //button[@type='button'] | |
waitForText | css=div.attempt-progress__text | 9% пройдено | ... |
waitForText | link=Вернуться на главную Сертификации | Вернуться на главную Сертификации |
click
dragAndDrop
type
submit
sendKeys
...
AndWait
clickAndWait
dragAndDropAndWait
typeAndWait
submitAndWait
sendKeysAndWait
...AndWait
Команда | Цель | Значение |
store | Степан | name |
storeElementPresent | //div/form | hasForm |
storeText | //h1 | title |
storeEval | storedVars['title'].toLowerCase() | header |
Команда | Цель | Значение |
assertValue |
id=result |
15120 |
verifyValue |
id=result |
15120 |
waitForValue |
id=result |
15120 |
Команда | Цель | Значение |
goBackAndWait | ||
verifyTextPresent | Добро пожаловать на мою страницу | |
type | id=phone | (555) 666-7066 |
type | id=address1 | ${myVariableAddress} |
цель, идентифицирующая элемент на странице веб-приложения
identifier=loginForm
id=loginForm
name=username
link=Начать тестирование
xpath=/html/body/form[1]
//form[1]
//form[@id='loginForm']/input[4]
//input[@name='continue'][@type='button']
dom=document.getElementById('loginForm')
dom=document.forms[0]
document.forms[0].elements[3]
css=form#loginForm
css=input[name="username"]
css=#loginForm input[type="button"]
Шаблоны дают пользователю возможность описывать искомый текст с помощью специальных символов, вместо того, чтобы указывать этот текст в точности
Автоматизация рутины
Знакомство с командами Selenium
Работает только в Firefox
- Открыть http://www.google.com
- Набрать `webdriver` в строке поиска
- Кликнуть по кнопке
driver.get('http://www.google.com');
driver.findElement(webdriver.By.id('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.id('btnG')).click();
browser
.get("http://www.google.com")
.elementById('q')
.sendKeys('webdriver')
.elementById('btnG')
.click()
client
.url('http://google.com')
.setValue('#q','webdriver')
.click('#btnG')
# Загружаем selenium-server
curl -O http://selenium-release.storage.googleapis.com/3.0/selenium-server-standalone-3.4.0.jar
# Загружаем и распаковываем geckodriver
curl -L https://github.com/mozilla/geckodriver/releases/download/v0.16.0/geckodriver-v0.16.0-macos.tar.gz | tar xz
# Запускаем selenium-server
java -jar -Dwebdriver.gecko.driver=./geckodriver selenium-server-standalone-3.4.0.jar
# Установка selenium-standalone
npm install selenium-standalone --save-dev
# Установка необходимых драйверов браузеров
./node_modules/.bin/selenium-standalone install
# Запуск сервера
./node_modules/.bin/selenium-standalone start
# Устанавливаем webdriverio
npm install webdriverio --save-dev
const webdriverio = require('webdriverio');
const options = {
desiredCapabilities: {
browserName: 'firefox'
}
};
webdriverio
.remote(options)
.init()
.url('http://www.google.com')
.getTitle()
.then(title => console.log('Title was: ' + title))
.end();
# Запускаем google-script.js
node google-script.js
> Title was: Google
Автоматизированный запуск
Подходит только для скриптов
Promise-интерфейс
Не параллелится
Локально нет всех браузеров
./node_modules/.bin/wdio config
// tests/google-test.js
const assert = require('assert');
describe('Google page', () => {
it('should have correct title', () => {
browser.url('http://www.google.com');
const actual = browser.getTitle();
assert.equal(actual, 'Google');
});
});
./node_modules/.bin/wdio wdio.conf.js
const assert = require('assert');
describe('Converter page', () => {
it('should convert value', () => {
browser.url(
'https://urfu-2016-convertor.herokuapp.com/convert.html');
browser.setValue('#value', '1.5');
browser.setValue('#from', 'week');
browser.setValue('#to', 'min');
browser.click('#send');
browser.waitForValue('#result', 2000);
const actual = browser.getValue('#result');
assert.equal(actual, '15120');
});
});
Автоматизированный запуск
Синхронный интерфейс
Параллельный запуск тестов
Локально нет всех браузеров
export SAUCE_USERNAME="your Sauce username"
export SAUCE_ACCESS_KEY="your sauce access key"
./node_modules/.bin/wdio config
// wdio.conf.js
{
mochaOpts: {
timeout: 30000
}
}
./node_modules/.bin/wdio wdio.conf.js
Автоматизированный запуск
Синхронный интерфейс
Параллельный запуск тестов
Все браузеры
npm install gemini --save-dev
module.exports = {
rootUrl: 'https://urfu-2016-convertor.herokuapp.com',
gridUrl: `http://${process.env.SAUCE_USERNAME}:${process.env.SAUCE_ACCESS_KEY}@ondemand.saucelabs.com:80/wd/hub`,
browsers: {
chrome: {
desiredCapabilities: {
browserName: 'chrome'
}
}
}
};
// gemini/converter-test.js
gemini.suite('Converter', (suite) => {
suite.setUrl('/convert.html')
.setCaptureElements('.container')
.capture('enabled');
});
// gemini/converter-test.js
gemini.suite('Converter', (suite) => {
suite.setUrl('/convert.html')
/* ... */
.capture('disabled', (actions, find) => {
const from = find('#from');
actions.sendKeys(from, 'Invalid value');
});
});
# Создаём эталонные снимки
./node_modules/.bin/gemini update
# Тестируем
./node_modules/.bin/gemini test
# Устанавливаем gemini-gui
npm install gemini-gui --save-dev
# Запускаем gemini-gui
./node_modules/.bin/gemini-gui
gemini.suite('Converter', (suite) => {
suite.setUrl('/convert.html')
/* ... */
.capture('disabled', (actions, find) => {
const from = find('#from');
actions
.sendKeys(from, gemini.BACK_SPACE)
.sendKeys(from, 'Invalid value');
});
});