Hoe te testen of een element klasse heeft met behulp van Gradenboog?

Ik probeer Protractor uit om de Angular-app e2e te testen en heb niet ontdekt hoe ik kan detecteren of een element een specifieke klasse heeft of niet.

In mijn geval klikt de test op de verzendknop en nu wil ik weten of form[name=”getoffer”] klasse .ngDirty heeft. Wat kunnen de oplossingen zijn?

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

Antwoord 1, autoriteit 100%

Eén probleem waar u op moet letten bij het gebruik van toMatch(), zoals in het geaccepteerde antwoord, zijn gedeeltelijke overeenkomsten. Laten we bijvoorbeeld zeggen dat je een element hebt met de klassen correcten incorrect, en dat je wilt testen of het de klasse correctheeft. . Als u expect(element.getAttribute('class')).toMatch('correct')zou gebruiken, wordt true geretourneerd, zelfs als het element de klasse incorrectheeft .

Mijn suggestie:

Als je alleen exacte overeenkomsten wilt accepteren, kun je er een hulpmethode voor maken:

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

Je kunt het als volgt gebruiken (gebruik makend van het feit dat expectautomatisch beloften oplost in Protractor):

expect(hasClass(element(by.name('getoffer')), 'ngDirty')).toBe(true);

Antwoord 2, autoriteit 50%

Als je Protractor gebruikt met Jasmine, kun je toMatchgebruiken om te matchen als een reguliere expressie…

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

Houd er ook rekening mee dat toContainovereenkomt met lijstitems, als je dat nodig hebt.


Antwoord 3, autoriteit 17%

Het eenvoudigst is:

expect(element.getAttribute('class')).toContain("active");

Antwoord 4, autoriteit 4%

Op basis van het antwoord van Sergey K zou je hiervoor ook een aangepaste matcher kunnen toevoegen:

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

Dan kun je het in tests als deze gebruiken:

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

En je krijgt de volgende foutmelding als dat niet het geval is:

Message:
   Expected div#ugly to have class beautiful
 Stacktrace:
   Error: Expected div#ugly to have class 'beautiful'

Antwoord 5, autoriteit 4%

Heb je dit al geprobeerd?

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

of een variatie op het bovenstaande…


Antwoord 6, autoriteit 2%

Ik heb deze matcher gemaakt, ik moest hem in een belofte verpakken en 2 retourzendingen gebruiken

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 mijn test kan ik nu dingen als deze doen:

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

dit werkt ook wanneer een element meerdere klassen heeft of wanneer een element helemaal geen class-attribuut heeft.


Antwoord 7, autoriteit 2%

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

Dit is hoe ik het tenminste doe, zonder de verwachtingsfunctie te hoeven gebruiken. Deze functie retourneert gewoon waar als de klasse zich binnen het element bevindt en onwaar als dat niet het geval is. Dit gebruikt ook beloften, dus je zou het als volgt gebruiken:

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

Bewerken: ik realiseer me net dat dit in wezen hetzelfde is als het bovenste antwoord


Antwoord 8

Hiereen Jasmine 1.3.x aangepaste toHaveClassmatcher met ontkenning .notondersteuning plus wacht tot 5 seconden (of wat je ook opgeeft).

Zoek de volledige aangepaste matcher die aan uw onPrepare-blok moet worden toegevoegd

Voorbeeldgebruik:

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');
});

Antwoord 9

Een manier om dit te bereiken is door xpath te gebruiken en contains()

te gebruiken

Voorbeeld:

var expectElementToHaveClass = function (className) {
    var path = by.xpath("//div[contains(@class,'"+ className +"')]");
    expect(element.all(path).count()).to.eventually.be.eq(1);
};

Antwoord 10

Je kunt de CSS-parser gebruiken om dit af te handelen door te controleren of een element met de opgegeven klasse bestaat:

expect(element(by.css('.form[name="getoffer"].ngDirty')).isPresent()).toBe(true);

Antwoord 11

In wezen lost u een aantal problemen op:

  1. hoe je les krijgt. class is een html-attribuut en kan dus worden opgehaald met dit commando (awaitis tegenwoordig de aanbevolen manier)
let class = await element.getAttribute('class')
  1. Zodra je de waarde van een klasse hebt gekregen, wil je deze laten gelden
// for exact value
expect(class).toBe("active");
// for partial match
expect(class).toContain("active");
// or
expect(class.includes("active")).toBe(true);
// BUT, keep in mind
expect('male').toContain('male');
expect('female').toContain('male');
// BOTH pass

Other episodes