Проверка атрибутов

Protractor — это инструмент для автоматизированного тестирования веб-приложений на Angular и других JavaScript-фреймворках. Одной из ключевых задач при тестировании является проверка атрибутов элементов на странице. Атрибуты могут содержать информацию о состоянии элемента, ссылках, стилях или пользовательских данных, и их корректная проверка помогает убедиться, что приложение работает правильно.


Получение атрибутов элементов

Для доступа к атрибутам элементов используется метод getAttribute(). Он позволяет извлекать значение любого HTML-атрибута, включая стандартные (id, class, href) и пользовательские (data-*).

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

let button = element(by.css('button.submit'));
button.getAttribute('disabled').then(function(value) {
    console.log('Disabled:', value);  // Выведет true, если кнопка заблокирована
});

Ключевой момент: getAttribute() всегда возвращает строку или null, если атрибут отсутствует. Для булевых атрибутов (disabled, checked) проверка на 'true' или 'false' является стандартной практикой.


Проверка наличия и значения атрибута

Для проверки атрибута важно различать наличие атрибута и его значение.

Проверка наличия:

let inputField = element(by.css('input[name="username"]'));
inputField.getAttribute('required').then(function(value) {
    if (value !== null) {
        console.log('Поле обязательно для заполнения');
    }
});

Проверка значения:

let link = element(by.css('a.home-link'));
link.getAttribute('href').then(function(href) {
    expect(href).toBe('https://example.com/home');
});

При сравнении важно учитывать, что возвращаемое значение всегда строка. Для числовых или булевых данных требуется явное преобразование.


Использование ExpectedConditions для проверки атрибутов

Protractor предоставляет модуль ExpectedConditions для более надежной синхронизации тестов при динамическом изменении атрибутов элементов. Например, кнопка может становиться активной после выполнения определенного действия.

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

browser.wait(EC.elementToBeClickable(submitButton), 5000);
submitButton.getAttribute('disabled').then(function(value) {
    expect(value).toBe(null);  // Кнопка активна, атрибут disabled отсутствует
});

Использование ExpectedConditions снижает вероятность ложноположительных ошибок при тестировании динамического контента.


Проверка классов CSS через атрибут class

Классы элементов часто используются для отображения состояния (активный, выбранный, скрытый). Для проверки используется комбинация getAttribute('class') и методов строк JavaScript.

let menuItem = element(by.css('li.menu-item'));
menuItem.getAttribute('class').then(function(classes) {
    expect(classes.split(' ')).toContain('active');
});

Альтернативный способ — использовать метод element.hasClass(), который можно реализовать через getAttribute('class'):

protractor.ElementFinder.prototype.hasClass = function(className) {
    return this.getAttribute('class').then(function(classes) {
        return classes.split(' ').indexOf(className) !== -1;
    });
};

menuItem.hasClass('active').then(function(isActive) {
    expect(isActive).toBe(true);
});

Такой подход позволяет удобно проверять наличие нескольких классов.


Проверка пользовательских атрибутов data-*

Современные приложения часто используют пользовательские атрибуты data-* для хранения состояния. Проверка этих атрибутов аналогична проверке стандартных.

let notification = element(by.css('.notification'));
notification.getAttribute('data-severity').then(function(severity) {
    expect(severity).toBe('high');
});

Для динамических значений атрибутов можно использовать регулярные выражения:

notification.getAttribute('data-timestamp').then(function(timestamp) {
    expect(timestamp).toMatch(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/);
});

Советы по надежной проверке атрибутов

  1. Синхронизация с элементом: всегда учитывать, что атрибуты могут изменяться асинхронно. Использовать browser.wait или ExpectedConditions.
  2. Преобразование типов: getAttribute() возвращает строки. Для чисел и булевых значений необходимо преобразование.
  3. Проверка наличия: отличать проверку наличия атрибута (!== null) от проверки его значения.
  4. Множественные классы: разделять строку класса через пробел, чтобы проверять конкретный класс.
  5. Регулярные выражения: полезны для динамических атрибутов, таких как временные метки или идентификаторы.

Примеры комплексных проверок

Проверка, что кнопка активна и содержит определенный текст:

let button = element(by.css('button.submit'));
browser.wait(EC.elementToBeClickable(button), 5000);
expect(button.getAttribute('disabled')).toBe(null);
expect(button.getText()).toBe('Отправить');

Проверка элемента с несколькими классами и пользовательским атрибутом:

let card = element(by.css('.card'));
card.getAttribute('class').then(function(classes) {
    let classList = classes.split(' ');
    expect(classList).toContain('highlighted');
    expect(classList).toContain('selected');
});
card.getAttribute('data-id').then(function(id) {
    expect(id).toBe('card-123');
});

Эти подходы позволяют создавать надежные и стабильные проверки атрибутов, которые адаптируются к динамическим изменениям интерфейса и различным состояниям элементов.