92

我正在尝试使用 Protractor 对 Angular 应用程序进行 e2e 测试,但还没有弄清楚如何检测元素是否具有特定的类。

在我的例子中,测试点击了提交按钮,现在我想知道 form[name="getoffer"] 是否有类 .ngDirty。可能有什么解决方案?

describe('Contact form', function() {
    beforeEach(function(){
        browser.get('http://localhost:9000');
        element(by.linkText('Contact me')).click();
    });

    it('should fail form validation, all fields pristine', function() {
        element(by.css('.form[name="getoffer"] input[type="submit"]')).click();
        expect(element(by.name('getoffer'))).toHaveClass('ngDirty'); // <-- This line
    });
});
4

11 回答 11

113

toMatch()在接受的答案中,您必须注意 using 的一个问题是部分匹配。例如,假设您有一个可能具有类的元素correctincorrect并且您想测试它是否具有类correct。如果要使用expect(element.getAttribute('class')).toMatch('correct'),即使元素具有incorrect类,它也会返回 true。

我的建议:

如果你只想接受完全匹配,你可以为它创建一个辅助方法:

var hasClass = function (element, cls) {
    return element.getAttribute('class').then(function (classes) {
        return classes.split(' ').indexOf(cls) !== -1;
    });
};

您可以像这样使用它(利用expectProtractor 中自动解析承诺的事实):

expect(hasClass(element(by.name('getoffer')), 'ngDirty')).toBe(true);
于 2014-04-13T17:40:27.183 回答
57

如果您将 Protractor 与 Jasmine 一起使用,则可以将toMatch其用作正则表达式...

expect(element(by.name('getoffer')).getAttribute('class')).toMatch('ngDirty');

另外,请注意toContain,如果需要,它将匹配列表项。

于 2013-12-02T16:57:20.863 回答
19

最简单的是:

expect(element.getAttribute('class')).toContain("active");
于 2016-12-09T12:01:34.080 回答
4

你试过这个吗?

const el = element(by.name('getoffer'));
expect(el.getAttribute('class')).toBe('ngDirty')

或上述的变体......

于 2013-11-28T22:27:08.727 回答
4

根据 Sergey K 的回答,您还可以添加一个自定义匹配器来执行此操作:

(咖啡稿)

  beforeEach(()->
    this.addMatchers({
      toHaveClass: (expected)->
        @message = ()->
          "Expected #{@actual.locator_.value} to have class '#{expected}'"

        @actual.getAttribute('class').then((classes)->
          classes.split(' ').indexOf(expected) isnt -1
        )
    })
  )

然后你可以在这样的测试中使用它:

expect($('div#ugly')).toHaveClass('beautiful')

如果没有,您将收到以下错误:

 Message:
   Expected div#ugly to have class beautiful
 Stacktrace:
   Error: Expected div#ugly to have class 'beautiful'
于 2014-07-31T14:47:47.070 回答
2

我做了这个匹配器,我必须将它包装在一个承诺中并使用 2 个回报

this.addMatchers({
    toHaveClass: function(a) {
        return this.actual.getAttribute('class').then(function(cls){
            var patt = new RegExp('(^|\\s)' + a + '(\\s|$)');
            return patt.test(cls);
        });
    }
});

在我的测试中,我现在可以这样做:

   var myDivs = element.all(by.css('div.myClass'));
   expect(myDivs.count()).toBe(3);

   // test for class
   expect(myDivs.get(0)).not.toHaveClass('active');

当一个元素有多个类或一个元素根本没有类属性时,这也适用。

于 2015-01-20T08:51:15.417 回答
2
function checkHasClass (selector, class_name) {
    // custom function returns true/false depending if selector has class name

    // split classes for selector into a list
    return $(selector).getAttribute('class').then(function(classes){
        var classes = classes.split(' ');
        if (classes.indexOf(class_name) > -1) return true;
        return false;
    });
}

至少我是这样做的,不需要使用 expect 函数。如果类在元素内部,则此函数仅返回 true,否则返回 false。这也使用了 Promise,因此您可以像这样使用它:

checkHasClass('#your-element', 'your-class').then(function(class_found){
    if (class_found) console.log("Your element has that class");
});

编辑:我刚刚意识到这与最佳答案基本相同

于 2015-05-07T17:32:03.953 回答
1

这里有一个 Jasmine 1.3.x 自定义toHaveClass匹配器,.not支持否定加上等待最多 5 秒(或任何你指定的)。

在此要点中找到要添加到 onPrepare 块中的完整自定义匹配器

示例用法:

it('test the class finder custom matcher', function() {
    // These guys should pass OK given your user input
    // element starts with an ng-invalid class:
    expect($('#user_name')).toHaveClass('ng-invalid');
    expect($('#user_name')).not.toHaveClass('ZZZ');
    expect($('#user_name')).toNotHaveClass('ZZZ');
    expect($('#user_name')).not.toNotHaveClass('ng-invalid');
    // These guys should each fail:
    expect($('#user_name')).toHaveClass('ZZZ');
    expect($('#user_name')).not.toHaveClass('ng-invalid');
    expect($('#user_name')).toNotHaveClass('ng-invalid');
    expect($('#user_name')).not.toNotHaveClass('ZZZ');
});
于 2014-08-06T02:06:33.607 回答
1

实现此目的的一种方法是使用 xpath 并使用contains()

例子:

var expectElementToHaveClass = function (className) {
    var path = by.xpath("//div[contains(@class,'"+ className +"')]");
    expect(element.all(path).count()).to.eventually.be.eq(1);
};
于 2015-07-06T06:45:05.867 回答
1

您可以使用 CSS 解析器通过检查具有给定类的元素是否存在来处理此问题:

expect(element(by.css('.form[name="getoffer"].ngDirty')).isPresent()).toBe(true);
于 2018-02-15T19:40:00.623 回答
0

本质上,您正在解决一些问题:

  1. 如何上课。class 是一个 html 属性,因此可以通过此命令检索(await现在是推荐的方式)
let class = await element.getAttribute('class')
  1. 一旦你得到一个类的值,你想断言它
// for exact value
expect(class).toBe("active");

// for partial match
expect(class).toContain("active");
// or
expect(class.includes("active")).toBe(true);

// BUT, keep in mind
expect('male').toContain('male');
expect('female').toContain('male');
// BOTH pass
于 2021-02-08T23:22:36.153 回答