How to check if an element has a class using Protractor?

I am trying to use Protractor to test Angular e2e and have not figured out how to determine if an element has a specific class or not.

In my case, the test presses the submit button, and now I want to know if the form [name = "getoffer"] has the .ngDirty class. What could be the solutions?

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 }); }); 
+63
angularjs protractor
Nov 28 '13 at 14:01
source share
9 answers

One of them that you should look for with toMatch() , as in the accepted answer, is partial matches. For example, suppose you have an element that can have the correct and incorrect classes, and you want to verify that it has the correct class. If you used expect(element.getAttribute('class')).toMatch('correct') , this will return true even if the element has a class incorrect .

My suggestion:

If you want to accept only exact matches, you can create a helper method for it:

 var hasClass = function (element, cls) { return element.getAttribute('class').then(function (classes) { return classes.split(' ').indexOf(cls) !== -1; }); }; 

You can use it like this (taking advantage of the expect automatically resolving promises in Protractor):

 expect(hasClass(element(by.name('getoffer')), 'ngDirty')).toBe(true); 
+82
Apr 13 '14 at 17:40
source share

If you use Protractor with Jasmine, you can use toMatch to match the regex ...

 expect(element(by.name('getoffer')).getAttribute('class')).toMatch('ngDirty'); 

Also note that toContain will match list items if you need it.

+49
Dec 02 '13 at 16:57
source share

The easiest way:

 expect(element.getAttribute('class')).toContain("active"); 
+7
Dec 09 '16 at 12:01
source share

You tried...

 var el = element(by.name('getoffer')); expect(e.getAttribute('class')).toBe('ngDirty') 

or option above ...

+3
Nov 28 '13 at 22:27
source share

Based on Sergey K's answer, you can also add custom matches for this:

(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 ) }) ) 

Then you can use it in tests as follows:

 expect($('div#ugly')).toHaveClass('beautiful') 

And you will get the following error if it is not:

  Message: Expected div#ugly to have class beautiful Stacktrace: Error: Expected div#ugly to have class 'beautiful' 
+3
Jul 31 '14 at
source share

I made this helper, I had to wrap it with a promise and use 2 returns

 this.addMatchers({ toHaveClass: function(a) { return this.actual.getAttribute('class').then(function(cls){ var patt = new RegExp('(^|\\s)' + a + '(\\s|$)'); return patt.test(cls); }); } }); 

in my test I can now do stuf as follows:

  var myDivs = element.all(by.css('div.myClass')); expect(myDivs.count()).toBe(3); // test for class expect(myDivs.get(0)).not.toHaveClass('active'); 

this also works when an element has several classes or when the element has no class attribute at all.

+2
Jan 20 '15 at 8:51
source share

Here's a custom toHaveClass Jasmine toHaveClass template with support for .not negation plus a wait of up to 5 seconds (or whatever you specify).

Find the full user matches that will be added to your onPrepare block in this value.

Sample Usage:

 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'); }); 
+1
Aug 6 '14 at 2:06
source share
 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; }); } 

This is how I do it, at least without having to use the wait function. This function simply returns true if the class is inside the element and false is not. It also uses promises so you use it like:

 checkHasClass('#your-element', 'your-class').then(function(class_found){ if (class_found) console.log("Your element has that class"); }); 

Edit: I just realized that this is essentially the same as the main answer

+1
May 7 '15 at 17:32
source share

One way to achieve this is to use xpath and use contains()

Example:

 var expectElementToHaveClass = function (className) { var path = by.xpath("//div[contains(@class,'"+ className +"')]"); expect(element.all(path).count()).to.eventually.be.eq(1); }; 
+1
Jul 06 '15 at 6:45
source share



All Articles