I have a successful test
browser
.url(testURL)
.waitForElementPresent('body', 1000)
.verify.attributeContains('someElement', 'someAttribute', 'foo')
But for my purposes it is acceptable for 'someAttribute' to contain 'foo' OR 'bar'. I'm wondering how I can write this kind of test so that no test failures are reported by Nightwatch.
You can test if attribute contains 'foo' OR 'bar' in two steps:
get the attribute value with getAttribute() or attribute()
match a regex against the value
With getAttribute(), use regex.test():
browser.getAttribute('someElement', 'someAttribute', function(result) {
this.assert.value(/foo|bar/.test(result.value), true);
};
With attribute(), use matches() assertion:
browser.expect.element('someElement').to.have.attribute('someAttribute')
.which.matches(/foo|bar/);
use .elements() and obtain the length of element result to avoid fail message.
.elements('css selector','someElement[yourattribute="foo"]',function(result){
if(result.value.length>0){ //element exists
console.log('somelement is here')
}
else{
console.log('not here')
}
});
Related
I have a scenario, where i need to put Assertion on an element's text which could be true OR pass the test case, if the any 1 value is present out of many.
Let say, an element can contain multiple status' : 'Open', 'Create', 'In Progress' any of these could be true.
How can i implement this scenario and Assert with OR logical operator or any other way?
cy.get('element').should('have.text', 'Open' | 'Create')
It sounds like a one-of assertion, something like the following:
cy.get('element')
.invoke('text')
.should('be.oneOf', ['Open', 'Create'])
To do it you need to extract the text before the assertion.
For reference see chaijs oneOf
Asserts that the target is a member of the given array list. However, it’s often best to assert that the target is equal to its expected value.
These both Worked:
cy.get('element')
.invoke('text')
.should('satisfy', (text) => text === 'option1' || text === 'option2')
OR
cy.get('element')
.invoke('text')
.should('be.oneOf', ['option1', 'option2']);
Wodens answer is most valuable if you wish to make an assertion and have the test fail if one of them doesn't exist
However, if you want to check the text of the element that is visible and do separate things based on which one is available:
cy
.get('element')
.filter(':visible')
.invoke('text')
.then((text) => {
if(text.includes('Open')){
// Things that only occur when Open is present
} else if (text.includes('Create')){
// Things that only occur when Create is present
} else if (text.includes('In Progress')){
// Things that only occur when In Progress is present
} else {
// Things that happen when the options are exhausted
}
});
I want to assert that a component contains a string without caring about the string case.
For example, I want
cy.get('#label').should('contain.text', 'integrator');
to pass even if the label contains "Integrator."
What is the best way I can make this assertion?
You can also use cy.contains() with a regular expression
cy.contains('#label', /integrator/i) // should is implied in this command
or as an option
cy.contains('#label', 'integrator', {matchCase:false})
With should() you get retry of the expect()
cy.get('#label')
.should($el => {
expect($el.text().toLowerCase()).to.eq('integrator') // exact
// or
expect($el.text().toLowerCase()).to.contain('integrator') // partial
})
What you need is Regular expressions.
You can use the match assertion:
cy.get('#label')
.invoke('text')
.should('match', /integrator/i) //i = case sensitive
You can do like this as well:
cy.get('#label').then(($ele) => {
expect($ele.text().toLowerCase()).to.contain('integrator')
})
is there a way to call waitForElementPresent in nightwatch without erroring out if the element is not there?
Right now, if you pass in false as the third parameter, you still see an error. Ideally, I would like a function that waits for an element, and returns if it didn't find the element.
you can do it :
Browser.waitForElementPresent('#element',3000,false, function(result){
If(result.value === true){
// test if element present
}else{
// test if element not present
}
})
Since the day one, i did this and the problem with this code is nightwatch would count a failed test as a passed test,as you see above code handle both result value.
So i recommend let the nightwatch return error itself, write difference function for difference value.
Suppose I have
spyOn($cookieStore,'get').and.returnValue('abc');
This is too general for my use case. Anytime we call
$cookieStore.get('someValue') --> returns 'abc'
$cookieStore.get('anotherValue') --> returns 'abc'
I want to setup a spyOn so I get different returns based on the argument:
$cookieStore.get('someValue') --> returns 'someabc'
$cookieStore.get('anotherValue') --> returns 'anotherabc'
Any suggestions?
You can use callFake:
spyOn($cookieStore,'get').and.callFake(function(arg) {
if (arg === 'someValue'){
return 'someabc';
} else if(arg === 'anotherValue') {
return 'anotherabc';
}
});
To the ones using versions 3 and above of jasmine, you can achieve this by using a syntax similar to sinon stubs:
spyOn(componentInstance, 'myFunction')
.withArgs(myArg1).and.returnValue(myReturnObj1)
.withArgs(myArg2).and.returnValue(myReturnObj2);
details in: https://jasmine.github.io/api/edge/Spy#withArgs
One possible solution is use the expect().toHaveBeenCalledWith() to check the parameters, example:
spyOn($cookieStore,'get').and.returnValue('abc');
$cookieStore.get('someValue') --> returns 'abc';
expect($cookieStore.get).toHaveBeenCalledWith('someValue');
$cookieStore.get('anotherValue') --> returns 'abc'
expect($cookieStore.get).toHaveBeenCalledWith('anotherValue');
Another way of achieving the same result would be.... (Ideal when you are writing unit tests without using a testbed)
declare the spy in root describe block
const storageServiceSpy = jasmine.createSpyObj('StorageService',['getItem']);
and inject this spy in the place of original service in the constructor
service = new StoragePage(storageServiceSpy)
and inside the it() block...
storageServiceSpy.getItem.withArgs('data').and.callFake(() => {})
I'd like to use CasperJS to evaluate a variable equals a certain value.
I simplified my exemple as much as I could that way:
var testDate = "24/03/14";
casper.test.begin('TEST', 1, function suite(test) {
casper.start('http://www.google.com/', function() {
this.test.assertEval(function() {
return testDate == "24/03/14";
}, "testDate is 24/03/14" );
});
casper.run(function() {
this.test.done();
});
});
I don't know why it fails, here is what I get in my console:
Test file: tests.js
#TEST
FAIL testDate is 24/03/14
# type: assertEval
# file: tests.js:7
# code: }, "testDate is 24/03/14" );
# subject: null
# fn: undefined
# params: undefined
FAIL 1 test executed in 2.896s, 0 passed, 1 failed, 0 dubious, 0 skipped.
Details for the 1 failed test:
In tests.js:7
TEST
assertEval: testDate is 24/03/14
Any idea ?
UPDATE
I realised my simplified example was faulty, it didn't represent what I really needed.
Actually, what I want to achieve is to test if a variable from the current page DOM context equals a local variable.
As per manual Asserteval:
Asserts that a code evaluation in remote DOM strictly resolves to a boolean true:
your testdate variable is local to the casperjs script and is not accessible in the remote dom. You would have to inject it to the window like described here.
Ok found the answer myself.
To test if a variable from the current page DOM context equals a local variable, I realised I could use a simple assertEvalEquals():
test.assertEvalEquals(function() {
return variableFromPageDomContext;
}, localVariable);
Likewise, when testing if a variable from the current page DOM context matches a RegExp pattern, we have to use evaluate() to get the variable from the DOM as the first parameter of an assertMatch():
test.assertMatch(this.evaluate(function() {
return variableFromPageDomContext;
}), RegExpPattern);
Hope that can help.
As #Surreal answers its possible to use the assertEvalEquals() passing the function and the expected value.
However the original question wants to pass a variable from casperjs context to assertEval() function, you can simply do it as follows, passing to assertEval() three arguments: the function which receive the value, a message for the assert and the value:
var varPassToEval = 'someValue';
test.assertEval(
function(varFromCasperContext){
return varFromPageDomContext === varFromCasperContext;
},
'Assert Eval to test',
varPassToEval
);
With the above example probably is clear to use assertEvalEquals() however could be useful for more complex cases, for example imagine that you want to check if a text appears in a some <li> inside <ul> in DOM which it's dynamic and can change but you don't know at first where your text is... for this case you can use:
var somePartOfText = 'blue';
test.assertEval(
function(varFromCasperContext){
return document.getElementsByTagName("ul")[0].textContent.indexOf(varFromCasperContext) != -1;
},
'Assert Eval to test',
somePartOfText
);
Hope it helps,