Protractor — это инструмент для end-to-end тестирования Angular и не-Angular приложений на JavaScript. Основной задачей Protractor является управление браузером и взаимодействие с элементами DOM, что позволяет проверять функциональность веб-приложений в реальных условиях.
В Protractor для работы с элементами используется объект
element, который создаётся с помощью локаторов.
element возвращает ElementFinder — объект,
представляющий один элемент DOM. Для работы с коллекциями элементов
используется element.all, возвращающий
ElementArrayFinder.
let usernameInput = element(by.id('username'));
let allButtons = element.all(by.tagName('button'));
Ключевые методы ElementFinder:
click() — клик по элементу.sendKeys() — ввод текста в поле ввода.getText() — получение текста элемента.getAttribute(attributeName) — получение значения
атрибута.isDisplayed() — проверка видимости элемента.isEnabled() — проверка доступности элемента.isPresent() — проверка наличия элемента в DOM.ElementArrayFinder позволяет выполнять действия над
множеством элементов одновременно:
allButtons.each(function(button) {
button.getText().then(function(text) {
console.log(text);
});
});
Локаторы — это способ идентификации элементов на странице. Protractor расширяет стандартные локаторы Selenium и добавляет специфичные для Angular:
Стандартные локаторы:
by.id('id') — поиск по идентификатору.by.css('selector') — поиск по CSS-селектору.by.className('class') — поиск по классу.by.tagName('tag') — поиск по тегу.by.name('name') — поиск по атрибуту name.by.linkText('text') — поиск по полному тексту
ссылки.by.partialLinkText('text') — поиск по части текста
ссылки.by.xpath('xpath') — поиск с помощью XPath.Angular-специфичные локаторы:
by.model('modelName') — поиск по Angular-модели.by.binding('bindingName') — поиск по
Angular-привязке.by.repeater('repeaterExpression') — поиск повторяющихся
элементов, например, в ng-repeat.Использование Angular-локаторов позволяет тестам быть более стабильными и не зависеть от структурных изменений HTML.
Protractor взаимодействует с DOM через браузерный движок и управляет элементами асинхронно. Для корректной работы с Angular нужно учитывать ожидание завершения асинхронных операций. Основные подходы:
let EC = protractor.ExpectedConditions;
let loginButton = element(by.id('login'));
browser.wait(EC.visibilityOf(loginButton), 5000);
loginButton.click();
let message = element(by.css('.alert'));
browser.wait(EC.textToBePresentInElement(message, 'Успешно'), 5000);
let checkbox = element(by.id('agree'));
browser.wait(EC.elementToBeClickable(checkbox), 3000);
checkbox.click();
Использование ExpectedConditions позволяет сделать тесты
более стабильными, избегая ошибок, связанных с асинхронностью.
Для повышения устойчивости тестов к изменениям DOM важно правильно выбирать локаторы:
id) —
лучший выбор для одиночных элементов.ElementArrayFinder поддерживает фильтрацию и
преобразование элементов:
let visibleButtons = allButtons.filter(function(button) {
return button.isDisplayed();
});
visibleButtons.map(function(button) {
return button.getText();
});
Методы first(), last(),
get(index) позволяют обращаться к конкретным элементам
коллекции.
Для взаимодействия с элементами внутри iframe необходимо переключиться на контекст:
let frame = element(by.tagName('iframe'));
browser.switchTo().frame(frame.getWebElement());
element(by.id('input')).sendKeys('тест');
browser.switchTo().defaultContent();
Для работы с окнами или вкладками используется
getAllWindowHandles и
switchTo().window(handle).
Protractor позволяет имитировать действия пользователя:
click() — клик.sendKeys() — ввод текста.clear() — очистка поля ввода.mouseMove() — перемещение мыши.dragAndDrop() — перетаскивание элементов.Для сложных действий используется browser.actions():
browser.actions()
.mouseMove(element(by.id('drag')))
.dragAndDrop(element(by.id('drop')))
.perform();
Это позволяет эмулировать реальные сценарии пользователя, включая drag-and-drop, hover и комбинированные клики.
Protractor работает с Promise и асинхронными операциями.
Методы getText(), isDisplayed() возвращают
промисы. Использование async/await упрощает синхронное
восприятие кода:
let text = await element(by.id('message')).getText();
if (text === 'Готово') {
await element(by.id('continue')).click();
}
Асинхронность требует внимательного подхода к последовательности действий и ожиданиям элементов.
ExpectedConditions необходимы для надежного
взаимодействия с динамическим DOM.async/await для
корректного порядка действий.Эффективное взаимодействие с DOM через элементы и локаторы является фундаментом для написания надежных и масштабируемых Protractor-тестов.