Bagaimana cara menggunakan busur derajat untuk memeriksa apakah suatu elemen terlihat?

111

Saya mencoba untuk menguji apakah suatu elemen terlihat menggunakan busur derajat. Inilah elemennya:

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

Saat berada di konsol chrome, saya dapat menggunakan pemilih jQuery ini untuk menguji apakah elemen tersebut terlihat:

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

Namun, ketika saya mencoba melakukan hal yang sama pada busur derajat, saya mendapatkan kesalahan ini saat runtime:

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

Mengapa ini tidak valid? Bagaimana cara memeriksa visibilitas menggunakan busur derajat?

limp_chimp
sumber
Hai @limp_chimp, apakah jawaban saya di bawah ini membantu Anda?
Leo Gallucci
@limp_chimp untuk hal-hal seperti visibilitas, pertimbangkan untuk menggunakan pengujian unit DOM klien AngularJS. Mereka jauh lebih cepat untuk dijalankan dan lebih mudah untuk dikembangkan.
Offirmo

Jawaban:

144

Ini harus melakukannya:

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

Ingat busur derajat ini $tidak jQuery dan :visibletidak belum menjadi bagian dari CSS yang tersedia + pseudo-penyeleksi

Info lebih lanjut di https://stackoverflow.com/a/13388700/511069

Leo Gallucci
sumber
1
Aduh. Keren abis. Inilah yang saya butuhkan untuk dapat menentukan. Terima kasih banyak kawan.
racl101
2
Jawaban di bawah ini juga menggunakan isDisplayed()tetapi hanya diperluas untuk menyelesaikan janji kelengkapan meskipun langkah itu opsional dan hanya dimaksudkan untuk menyertakan persyaratan dalam pengujian Anda yang merupakan praktik yang buruk. @asenovm dapatkah Anda menjelaskan lebih lanjut komentar "Ini benar-benar salah"?
Leo Gallucci
@LeoGallucci, isDisplayed () mengembalikan ElementFinder dan bukan boolean.
asenovm
1
Harap jangan .toBeTruthy();gunakan .toBe(true)sebagai gantinya. .toBeTruthy();akan mencocokkan hal-hal seperti [], 'false', 42. Pada dasarnya apa pun yang mengharapkan 0, "", null, undefined, NaN atau false adalah benar.
Brian
78

Cara yang benar untuk memeriksa visibilitas elemen dengan Protractor adalah dengan memanggil isDisplayedmetode tersebut. Anda harus berhati-hati karena isDisplayedtidak mengembalikan boolean, melainkan promisememberikan visibilitas yang dievaluasi. Saya telah melihat banyak contoh kode yang menggunakan metode ini secara salah dan oleh karena itu tidak mengevaluasi visibilitas sebenarnya.

Contoh untuk mendapatkan visibilitas suatu elemen:

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

Namun, Anda tidak memerlukan ini jika Anda hanya memeriksa visibilitas elemen (bukan mendapatkannya) karena busur derajat menambal Jasmine expect () sehingga selalu menunggu janji diselesaikan. Lihat github.com/angular/jasminewd

Jadi Anda bisa melakukan:

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

Karena Anda menggunakan AngularJSuntuk mengontrol visibilitas elemen itu, Anda juga dapat memeriksa atribut kelasnya ng-hideseperti ini:

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

Saya memiliki masalah serupa, saya hanya ingin mengembalikan elemen yang terlihat di objek halaman. Saya menemukan bahwa saya dapat menggunakan css :not. Dalam kasus masalah ini, ini seharusnya membuat Anda ...

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

Dalam konteks objek halaman, Anda HANYA bisa mendapatkan elemen yang terlihat dengan cara ini juga. Misalnya. diberikan halaman dengan banyak item, di mana hanya beberapa yang terlihat, Anda dapat menggunakan:

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

Ini akan mengembalikan semua terlihat i.icons

Air asin
sumber
1
isDisplayed () harus berada dalam cakupan yang diharapkan seperti yang dijelaskan @leoGallucci.
Striped
5

Jika ada beberapa elemen di DOM dengan nama kelas yang sama. Tetapi hanya satu elemen yang terlihat.

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

Dalam contoh ini, filter mengambil kumpulan elemen dan mengembalikan satu elemen yang terlihat menggunakan isDisplayed () .

Seorang Qadeer Qureshi
sumber
Ini adalah jawaban yang bagus; pertimbangkan kasus dimana tidak ada elemen seperti itu! $ ('. text-input-input') akan mengingatkan pengguna dengan elegan; ini mungkin gagal karena filteredElement.length === 0?
The Red Pea
1

Jawaban ini akan cukup kuat untuk bekerja untuk elemen yang tidak ada di halaman, oleh karena itu gagal dengan baik (tidak memberikan pengecualian) jika pemilih gagal menemukan elemen tersebut.

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()
    })
})
hari yang aktif
sumber
1

Menunggu visibilitas

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

Trik Xpath untuk hanya menemukan elemen yang terlihat

element(by.xpath('//i[not(contains(@style,"display:none")) and @class="icon-spinner icon-spin ng-hide"]))
Drew Royster
sumber
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");
})
Anil Kumar
sumber
0

Berikut adalah beberapa potongan kode yang dapat digunakan untuk framework yang menggunakan typescript, busur derajat, jasmine

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

// Menegaskan teks

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

// Menegaskan sebuah elemen

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

    );

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

// Menegaskan formulir

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);
                    });     
Khyati Sehgal
sumber