私は分度器を使ってAngularアプリをテストしていますが、要素に特定のクラスがあるかどうかを検出する方法がわかりません。
私の場合、テストは送信ボタンをクリックし、form [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
});
});
受け入れられた答えのように、toMatch()
を使用する際に注意する必要がある1つの落とし穴は、部分一致です。たとえば、クラスcorrect
およびincorrect
を持つ可能性のある要素があり、クラスcorrect
を持つことをテストするとします。 expect(element.getAttribute('class')).toMatch('correct')
を使用する場合、要素にincorrect
クラスがある場合でもtrueを返します。
私の提案:
完全一致のみを受け入れたい場合は、ヘルパーメソッドを作成できます。
var hasClass = function (element, cls) {
return element.getAttribute('class').then(function (classes) {
return classes.split(' ').indexOf(cls) !== -1;
});
};
次のように使用できます(expect
がProtractorのプロミスを自動的に解決するという事実を利用して):
expect(hasClass(element(by.name('getoffer')), 'ngDirty')).toBe(true);
ジャスミンで分度器を使用している場合、toMatch
を使用して正規表現として一致させることができます...
expect(element(by.name('getoffer')).getAttribute('class')).toMatch('ngDirty');
また、必要な場合、toContain
はリスト項目と一致することに注意してください。
最も簡単なのは:
expect(element.getAttribute('class')).toContain("active");
Sergey Kからの回答に基づいて、カスタムマッチャーを追加してこれを行うこともできます。
(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'
やってみました...
var el = element(by.name('getoffer'));
expect(e.getAttribute('class')).toBe('ngDirty')
または上記のバリエーション...
私はこのマッチャーを作成しました。約束で包んで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');
これは、要素に複数のクラスがある場合、または要素にクラス属性がまったくない場合にも機能します。
これを実現する1つの方法は、xpathを使用してcontains()
を使用することです
例:
var expectElementToHaveClass = function (className) {
var path = by.xpath("//div[contains(@class,'"+ className +"')]");
expect(element.all(path).count()).to.eventually.be.eq(1);
};
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;
});
}
これは少なくとも、expect関数を使用せずに行う方法です。この関数は、クラスが要素内にある場合はtrueを返し、そうでない場合はfalseを返します。これもpromiseを使用するため、次のように使用します。
checkHasClass('#your-element', 'your-class').then(function(class_found){
if (class_found) console.log("Your element has that class");
});
編集:これは本質的にトップアンサーと同じであることに気付きました
ここ Jasmine 1.3.xカスタムtoHaveClass
否定付き.not
サポートに加えて、最大5秒(または指定したもの)まで待機します。
このGistの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');
});
CSSパーサーを使用して、指定されたクラスの要素が存在するかどうかを確認することでこれを処理できます。
expect(element(by.css('.form[name="getoffer"].ngDirty')).isPresent()).toBe(true);