İletki kullanarak bir elemanın sınıfı olup olmadığı nasıl test edilir?


90

Açı uygulamasını e2e test etmek için Açıölçer deniyorum ve bir elemanın belirli bir sınıfa sahip olup olmadığını nasıl tespit edeceğimi bulamadım.

Benim durumumda, test gönder düğmesine tıklar ve şimdi formun [name = "getoffer"] .ngDirty sınıfına sahip olup olmadığını öğrenmek istiyorum. Çözümler neler olabilir?

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

Yanıtlar:


110

toMatch()Kabul edilen cevapta olduğu gibi kullanırken dikkat etmeniz gereken bir nokta kısmi eşleşmelerdir. Örneğin, diyelim ki sınıfları olabilir bir öğe var diyelim correctve incorrectve bunu sınıfa sahip olduğunu test etmek istiyorum correct. Kullanacak olsaydınız expect(element.getAttribute('class')).toMatch('correct'), öğe incorrectsınıfa sahip olsa bile bu true döndürür .

Benim önerim:

Yalnızca tam eşleşmeleri kabul etmek istiyorsanız, bunun için bir yardımcı yöntem oluşturabilirsiniz:

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

Bunu şu şekilde kullanabilirsiniz ( expectAçıölçer'deki vaatleri otomatik olarak çözen gerçeğinden yararlanarak ):

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

1
Bu benim için çalıştı, sınıf adının deve durumu değil kısa çizgi biçimi olması gerektiği expect(hasClass(element(by.name('getoffer')), 'ng-dirty')).toBe(true);
moduyla

İşlevin sınıfın ne yaptığı konusunda pek emin değilim, özellikle .then işlevine geçilirken hangi sınıfların nerede ve hangi sınıflarda olduğu konusunda, birisi beni aydınlatabilir mi?
ErikAGriffin

@ErikAGriffin: hasClass işlevi iki argüman iletildi - bir html öğesi ve kontrol edilecek bir sınıfın adı. İşlev, öğenin sahip olduğu "sınıf" özelliğini (sınıflar) alır. Bir sınıf dizisi elde etmek için sınıf dizesini böler. Ardından, aradığınız sınıfın dizinin herhangi bir pozitif dizininde olup olmadığını kontrol eder. Varoluşu kontrol etmenin bir yolu olduğunu varsayıyorum.
VSO

Dört satırlık fonksiyonunuzu bu seksi ES6 tek satırına yeniden yazdım: hasClass = (element, className) => element.getAttribute ('class']. Sonra ((classes) => classes.split ('') .indexOf sınıfAdı)! == -1);
Laurens Mäkel

TypeScript'te: async function hasClass (elm: ElementFinder, className: string): Promise <boolean> {const classNamesStr: string = await elm.getAttribute ('class'); const classNamesArr: string [] = classNamesStr.split (''); return classNamesArr.includes (className); }
tedw

57

Jasmine ile Açıölçer kullanıyorsanız, toMatchnormal bir ifade olarak eşleştirmek için kullanabilirsiniz ...

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

Ayrıca, toContainihtiyacınız olursa bunun liste öğeleriyle eşleşeceğini unutmayın .


1
Bunu yapmanın ideal yolu olup olmadığından emin değilim, ama en azından beklendiği gibi çalışıyor :)
Allan Tatter

1
Hayır, muhtemelen olmadığını söyleyebilirim. Ben beklediğiniz elementbir ile bir nesneyi döndürmek için hasClassbir iç sarabilirdiniz yöntemi expect... çağrı
ryan.l

2
toContaintoMatchbu durumda olduğundan daha iyi bir seçim olabilir .
TrueWill

Kısmi eşleşmelere karşı korunmak istiyorsanız, gibi bir şey deneyin /(^|\s)ngDirty($|\s)/.
Andrew Myers

muhtemelen .not.toContainbelirli bir sınıfa sahip olup olmadığını kontrol etmek .toContainiçin veya var olup olmadığını kontrol etmek için kullanabilirsiniz
Jack

18

En basit olanı:

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

Bu java.util.ArrayList cannot be cast to java.lang.StringMicrosoft Edge'de hata
Manolis

@Manolis angularjs için web konsolunda java istisnalarını nasıl alıyorsunuz?
vasia

4

Sergey K'nin cevabına göre, bunu yapmak için özel bir eşleştirici de ekleyebilirsiniz:

(kahve reçetesi)

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

O zaman aşağıdaki gibi testlerde kullanabilirsiniz:

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

Ve yoksa aşağıdaki hatayı alırsınız:

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

3

Denedin mi...

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

veya yukarıdakinin bir çeşidi ...


5
Sorun şu ki, forma birden fazla sınıf bağlı.
Allan Tatter

2

Bu eşleştiriciyi yaptım, bir söze sarmak ve 2 iade kullanmak zorunda kaldım

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

benim testimde artık böyle bir şey yapabilirim:

   var myDivs = element.all(by.css('div.myClass'));
   expect(myDivs.count()).toBe(3);

   // test for class
   expect(myDivs.get(0)).not.toHaveClass('active');

bu aynı zamanda bir elemanın birden fazla sınıfa sahip olması veya bir elemanın hiç sınıf niteliği olmaması durumunda da işe yarar.


1

BuradatoHaveClass , olumsuzluk .notdesteğine sahip bir Jasmine 1.3.x özel eşleştirici ve 5 saniyeye kadar (veya ne belirtirseniz) bekleyin.

Bu ana başlıkta onPrepare bloğunuza eklenecek tam özel eşleştiriciyi bulun

Örnek kullanım:

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

Beklenti işlevini kullanmaya gerek kalmadan en azından böyle yapıyorum. Bu işlev, sınıf öğenin içindeyse true, değilse false döndürür. Bu aynı zamanda vaatleri de kullanır, böylece aşağıdaki gibi kullanırsınız:

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

Düzenleme: Bunun esasen en iyi cevapla aynı olduğunu fark ettim


1

Bunu başarmanın bir yolu, xpath kullanmak ve contains()

Misal:

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

0

Verilen sınıfa sahip bir öğenin var olup olmadığını kontrol ederek bunu işlemek için CSS ayrıştırıcısını kullanabilirsiniz:

expect(element(by.css('.form[name="getoffer"].ngDirty')).isPresent()).toBe(true);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.