Как проверить, имеет ли элемент класс с помощью Protractor?
Я пытаюсь использовать Protractor для тестирования e2e Angular и не понял, как определить, имеет ли элемент определенный класс или нет.
В моем случае тест нажимает кнопку отправки, и теперь я хочу знать, имеет ли форма [ name= "getoffer" ] класс .ngDirty. Каковы могут быть решения?
describe('Contact form', function() {
beforeEach(function(){
browser.get('http://localhost:9000');
element(by.linkText('Contact me')).click();
});
it('should fail form validation, all fields pristine', function() {
element(by.css('.form[name="getoffer"] input[type="submit"]')).click();
expect(element(by.name('getoffer'))).toHaveClass('ngDirty'); // <-- This line
});
});
Ответы
Ответ 1
Один из них, который вы должны искать с помощью toMatch()
, как и в принятом ответе, - это частичные совпадения. Например, предположим, что у вас есть элемент, который может иметь классы correct
и incorrect
, и вы хотите проверить, что он имеет класс correct
. Если бы вы использовали expect(element.getAttribute('class')).toMatch('correct')
, это вернет true, даже если элемент имеет класс incorrect
.
Мое предложение:
Если вы хотите принимать только точные соответствия, вы можете создать для него вспомогательный метод:
var hasClass = function (element, cls) {
return element.getAttribute('class').then(function (classes) {
return classes.split(' ').indexOf(cls) !== -1;
});
};
Вы можете использовать его так (воспользовавшись тем, что expect
автоматически разрешает promises в Protractor):
expect(hasClass(element(by.name('getoffer')), 'ngDirty')).toBe(true);
Ответ 2
Если вы используете Protractor с Jasmine, вы можете использовать toMatch
для соответствия регулярному выражению...
expect(element(by.name('getoffer')).getAttribute('class')).toMatch('ngDirty');
Также обратите внимание, что toContain
будет соответствовать элементам списка, если вам это нужно.
Ответ 3
Проще всего:
expect(element.getAttribute('class')).toContain("active");
Ответ 4
Вы пробовали...
var el = element(by.name('getoffer'));
expect(e.getAttribute('class')).toBe('ngDirty')
или вариант выше...
Ответ 5
Основываясь на ответе Сергея К, вы также можете добавить пользовательский матчи для этого:
(CoffeeScript)
beforeEach(()->
this.addMatchers({
toHaveClass: (expected)->
@message = ()->
"Expected #{@actual.locator_.value} to have class '#{expected}'"
@actual.getAttribute('class').then((classes)->
classes.split(' ').indexOf(expected) isnt -1
)
})
)
Затем вы можете использовать его в тестах следующим образом:
expect($('div#ugly')).toHaveClass('beautiful')
И вы получите следующую ошибку, если это не так:
Message:
Expected div#ugly to have class beautiful
Stacktrace:
Error: Expected div#ugly to have class 'beautiful'
Ответ 6
Я сделал этот помощник, мне пришлось обернуть его обещанием и использовать 2 возвращения
this.addMatchers({
toHaveClass: function(a) {
return this.actual.getAttribute('class').then(function(cls){
var patt = new RegExp('(^|\\s)' + a + '(\\s|$)');
return patt.test(cls);
});
}
});
в моем тесте теперь могу сделать stuf следующим образом:
var myDivs = element.all(by.css('div.myClass'));
expect(myDivs.count()).toBe(3);
// test for class
expect(myDivs.get(0)).not.toHaveClass('active');
это также работает, когда элемент имеет несколько классов или когда элемент вообще не имеет атрибута класса.
Ответ 7
Здесь настраиваемый toHaveClass
шаблон Jasmine 1.3.x с поддержкой отрицания .not
плюс ожидание до 5 секунд (или все, что вы указываете).
Найти полный пользовательский матчи, который будет добавлен в ваш блок onPrepare в этом значении
Использование образца:
it('test the class finder custom matcher', function() {
// These guys should pass OK given your user input
// element starts with an ng-invalid class:
expect($('#user_name')).toHaveClass('ng-invalid');
expect($('#user_name')).not.toHaveClass('ZZZ');
expect($('#user_name')).toNotHaveClass('ZZZ');
expect($('#user_name')).not.toNotHaveClass('ng-invalid');
// These guys should each fail:
expect($('#user_name')).toHaveClass('ZZZ');
expect($('#user_name')).not.toHaveClass('ng-invalid');
expect($('#user_name')).toNotHaveClass('ng-invalid');
expect($('#user_name')).not.toNotHaveClass('ZZZ');
});
Ответ 8
function checkHasClass (selector, class_name) {
// custom function returns true/false depending if selector has class name
// split classes for selector into a list
return $(selector).getAttribute('class').then(function(classes){
var classes = classes.split(' ');
if (classes.indexOf(class_name) > -1) return true;
return false;
});
}
Вот как я это делаю, по крайней мере, без необходимости использовать функцию ожидания. Эта функция просто возвращает значение true, если класс находится внутри элемента, а false - нет. Это также использует promises, чтобы вы использовали его как:
checkHasClass('#your-element', 'your-class').then(function(class_found){
if (class_found) console.log("Your element has that class");
});
Изменить: я просто понял, что это по сути то же самое, что и главный ответ
Ответ 9
Один из способов добиться этого - использовать xpath и использовать contains()
Пример:
var expectElementToHaveClass = function (className) {
var path = by.xpath("//div[contains(@class,'"+ className +"')]");
expect(element.all(path).count()).to.eventually.be.eq(1);
};