angularjs - change - ng-model
¿Cómo probar si un elemento tiene clase usando Transportador? (11)
El más simple es:
expect(element.getAttribute(''class'')).toContain("active");
Estoy probando Protractor para probar e2e la aplicación angular y no he descubierto cómo detectar si un elemento tiene una clase específica o no.
En mi caso, la prueba hace clic en el botón de enviar y ahora quiero saber si la forma [name = "getoffer"] tiene la clase .ngDirty. ¿Cuáles pueden ser las soluciones?
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
});
});
En función de la respuesta de Sergey K, también podría agregar un marcador personalizado para hacer esto:
(coffeescript)
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
)
})
)
Entonces puedes usarlo en pruebas como esta:
expect($(''div#ugly'')).toHaveClass(''beautiful'')
Y obtendrá el siguiente error si no:
Message:
Expected div#ugly to have class beautiful
Stacktrace:
Error: Expected div#ugly to have class ''beautiful''
Has probado...
var el = element(by.name(''getoffer''));
expect(e.getAttribute(''class'')).toBe(''ngDirty'')
o una variación de los anteriores ...
Hice esta combinación, tuve que envolverla en una promesa y usar 2 devoluciones
this.addMatchers({
toHaveClass: function(a) {
return this.actual.getAttribute(''class'').then(function(cls){
var patt = new RegExp(''(^|//s)'' + a + ''(//s|$)'');
return patt.test(cls);
});
}
});
en mi prueba, ahora puedo hacer algo así:
var myDivs = element.all(by.css(''div.myClass''));
expect(myDivs.count()).toBe(3);
// test for class
expect(myDivs.get(0)).not.toHaveClass(''active'');
esto también funciona cuando un elemento tiene múltiples clases o cuando un elemento no tiene ningún atributo de clase.
Puede usar el analizador CSS para manejar esto al verificar si existe un elemento con la clase dada:
expect(element(by.css(''.form[name="getoffer"].ngDirty'')).isPresent()).toBe(true);
Puedes usar toMatch si tienes cuidado. Tenga en cuenta el / b en la expresión regular. Eso asegura que haya un límite en cualquiera de los extremos de tu nombre de clase.
expect(element(by.name(''getoffer'')).getAttribute(''class'')).toMatch(//bngDirty/b/);
Si está utilizando un transportador con jazmín, puede usar toMatch
para que coincida con una expresión regular ...
expect(element(by.name(''getoffer'')).getAttribute(''class'')).toMatch(''ngDirty'');
Además, tenga en cuenta que toContain
coincidirá con los elementos de la lista, si es necesario.
Una forma de lograr esto sería usar xpath y use contains()
Ejemplo:
var expectElementToHaveClass = function (className) {
var path = by.xpath("//div[contains(@class,''"+ className +"'')]");
expect(element.all(path).count()).to.eventually.be.eq(1);
};
Uno tiene que tener en cuenta al usar toMatch()
, como en la respuesta aceptada, son coincidencias parciales. Por ejemplo, supongamos que tiene un elemento que podría tener las clases correct
e incorrect
, y desea probar que tiene la clase correct
. Si expect(element.getAttribute(''class'')).toMatch(''correct'')
que usar expect(element.getAttribute(''class'')).toMatch(''correct'')
, eso devolverá verdadero incluso si el elemento tiene la clase incorrect
.
Mi sugerencia:
Si solo quiere aceptar coincidencias exactas, puede crear un método de ayuda para ello:
var hasClass = function (element, cls) {
return element.getAttribute(''class'').then(function (classes) {
return classes.split('' '').indexOf(cls) !== -1;
});
};
Puede usarlo así (aprovechando el hecho de que expect
que se resuelvan automáticamente las promesas en el transportador):
expect(hasClass(element(by.name(''getoffer'')), ''ngDirty'')).toBe(true);
Here un Jasmine 1.3.x personalizado toHaveClass
matcher con negación .not
compatible, además de esperar hasta 5 segundos (o lo que especifique).
Uso de muestra:
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'');
});
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;
});
}
Así es como lo hago, al menos, sin la necesidad de utilizar la función de esperar. Esta función simplemente devuelve verdadero si la clase está dentro del elemento y falso si no. Esto también usa promesas para que lo use como:
checkHasClass(''#your-element'', ''your-class'').then(function(class_found){
if (class_found) console.log("Your element has that class");
});
Editar: Me acabo de dar cuenta de que esto es esencialmente lo mismo que la respuesta superior