จะใช้ไม้โปรแทรกเตอร์ตรวจสอบได้อย่างไรว่าสามารถมองเห็นองค์ประกอบได้หรือไม่?


111

ฉันกำลังพยายามทดสอบว่าสามารถมองเห็นองค์ประกอบโดยใช้ไม้โปรแทรกเตอร์ได้หรือไม่ นี่คือลักษณะขององค์ประกอบ:

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

เมื่ออยู่ในคอนโซล Chrome ฉันสามารถใช้ตัวเลือก jQuery นี้เพื่อทดสอบว่าองค์ประกอบนั้นมองเห็นได้หรือไม่:

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

อย่างไรก็ตามเมื่อฉันพยายามทำเช่นเดียวกันในไม้โปรแทรกเตอร์ฉันได้รับข้อผิดพลาดนี้ที่รันไทม์:

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

เหตุใดจึงไม่ถูกต้อง ฉันจะตรวจสอบการมองเห็นโดยใช้ไม้โปรแทรกเตอร์ได้อย่างไร?


เฮ้ @limp_chimp คำตอบด้านล่างของฉันช่วยคุณได้หรือไม่?
Leo Gallucci

@limp_chimp สำหรับสิ่งต่างๆเช่นการมองเห็นให้นึกถึงการใช้การทดสอบหน่วย DOM ของไคลเอ็นต์ AngularJS วิ่งได้เร็วกว่ามากและพัฒนาได้ง่ายกว่ามาก
Offirmo

คำตอบ:


144

สิ่งนี้ควรทำ:

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

จำไว้ว่าไม้โปรแทรกเตอร์$ไม่ใช่ jQuery และยัง:visibleไม่ได้เป็นส่วนหนึ่งของCSS selectors + pseudo-selectors

ข้อมูลเพิ่มเติมที่https://stackoverflow.com/a/13388700/511069


1
แย่จัง เจ๋ง. นี่คือสิ่งที่ฉันต้องการเพื่อให้สามารถระบุได้ ขอบคุณมากครับ
racl101

2
คำตอบด้านล่างยังใช้isDisplayed()แต่เพียงแค่ขยายเพื่อแก้ไขคำสัญญาเพื่อความสมบูรณ์แม้ว่าขั้นตอนนั้นจะเป็นทางเลือกและมีไว้สำหรับการรวมเงื่อนไขในการทดสอบของคุณเท่านั้นซึ่งเป็นการปฏิบัติที่ไม่ดี @asenovm คุณสามารถอธิบายเพิ่มเติมเกี่ยวกับความคิดเห็น "นี่เป็นเรื่องผิดธรรมดา" ได้หรือไม่
Leo Gallucci

@LeoGallucci, isDisplayed () ส่งคืน ElementFinder ไม่ใช่บูลีน
asenovm

1
กรุณาอย่าใช้.toBeTruthy();ใช้.toBe(true)แทน .toBeTruthy();จะจับคู่สิ่งต่างๆเช่น [], 'false', 42 โดยพื้นฐานแล้วสิ่งที่คาดหวัง 0, "", null, undefined, NaN หรือ false จะเป็นความจริง
Brian

78

วิธีที่ถูกต้องในการตรวจสอบการมองเห็นขององค์ประกอบด้วยไม้โปรแทรกเตอร์คือการเรียกใช้isDisplayedเมธอด คุณควรระมัดระวังแม้ว่าisDisplayedจะไม่ส่งคืนบูลีน แต่เป็นการpromiseให้การมองเห็นที่ประเมินไว้ ฉันเคยเห็นตัวอย่างโค้ดมากมายที่ใช้วิธีนี้อย่างไม่ถูกต้องดังนั้นจึงไม่ได้ประเมินการแสดงผลที่แท้จริง

ตัวอย่างสำหรับการมองเห็นองค์ประกอบ:

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

อย่างไรก็ตามคุณไม่จำเป็นต้องใช้สิ่งนี้หากคุณแค่ตรวจสอบการมองเห็นขององค์ประกอบ (ตรงข้ามกับการรับมัน) เนื่องจากไม้โปรแทรกเตอร์แพทช์จัสมินคาดหวัง () ดังนั้นจึงรอคำสัญญาที่จะแก้ไขเสมอ โปรดดูgithub.com/angular/jasminewd

ดังนั้นคุณสามารถทำได้:

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

เนื่องจากคุณใช้AngularJSเพื่อควบคุมการมองเห็นขององค์ประกอบนั้นคุณสามารถตรวจสอบแอตทริบิวต์คลาสได้ng-hideเช่นนี้:

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

8

ฉันมีปัญหาที่คล้ายกันคือฉันต้องการเพียงองค์ประกอบที่ส่งคืนที่มองเห็นได้ในวัตถุหน้าเท่านั้น ฉันพบว่าฉันสามารถใช้ css :notได้ ในกรณีของปัญหานี้คุณควรทำ ...

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

ในบริบทของออบเจ็กต์เพจคุณสามารถรับเฉพาะองค์ประกอบที่มองเห็นได้ด้วยวิธีนี้เช่นกัน เช่น. กำหนดหน้าที่มีหลายรายการซึ่งมีเพียงบางส่วนเท่านั้นที่มองเห็นได้คุณสามารถใช้:

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

นี้จะกลับคุณสามารถมองเห็นได้ทุกi.iconวินาที


1
isDisplayed () ควรอยู่ในขอบเขตที่คาดหวังตามที่ @leoGallucci อธิบายไว้
ลาย

5

หากมีหลายองค์ประกอบใน DOM ที่มีชื่อคลาสเดียวกัน แต่มีเพียงองค์ประกอบเดียวเท่านั้นที่มองเห็นได้

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

ในตัวกรองตัวอย่างนี้จะใช้เวลาคอลเลกชันขององค์ประกอบและส่งกลับเป็นองค์ประกอบที่มองเห็นเดียวโดยใช้isDisplayed ()


นี่คือคำตอบที่ดี พิจารณากรณีที่ไม่มีองค์ประกอบดังกล่าว! $ ('. text-input-input') จะแจ้งเตือนผู้ใช้อย่างหรูหรา สิ่งนี้อาจล้มเหลวเพราะfilteredElement.length === 0?
The Red Pea

1

คำตอบนี้จะมีประสิทธิภาพเพียงพอที่จะใช้กับองค์ประกอบที่ไม่ได้อยู่ในหน้าดังนั้นจึงล้มเหลวอย่างสง่างาม (ไม่ใช่ข้อยกเว้น) หากตัวเลือกไม่พบองค์ประกอบ

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

เพื่อรอการเปิดเผย

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

เคล็ดลับ Xpath เพื่อค้นหาเฉพาะองค์ประกอบที่มองเห็นได้

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


0

นี่คือข้อมูลโค้ดบางส่วนที่สามารถใช้สำหรับกรอบงานที่ใช้ typescript, ไม้โปรแทรกเตอร์, จัสมิน

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

// การยืนยันข้อความ

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

// การยืนยันองค์ประกอบ

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

    );

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

// การยืนยันแบบฟอร์ม

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);
                    });     
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.