分度器を使用して要素が表示されているかどうかを確認する方法


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 2014

可視性などの@limp_chimpについては、AngularJSクライアントのDOMユニットテストの使用を検討してください。それらは実行がはるかに速く、開発が容易です。
Offirmo 2014

回答:


144

これはそれを行うはずです:

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

分度器$はjQuery :visibleではなく、まだ利用可能なCSSセレクター+疑似セレクターの一部ではないことに注意してください

https://stackoverflow.com/a/13388700/511069の詳細情報


1
ああ男。とてもクール。これはまさに私が決定できるようにする必要があったものです。どうもありがとうございました。
racl101 2016年

2
以下の答えも使用してisDisplayed()いますが、完全性の約束を解決するために拡張されていますが、そのステップはオプションであり、テストに条件を含めることのみを目的としています。これは悪い習慣です。@asenovmあなたの「これは明らかに間違っている」コメントをさらに詳しく説明できますか?
レオガルッチ

@LeoGallucci、isDisplayed()はブール値ではなくElementFinderを返します。
asenovm 2016

1
代わりにuseを.toBeTruthy();使用しないでください.toBe(true).toBeTruthy();[]、 'false'、42のようなものに一致します。基本的に、すべての期待値は0、 ""、null、未定義、NaNまたはfalseです。
ブライアン、

78

Protractorで要素の可視性をチェックする正しい方法は、isDisplayedメソッドを呼び出すことです。isDisplayedはブール値を返さないので注意が必要ですがpromise、評価された可視性を提供します。この方法を誤って使用しているため、実際の可視性を評価しないコード例をたくさん見ました。

要素の可視性を取得する例:

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

ただし、分度器はJasmine expect()にパッチを適用するため、要素の可視性をチェックするだけの場合は必要ありません。プロミスが解決されるまで常に待機するためです。github.com/angular/jasminewdを参照してください

だからあなたはただ行うことができます:

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

を使用AngularJSしてその要素の可視性を制御しているので、次のng-hideようにそのclass属性を確認することもできます。

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

8

同様の問題があり、ページオブジェクトに表示されるreturn要素のみが必要でした。cssを使用できることがわかりました:not。この問題の場合、これでうまくいくはずです...

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

ページオブジェクトのコンテキストでは、この方法で表示される要素のみを取得することもできます。例えば。複数のアイテムを含むページがあり、一部しか表示されていない場合は、以下を使用できます。

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

これはあなたのすべての可視戻りますi.icon


1
isDisplayed()は、@ leoGallucciが説明しているように、expectスコープにある必要があります。
ストライプ2015年

5

DOMに同じクラス名の要素が複数ある場合。ただし、表示される要素は1つだけです。

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ますか?
Red Pea 2018年

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"]))

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

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.