如何使用量角器检查元素是否可见?

时间:2014-04-03 22:36:17

标签: angularjs visible protractor

我正在尝试使用量角器测试元素是否可见。这是元素的样子:

<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.

为什么这不起作用?如何使用量角器检查可见性?

9 个答案:

答案 0 :(得分:137)

这应该这样做:

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

请记住量角器的$不是jQuery而:visible 尚未available CSS selectors + pseudo-selectors的一部分

https://stackoverflow.com/a/13388700/511069

的更多信息

答案 1 :(得分:75)

使用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()所以它总是等待promises得到解决。见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

答案 2 :(得分:8)

我有一个类似的问题,因为我只想要在页面对象中可见的返回元素。我发现我能够使用css :not。在这个问题的情况下,这应该是你......

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

在页面对象的上下文中,您只能获得以这种方式可见的元素。例如。给定一个包含多个项目的页面,其中只有一些是可见的,您可以使用:

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

这将返回所有可见的i.icon s

答案 3 :(得分:5)

如果DOM中有多个元素具有相同的类名。但只有一个元素是可见的。

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

在此示例中,过滤器使用 isDisplayed()来获取元素集合并返回单个可见元素。

答案 4 :(得分: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()
    })
})

答案 5 :(得分: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"]))

答案 6 :(得分: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");
})

答案 7 :(得分:1)

需要考虑的事情

.isDisplayed() 假定元素存在(存在于 DOM 中)

所以如果你这样做

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

但该元素不存在,而不是正常的失败期望,$('[ng-show=saving]').isDisplayed() 将抛出错误导致 it 块的其余部分未执行

解决方案

如果您假设您正在检查的元素可能因任何原因不存在于页面上,那么请使用下面的安全方法

/**
*  element is Present and is Displayed
*  @param    {ElementFinder}      $element       Locator of element
*  @return   {boolean}
*/
let isDisplayed = function ($element) {
  return (await $element.isPresent()) && (await $element.isDisplayed())
}

并使用

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

答案 8 :(得分:0)

以下是可用于使用Typescript,量角器,茉莉花和茉莉花的框架的少量代码段

onActivityResult 64206
onCancel

//声明文本

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