Nightwatch variable scope and accessing outside .element call - javascript

I have the following method in my Nightwatch test that does not work as expected:
function checkCategoryRows(browser, theOptionText, rows) {
var isGood = true;
rows.value.forEach(function (row) {
browser.elementIdText(row.ELEMENT, function (categoryText) {
if (categoryText.value != theOptionText) {
browser.verify.ok(0 == 1, categoryText.value + ' = ' + theOptionText);
isGood = false;
} else
isGood = false; //<-- Manually making sure it sets either way
})
})
browser.verify.ok(isGood == true, theOptionText + ' category is good...');
}
isGood
is always true; even if I set it manually. It appears that anything inside the browser.element(){} call is only scoped inside that call.
How do I get this to work so at the end of the for loop I can show that something was 'not good' in that particular set of rows?

Apparently, in Nightwatch, there is no 'document' or 'window' object. There is a 'browser' object that seems to be similar. Here is how I solved it:
function checkCategoryRows(browser, theOptionText, rows) {
browser.isGood = true;
rows.value.forEach(function (row) {
browser.elementIdText(row.ELEMENT, function (categoryText) {
//console.info(categoryText)
if (categoryText.value != theOptionText) {
browser.verify.ok(0 == 1, categoryText.value + ' = ' + theOptionText);
browser.isGood = false;
}
//else
// browser.isGood = false; // for testing
console.log('browser.isGood=' + browser.isGood);
})
})
browser.verify.ok(browser.isGood == true, theOptionText + ' category is good...');
}
Setting browser.isGood = true; initially made it available to the rest of the method.

Related

How can I run recursive function in cypress or find length with async await

I am running tests using Cypress.
I have an array of Litecoin addresses. I am trying to set first in the input. Then submit the form.
If the address is duplicate then a notification is displayed and submit button will be not visible. The same I want to set for the second element and so on till end of the array.
I tried recursive function:
function runTillElementFound (totalCount, currentCount, litecoin_addresses)
{
var self = this;
if (currentCount < totalCount) {
return cy.get('body').then(($body) =>
{
if ($body.find(dash_page.save_wallet_circle_btn)) {
//if there is save button then set address and submit form
cy.log('taken address: ' + litecoin_addresses[ currentCount ]);
dashact.fill_wallet(litecoin_addresses[ currentCount ]);
cy.log('address is filled');
dashact.submit_wallet(true, 0);
self.runTillElementFound(totalCount, currentCount++);
}
});
} else {
return false; //if element not present after Max count reached.
}
I try to call it:
it('Set wallet', () =>
{
cy.log('this is array length: ' + litecoin_addresses);
runTillElementFound(20, 0, litecoin_addresses);
/* comact.submit_form(true, 1);
let ltc_address = promisify(dashact.get_wallet_value());
cy.log('this is address: ' + ltc_address);
//close popup and check that it is closed:
popact.submit_payment(); */
});
However I receive undefined:
I have also tried non recursive function:
for (var i = 0; i < litecoin_addresses.length; i++) {
cy.log('taken address: ' + litecoin_addresses[ i ])
if (litecoin_addresses[ i ] == wallet_before_edit || litecoin_addresses[ i ].length == 0 || litecoin_addresses[ i ].startsWith('ltc')) {
continue;
}
else {
cy.log('this is curent i: ' + i);
dashact.fill_wallet(litecoin_addresses[ i ]);
dashact.submit_wallet(true, null);
cy.get('body').then(($body) =>
{
// synchronously query from body
// to find which element was created
if ($body.find(com_page.not_message).length) {
// error was found, do something else here
cy.log('error was found');
}
else {
cy.log('error not found');
// input was not found, do something else here
i = litecoin_addresses.length;
cy.log('current i value: ' + i);
}
})
}
However it for sure, does not work, as i inside promise has one valued but in the loop it still remains the same.
If you use a specific array in your test code, you can easily get the length of the array by using the .lenght and access its elements by using the for loop.

eventOverlap is supposed to allow another event into a day that has a different tag

Here's the code:
eventOverlap: function(stillEvent, movingEvent) {
console.log("I am overlapping something");
if (stillEvent.tags == ""|| movingEvent.tags == "") {
console.log("One of the events have no tag");
return true;
} else {
console.log("SE = " + stillEvent.tags + " ME = " + movingEvent.tags);
$.each( stillEvent.tags.split(','), function( key, value ) {
var index = $.inArray( value, movingEvent.tags.split(',') );
var result = "";
if( index == -1 ) {
console.log("Found no similar tags");
result =true;
} else {
console.log("Similar tags at index:"+index);
result =false;
}
return result;
});
}
}
What I'm trying to do, is when I drag an event above another day that contains an event as well, this function will compare the tags string they have (by splitting them) and looking at each individually.
If one or both of the events have no tags, it is allowed into the day.
Else, each of these are supposed to be compared per element
say X=["1","2","3"] and Y=["3","4","5"] both of these has 3, therefore it should return false. But if it finds no similar elements, like X = ["1"] and Y = ["2"] it should return true. False will disable eventOverlap, and true otherwise.
So I checked with the console. What's happening here is that even if it knows that there are no similar tags, eventOverlap is still not enabled. Only when the other event has no tag.
Might it be a flaw on my logic? Thanks!
What about something like this?
...
eventOverlap: function(stillEvent, movingEvent) {
if (stillEvent.tags == ""|| movingEvent.tags == "") {
console.log("One of the events have no tag");
return true;
} else {
for (i = 0; i<stillEvents.tags.length; i++){
for(j = 0;j<movingEvent.tags.length,j++) {
if (movingEvent.tags[j] == stillEvents.tags[i]){
return false;
}
}
}
return true;
}
}
...

Firebase array always return false

I'm creating an application with ionic and firebase. I'm trying to verify if a element exists in my array, and if it does, I need to return true, else I need to return false. The problem is, it always return false, even if the item exists in firebase. Can you please tell me what is going wrong with following code?
Here's my service:
function IsReserved(id){
var ref = fb.child('/reserved/').orderByChild('product').equalTo(id);
ref.once("value").then(function(snapshot){
snapshot.forEach(function(data){
if(data.val().user === $rootScope.currentUser.$id){
console.log(data.val().user + " * " + $rootScope.currentUser.$id);
return true;
}
});
});
return false;
}
Here is my controller:
function Reservar(produto) {
if(!$rootScope.cart){
$rootScope.cart = [];
$rootScope.fprice = 0;
}
var user=$rootScope.currentUser;
var res = vm.IsReserved(produto.$id);
console.log(res);
if(res){
console.log("já reservado");
return;
}
Here is my firebase strucure:
-reserved:
--KdS2cH1OJ5MhKAV6Yio:
-product: "product1"
-user: "W30BB1RMg1XhNo9og9cMo4Gpr4S2"
Your code won't work because firebase works asynchronously.
You should use a callback function as a parameter, something like this:
function IsReserved(id, callback){
var ref = fb.child('/reserved/').orderByChild('product').equalTo(id);
ref.once("value").then(function(snapshot){
snapshot.forEach(function(data){
if(data.val().user === $rootScope.currentUser.$id){
console.log(data.val().user + " * " + $rootScope.currentUser.$id);
callback(true);
return;
}
});
});
return false; //-- This will always be executed before the code inside the .then, that's why your function always returns false
}
And on you controller, something like this:
function Reservar(produto)
{
if(!$rootScope.cart){
$rootScope.cart = [];
$rootScope.fprice = 0;
}
var user=$rootScope.currentUser;
vm.IsReserved(produto.$id, function(response){
console.log(response);
if(response){
console.log("já reservado");
}
});
}
Could you understand?

Error handler is working in every situation

Handler is working with my code but it shouldn't alert when the the value is not null. I got an alert in either situations. I don't know what went wrong .
var data = {};
var deviceId = ["asdfa23", "asdfa32"]
data[deviceId] = "asdfasdf";
try {
if(data[deviceId].value == null)
throw "this is null"
}
catch(err) {
alert(err)
}
Just replace your in your if statements :
(data[deviceId].value == null)
by :
(data[deviceId] == null)
You don't have value field, it is not an object.
You can do .some() method to check a condition over an array.
var data = {};
var deviceId = "thermoment123";
data[deviceId] = ["er213", "er243"];
for(var device in data){
try{
var bool = data[deviceId].some(function(elm){
return elm
? true
: false
});
if (!bool){
var errorSensor = "The sensor "+ deviceId + " has no data"
throw errorSensor;
}
} catch(err){
alert(err)
}
}
You assign an array to data[deviceId].
The array has two properties 0 and 1 (along with all the inherited properties like forEach and length).
value is not a property of normal arrays and you haven't added one.
you have a couple syntax errors in your code:
var data = {};
var deviceId = "thermoment123";
data[deviceId] = ["er213", "er243"];
for (var device in data) {
try {
if (data[deviceId] == null) { //removed the .value
var errorSensor = "The sensor " + data[deviceId] + " has no data"; //added ';'
throw errorSensor;
} //close brackets that start at from if statement
} catch (err) {
alert(err); //added ';'
}
}

Why isn't this working javascript?

I am using this to detect errors on my form...
var error = false;
if (val === '') {
error = true;
}
if (error = true) {
$('#joinForm .submit').click(function(event) {
event.preventDefault();
});
}
Simple really but not working, am I missing something stupid? variable error is default false.
If an error is found it is true.
If error is found to be true it prevents the form being submitted?
var error = false;
if (val === '') { // <<< This checks type first, then value
// An empty '' variable is not type-equivalent
// to a (boolean) false value
error = true;
}
if (error = true) { // <<< You're setting a variable here, which means
// means that you're testing if the variable
// assignment itself is successful, you'll get
// a true result in most cases, and except with
// things like while loops, you shouldn't use this
// form.
// Maybe you want == (falsy)? Or === (type-checked)?
$('#joinForm .submit').click(function(event) {
event.preventDefault();
});
}
You should do the checking in the submit event handler:
$('#joinForm').submit(function(event) {
var error = false;
if (val === '') {
error = true;
}
if (error) {
event.preventDefault();
}
});

Categories