by.className()

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

Синтаксис

element(by.className('имя_класса'));
  • 'имя_класса' — строка, содержащая CSS-класс элемента.
  • Возвращает объект типа ElementFinder, если найден один элемент, или ElementArrayFinder, если используется в контексте element.all().

Основные особенности

  1. Точный поиск по классу: by.className() ищет элементы, содержащие указанный класс полностью. Если элемент имеет несколько классов, метод сработает при наличии совпадения хотя бы одного класса.

  2. Чувствительность к пробелам: Класс должен передаваться без пробелов и с точным совпадением имени. Пробелы или несколько классов в строке вызовут ошибку.

  3. Работа с множественными элементами: Для поиска всех элементов с определённым классом используется:

element.all(by.className('имя_класса')).then(function(elements) {
    // elements — массив найденных элементов
});

Примеры использования

Пример 1: Поиск одного элемента

let submitButton = element(by.className('btn-primary'));
submitButton.click();

В этом примере происходит поиск кнопки с классом btn-primary и выполнение действия click().

Пример 2: Поиск нескольких элементов

let listItems = element.all(by.className('list-item'));
listItems.count().then(function(count) {
    console.log('Количество элементов:', count);
});

Метод count() возвращает число найденных элементов.

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

element.all(by.className('product-name')).each(function(item) {
    item.getText().then(function(text) {
        console.log(text);
    });
});

Метод each() позволяет выполнять операции для каждого найденного элемента, а getText() — получить текстовое содержимое.

Советы по использованию

  • Если элемент имеет несколько классов, указывайте только один, наиболее уникальный. Например, <div class="card highlight"> можно искать как by.className('highlight').
  • Для динамически меняющихся классов лучше использовать CSS-селекторы через by.css(), так как by.className() ищет точное совпадение.
  • Использование element.all() предпочтительно при возможности появления нескольких элементов с одинаковым классом. Это предотвращает ошибки при попытке взаимодействовать с единственным элементом.

Отличие by.className() от других локаторов

  • by.id() ищет элемент по уникальному идентификатору, что быстрее и точнее.
  • by.css() позволяет комбинировать классы, идентификаторы и другие атрибуты.
  • by.tagName() ищет элементы по имени тега HTML.

by.className() идеально подходит для простого поиска по одному классу без сложных CSS-комбинаций.

Практические кейсы

  1. Тестирование кнопок формы
element(by.className('form-submit')).click();
expect(element(by.className('form-success')).isDisplayed()).toBe(true);
  1. Сбор данных из таблицы
element.all(by.className('table-row')).each(function(row) {
    row.element(by.className('cell-name')).getText().then(function(name) {
        console.log('Имя:', name);
    });
});
  1. Проверка наличия элементов
expect(element.all(by.className('error-message')).count()).toBeGreaterThan(0);

Ограничения

  • Не подходит для поиска по сложным комбинациям классов.
  • Если класс генерируется динамически (например, через JavaScript-фреймворки), поиск может быть ненадёжным.
  • В больших DOM-структурах поиск по классу может быть медленнее, чем по ID.

Использование by.className() делает код тестов более читаемым и понятным при работе с элементами, которые имеют уникальные или достаточно уникальные CSS-классы. Его сочетание с методами element.all(), each(), getText() и действиями над элементами позволяет строить гибкие и точные сценарии автоматизированного тестирования.