by.css()

Метод by.css() в Protractor используется для поиска элементов на веб-странице с помощью CSS-селекторов. Это один из самых гибких и часто применяемых локаторов, так как CSS-селекторы позволяют обращаться к элементам по тегу, классу, идентификатору, атрибутам, состоянию и их комбинациям.

Основы использования by.css()

Синтаксис метода прост:

element(by.css('CSS-селектор'));

Здесь element — это глобальная функция Protractor, возвращающая объект ElementFinder, который позволяет выполнять действия над найденным элементом, такие как клик, ввод текста или проверка видимости. CSS-селектор передаётся как строка.

Примеры базовых селекторов:

// По идентификатору
element(by.css('#login-button'));

// По классу
element(by.css('.form-control'));

// По тегу
element(by.css('input'));

// По атрибуту
element(by.css('[name="username"]'));

Комбинирование селекторов

CSS позволяет комбинировать селекторы для более точного поиска:

// Тег и класс одновременно
element(by.css('button.submit-btn'));

// Класс и атрибут
element(by.css('.form-control[name="email"]'));

// Вложенные элементы
element(by.css('form.login-form input[type="password"]'));

Псевдоклассы и состояние элементов

CSS-селекторы поддерживают псевдоклассы, что позволяет искать элементы по состоянию:

// Первый элемент списка
element(by.css('ul li:first-child'));

// Последний элемент
element(by.css('ul li:last-child'));

// Активный элемент
element(by.css('button.active'));

// Проверка видимого элемента
element(by.css('div:visible'));

Работа с множественными элементами

Метод element.all(by.css()) возвращает коллекцию элементов (ElementArrayFinder). Это позволяет выполнять действия над множеством элементов сразу:

// Получение всех кнопок на странице
let buttons = element.all(by.css('button'));

// Получение текста всех кнопок
buttons.getText().then(texts => console.log(texts));

// Клик по первой кнопке
buttons.first().click();

// Клик по последней кнопке
buttons.last().click();

// Фильтрация элементов по условию
let visibleButtons = buttons.filter(async button => await button.isDisplayed());

Практические советы по использованию CSS-селекторов

  1. Уникальные идентификаторы (id) всегда предпочтительнее, если они доступны, так как они обеспечивают однозначный поиск элемента.
  2. Классы удобны для группировки элементов, но при динамическом изменении классов стоит использовать более стабильные атрибуты.
  3. Атрибуты data-* часто применяются специально для автоматизированного тестирования, например:
element(by.css('[data-test-id="submit"]'));
  1. Избегать излишне сложных селекторов, которые зависят от структуры DOM. Это повышает стабильность тестов при изменении верстки.

Взаимодействие с найденными элементами

После нахождения элемента с помощью by.css() можно использовать методы ElementFinder:

let usernameInput = element(by.css('#username'));

// Ввод текста
usernameInput.sendKeys('testuser');

// Клик
element(by.css('.submit-btn')).click();

// Проверка видимости
usernameInput.isDisplayed().then(isVisible => console.log(isVisible));

// Получение текста
element(by.css('.alert')).getText().then(text => console.log(text));

Сочетание с ожиданиями (ExpectedConditions)

Для более стабильного тестирования полезно использовать ожидания:

let EC = protractor.ExpectedConditions;
let submitButton = element(by.css('button.submit'));

browser.wait(EC.elementToBeClickable(submitButton), 5000);
submitButton.click();

Это позволяет избежать ошибок, связанных с попыткой взаимодействия с элементами, которые ещё не загрузились или не активны.

Использование в сложных сценариях

CSS-селекторы позволяют искать элементы даже в динамических структурах:

// Элемент внутри активной вкладки
element(by.css('.tab.active .tab-content input[name="search"]'));

// Последняя строка таблицы
element(by.css('table#users tr:last-child td.name'));

// Кнопка с определённым текстом
element(by.cssContainingText('button', 'Удалить'));

Метод by.cssContainingText() — частый помощник, когда нужно найти элемент по тексту, оставаясь при этом в рамках CSS-селекторов.

Итоговые рекомендации

  • by.css() универсален, гибок и удобен для большинства задач.
  • Использовать уникальные идентификаторы и атрибуты для стабильности.
  • Применять ожидания и фильтры для динамических элементов.
  • Сохранять простоту селекторов, избегая глубокой зависимости от структуры DOM.

by.css() остаётся ключевым инструментом Protractor для построения надёжных и читаемых тестов, способных взаимодействовать с любыми элементами веб-страницы.