Bir öğenin görünür olup olmadığını kontrol etmek için iletki nasıl kullanılır?


111

İletki kullanarak bir öğenin görünür olup olmadığını test etmeye çalışıyorum. İşte öğenin neye benzediği:

<i class="icon-spinner icon-spin ng-hide" ng-show="saving"></i>

Chrome konsolundayken, öğenin görünür olup olmadığını test etmek için bu jQuery seçiciyi kullanabilirim:

$('[ng-show=saving].icon-spin')
[
<i class=​"icon-spinner icon-spin ng-hide" ng-show=​"saving">​</i>​
]
> $('[ng-show=saving].icon-spin:visible')
[]

Ancak, iletki içinde aynısını yapmaya çalıştığımda, çalışma zamanında şu hatayı alıyorum:

InvalidElementStateError: 
invalid element state: Failed to execute 'querySelectorAll' on 'Document': 
'[ng-show=saving].icon-spin:visible' is not a valid selector.

Bu neden geçerli değil? İletki kullanarak görünürlüğü nasıl kontrol edebilirim?


Hey @limp_chimp aşağıdaki cevabım size yardımcı oldu mu?
Leo Gallucci

@limp_chimp görünürlük gibi şeyler için AngularJS istemci DOM birim testlerini kullanmayı düşünün. Çalıştırması çok daha hızlı ve geliştirmesi daha kolaydır.
Offirmo

Yanıtlar:


144

Bunu yapmalı:

expect($('[ng-show=saving].icon-spin').isDisplayed()).toBe(true);

İletkinin $jQuery olmadığını ve henüz mevcut CSS seçicilerinin ve sözde seçicilerinin bir parçası :visibleolmadığını unutmayın.

Https://stackoverflow.com/a/13388700/511069 adresinde daha fazla bilgi


1
Ah adamım. Çok havalı. Bu tam olarak belirleyebilmem gereken şeydi. Çok teşekkür ederim dostum
racl101

2
Aşağıdaki cevap da kullanır, isDisplayed()ancak tamlık vaadini çözmek için genişler, ancak bu adım isteğe bağlıdır ve yalnızca testlerinize kötü bir uygulama olan koşullu ifadeleri dahil etmek içindir. @asenovm "Bu tamamen yanlış" yorumunuzu biraz daha açabilir misiniz?
Leo Gallucci

@LeoGallucci, isDisplayed () bir boole değil, ElementFinder döndürür.
asenovm

1
Lütfen bunun yerine .toBeTruthy();kullanmayın .toBe(true). .toBeTruthy();[], 'false', 42 gibi şeylerle eşleşir. Temelde 0, "", null, undefined, NaN veya false bekleyen her şey doğrudur.
Brian

78

İletki ile bir öğenin görünürlüğünü kontrol etmenin doğru yolu isDisplayedyöntemi çağırmaktır . isDisplayedBir boole döndürmediğinden promise, değerlendirilen görünürlüğü sağladığı için dikkatli olmalısınız . Bu yöntemi yanlış kullanan ve bu nedenle gerçek görünürlüğünü değerlendirmeyen birçok kod örneği gördüm.

Bir öğenin görünürlüğünü elde etmek için örnek:

element(by.className('your-class-name')).isDisplayed().then(function (isVisible) {
    if (isVisible) {
        // element is visible
    } else {
        // element is not visible
    }
});

Bununla birlikte, eğer sadece öğenin görünürlüğünü kontrol ediyorsanız (onu elde etmek yerine) buna ihtiyacınız yoktur, çünkü Yasemin'in beklediği () iletki yamaları her zaman sözlerin çözülmesini bekler. Bkz. Github.com/angular/jasminewd

Yani şunları yapabilirsiniz:

expect(element(by.className('your-class-name')).isDisplayed()).toBeTruthy();

AngularJSBu öğenin görünürlüğünü kontrol etmek için kullandığınızdan , bunun sınıf özniteliğini de şu şekilde kontrol edebilirsiniz ng-hide:

var spinner = element.by.css('i.icon-spin');
expect(spinner.getAttribute('class')).not.toMatch('ng-hide'); // expect element to be visible

8

Benzer bir sorun yaşadım, çünkü yalnızca bir sayfa nesnesinde görünen dönüş öğelerini istiyordum. CSS'yi kullanabileceğimi buldum :not. Bu sorun durumunda, bu size yapmalı ...

expect($('i.icon-spinner:not(.ng-hide)').isDisplayed()).toBeTruthy();

Bir sayfa nesnesi bağlamında, YALNIZCA bu şekilde görünen öğeleri de elde edebilirsiniz. Örneğin. yalnızca bazılarının göründüğü birden çok öğeye sahip bir sayfa verildiğinde, şunları kullanabilirsiniz:

this.visibileIcons = $$('i.icon:not(.ng-hide)'); 

Bu size tüm görünür i.icone- postaları döndürecektir


1
@leoGallucci'nin açıkladığı gibi isDisplayed () beklenen kapsamda olmalıdır.
çizgili

5

DOM'da aynı sınıf adına sahip birden fazla öğe varsa. Ancak yalnızca bir öğe görülebilir.

element.all(by.css('.text-input-input')).filter(function(ele){
        return ele.isDisplayed();
    }).then(function(filteredElement){
        filteredElement[0].click();
    });

Bu örnekte filtre, bir öğe koleksiyonunu alır ve isDisplayed () kullanarak tek bir görünür öğe döndürür .


Bu harika bir cevap; böyle bir unsurun olmadığı durumu düşünün! $ ('. text-input-input') kullanıcıyı zarif bir şekilde uyarır; bu başarısız olabilir çünkü filteredElement.length === 0?
The Red Pea

1

Bu yanıt, sayfada olmayan öğeler için çalışacak kadar sağlam olacaktır, bu nedenle seçici öğeyi bulamazsa nazikçe başarısız olur (bir istisna oluşturmaz).

const nameSelector = '[data-automation="name-input"]';
const nameInputIsDisplayed = () => {
    return $$(nameSelector).count()
        .then(count => count !== 0)
}
it('should be displayed', () => {
    nameInputIsDisplayed().then(isDisplayed => {
        expect(isDisplayed).toBeTruthy()
    })
})

1

Görünürlüğü beklemek

const EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(element(by.css('.icon-spinner icon-spin ng-hide')))).then(function() {
  //do stuff
})

Xpath, yalnızca görünür öğeleri bulmak için hile

element(by.xpath('//i[not(contains(@style,"display:none")) and @class="icon-spinner icon-spin ng-hide"]))

1
 element(by.className('your-class-name')).isDisplayed().then(function (isVisible) {
if (isVisible) {
    // element is visible
} else {
    // element is not visible
}
}).catch(function(err){
console.log("Element is not found");
})

0

İşte Typescript, iletki, yasemin kullanan çerçeve için kullanılabilecek birkaç kod parçası.

browser.wait(until.visibilityOf(OversightAutomationOR.lblContentModal), 3000, "Modal text is present");

// Bir metni öne sürmek

OversightAutomationOR.lblContentModal.getText().then(text => {
                    this.assertEquals(text.toString().trim(), AdminPanelData.lblContentModal);
                });

// Bir eleman iddia etmek

expect(OnboardingFormsOR.masterFormActionCloneBtn.isDisplayed()).to.eventually.equal(true

    );

OnboardingFormsOR.customFormActionViewBtn.isDisplayed().then((isDisplayed) => {
                        expect(isDisplayed).to.equal(true);
                });

// Bir form üzerinde hak iddia etmek

formInfoSection.getText().then((text) => {
                        const vendorInformationCount = text[0].split("\n");
                        let found = false;
                        for (let i = 0; i < vendorInformationCount.length; i++) {
                            if (vendorInformationCount[i] === customLabel) {
                                found = true;
                            };
                        };
                        expect(found).to.equal(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.