Cypress | Cant change variable inside each loop - variables

OK, So, I have this code:
Cypress.Commands.add ('MethodName', (argument) => {
var Fails = 0
cy.get('anything').each(Id => {
if (blablabla) {
Fails += 1
cy.log("Inside the each: " + Fails) //prints 1
}
})
cy.log("Outside the each: " + Fails) //prints 0
});
I want to test each item and if a condition is wrong, I want to add 1 to the variable "Fails".
Then, in the end, if Fails is 0, then there are no errors, and I want it to log the message "NO FAILS". The problem is , even if the variable changes to 1 inside the EACH, when its outside, it comes back to 0.
This is so frustrating to me, because Im used to write C# code and in C#, that would work, since the declaration of the variable is outside the each.
What do you guys suggest?

JavaScript runs asynchronously which means that your codes doesn't run in sequence. So what's happening in your case is Outside the each: is executing first and after that Inside the each: is being executed. To make sure that Outside each runs after inside each, you have to use then().
Cypress.Commands.add('MethodName', (argument) => {
var Fails = 0
cy.get('anything').each(Id => {
if (blablabla) {
Fails += 1
cy.log("Inside the each: " + Fails)
}
}).then(() => {
cy.log("Outside the each: " + Fails)
})
})

Related

Vue.js Nuxt - cannot access Array (value evaluated upon first expanding error)

I have the following function which gives me an array called URLs
const storageRef = this.$fire.storage.ref().child(fileName)
try {
const snapshot = storageRef.put(element).then((snapshot) => {
snapshot.ref.getDownloadURL().then((url) => {
urls.push(url)
})
})
console.log('File uploaded.')
} catch (e) {
console.log(e.message)
}
});
console.log(urls)
console.log("about to run enter time with imageurls length " + urls.length)
When I run console.log(URLs) initially I do see the array like the following
[]
0: "testvalue"
length: 1
__proto__: Array(0)
However, there is a small information icon stating
This value was evaluated upon first expanding. The value may have changed since.
Because of this, when I try to get the length of URLs, I get zero, meaning the value is being updated.
Does anyone know what's happening? I am using Vue.JS/Nuxt.

"Parsing error: Unexpected token )" with bot

I'm making a discord bot and I'm trying to make a timer that every second it edits the message to time + 1 second like a real clock (Like 0:00). I'm a noob at this. This is my script:
const Discord = require("discord.js");
exports.run = async(bot, message, args) => {
let timerMessage = await message.channel.send('0');
for (i = 0, 10000000000) {
setTimeout(function() {
timerMessage.edit(timerMessage + 1);
}, 1000);
}
}
module.exports.help = {
name: "timer"
}
I have an error and it says: "Parsing error: Unexpected token )"
I would really appreciate it if you would help me with my problem, Thanks!
(Btw I'm using it in Glitch on Google Chrome)
It says that there's an unexpected token ) because you wrote your loop like this:
for (i = 0, 10000000000) {...}
You forgot to add the third argument (usually i++). Also, if you want it to run 10000000000 times you should write a comparison:
for (let i = 0; i < 10000000000; i++) {...}
I see what you're trying to achieve, but I would do it in a simpler way, using setInterval() instead of setTimeout().
setInterval(() => {
timerMessage.edit(timerMessage + 1);
}, 1000);
You seem to be missing a right parenthesis after the setTimeout function. I am not entirely familiar with what you are doing, but I would try something like this :
const Discord = require("discord.js");
exports.run = async (bot, message, args) => {
let timerMessage = await message.channel.send('0');
for (i = 0, 10000000000) {
setTimeout(function()) {
timerMessage.edit(timerMessage + 1);
}, 1000);
}
}
module.exports.help = {
name: "timer";
}
Although this should (maybe) replace the missing parenthesis in your code, it seems to have many other issues. For example, your for loop does not make much sense. Normally a for loop would look something like this (to repeat a certain number of times in java) :
for (int i = 0; i < 10; i++) {
System.out.println(i);
} // will print numbers 0-9, repeat 10 times
The whole chunk of code with the setTimeout bit seems to be messed up... It would help to have a little more context on what you are trying to do / some commenting in your code.
If you are trying to get into coding, I'd recommend something much more basic or some tutorials. CodingTrain has great coding videos on youtube and you will learn a ton no matter what language you go with. Hope this helped...

Generate dynamic tests based on a parameter in Nightwatch

I'm using NightwatchJS to automate the test on our reporting website.
This is my actual code:
module.exports = {
'#tags': ['Report 1','base','full'],
'Report 1' : function (browser) {
checkAnalisi(browser, 'report1', 1, 2015, '767.507')
}
};
function checkAnalisi(browser, nomeAnalisi, scheda, year, risultatoAtteso){
return browser
.url('https://example.com/Wizard?analisi=' + nomeAnalisi)
.waitForElementVisible('body', 5000)
.selectScheda(scheda-1) //Seleziona la scheda (0-based)
.selectPromptValue('Year', year)
.selectRappresentazione('Table')
.waitForElementVisible('table', 5000, true)
.assert.containsText('table tr:last-child td:last-child', risultatoAtteso)
.end();
}
I made some helper commands to select different things in the page:
.selectScheda(scheda-1)
.selectPromptValue('Year', year)
.selectRappresentazione('Table')
selectPromptValue wants a prompt name and the value to set it in the page.
For now the function only sets the year parameter but in my reports I also have different parameters.
What I want to do is to pass an object to the checkAnalisi function to dynamically generate test. For example if I want to set different prompt values I want to pass something like [['Year', 2015],['Another prompt','another value']] and the checkAnalisi function should add 2 .selectPromptValue steps with the respective values.
Is it possible to cycle an input array in my function to add more steps?
Actually I was able to solve this easily directly in my selectPromptValue custom command.
I simply added the new parameter to the checkAnalisi function like this (promptValues is the new parameter):
function checkAnalisi(browser, nomeAnalisi, scheda, promptValues, risultatoAtteso){
return browser
.url('https://example.com/Wizard?analisi=' + nomeAnalisi)
.waitForElementVisible('body', 5000)
.selectScheda(scheda-1) //Seleziona la scheda (0-based)
.selectPromptValue(promptValues)
.selectRappresentazione('Table')
.waitForElementVisible('table', 5000, true)
.assert.containsText('table tr:last-child td:last-child', risultatoAtteso)
.end();
}
I then modified the selectPromptValue.js custom command like this:
exports.command = function(v) {
for(var i=0; i<v.length; i++){
this.execute('$("#"+$("label:visible:contains(\'' + v[i][0] + '\')").attr("for")).val("' + v[i][1] + '")');
}
return this;
};

Selecting multiple files in a dart based chrome app

I was playing around with Google Dart and chrome apps. I tried to select a single file: No problem here!
The code looks like this and prints the filename.
Future<ChooseEntryResult> res = chrome.fileSystem.chooseEntry(new ChooseEntryOptions());
res.then((ChooseEntryResult entry) {
print("entries: " + entry.entry.name);
});
But selecting multiple files does not work. In a native chrome app I can do:
chrome.fileSystem.chooseEntry({"acceptsMultiple":true}, function(entries) {
console.log(entries);
});
Even this code fails (I only added acceptsMultiple: false)
Future<ChooseEntryResult> res = chrome.fileSystem.chooseEntry(new ChooseEntryOptions(acceptsMultiple: false));
res.then((ChooseEntryResult entry) {
print("entries: " + entry.entry.name);
});
I would expect this to work:
Future<ChooseEntryResult> res = chrome.fileSystem.chooseEntry(new ChooseEntryOptions(acceptsMultiple: true));
res.then((ChooseEntryResult entry) {
print("entries: " + entry.entries);
});
But whenever I select multiple files the "entry" and "entries" fields of ChooseEntryResult gives me null. Has anyone managed to get this working?

Using Rx to Geocode an address in Bing Maps

I am learning to use the Rx extensions for a Silverlight 4 app I am working on. I created a sample app to nail down the process and I cannot get it to return anything.
Here is the main code:
private IObservable<Location> GetGPSCoordinates(string Address1)
{
var gsc = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService") as IGeocodeService;
Location returnLocation = new Location();
GeocodeResponse gcResp = new GeocodeResponse();
GeocodeRequest gcr = new GeocodeRequest();
gcr.Credentials = new Credentials();
gcr.Credentials.ApplicationId = APP_ID2;
gcr.Query = Address1;
var myFunc = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(gsc.BeginGeocode, gsc.EndGeocode);
gcResp = myFunc(gcr) as GeocodeResponse;
if (gcResp.Results.Count > 0 && gcResp.Results[0].Locations.Count > 0)
{
returnLocation = gcResp.Results[0].Locations[0];
}
return returnLocation as IObservable<Location>;
}
gcResp comes back as null. Any thoughts or suggestions would be greatly appreciated.
The observable source you are subscribing to is asynchronous, so you can't access the result immediately after subscribing. You need to access the result in the subscription.
Better yet, don't subscribe at all and simply compose the response:
private IObservable<Location> GetGPSCoordinates(string Address1)
{
IGeocodeService gsc =
new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
Location returnLocation = new Location();
GeocodeResponse gcResp = new GeocodeResponse();
GeocodeRequest gcr = new GeocodeRequest();
gcr.Credentials = new Credentials();
gcr.Credentials.ApplicationId = APP_ID2;
gcr.Query = Address1;
var factory = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(
gsc.BeginGeocode, gsc.EndGeocode);
return factory(gcr)
.Where(response => response.Results.Count > 0 &&
response.Results[0].Locations.Count > 0)
.Select(response => response.Results[0].Locations[0]);
}
If you only need the first valid value (the location of the address is unlikely to change), then add a .Take(1) between the Where and Select.
Edit: If you want to specifically handle the address not being found, you can either return results and have the consumer deal with it or you can return an Exception and provide an OnError handler when subscribing. If you're thinking of doing the latter, you would use SelectMany:
return factory(gcr)
.SelectMany(response => (response.Results.Count > 0 &&
response.Results[0].Locations.Count > 0)
? Observable.Return(response.Results[0].Locations[0])
: Observable.Throw<Location>(new AddressNotFoundException())
);
If you expand out the type of myFunc you'll see that it is Func<GeocodeRequest, IObservable<GeocodeResponse>>.
Func<GeocodeRequest, IObservable<GeocodeResponse>> myFunc =
Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>
(gsc.BeginGeocode, gsc.EndGeocode);
So when you call myFunc(gcr) you have an IObservable<GeocodeResponse> and not a GeocodeResponse. Your code myFunc(gcr) as GeocodeResponse returns null because the cast is invalid.
What you need to do is either get the last value of the observable or just do a subscribe. Calling .Last() will block. If you call .Subscribe(...) your response will come thru on the call back thread.
Try this:
gcResp = myFunc(gcr).Last();
Let me know how you go.
Richard (and others),
So I have the code returning the location and I have the calling code subscribing. Here is (hopefully) the final issue. When I call GetGPSCoordinates, the next statement gets executed immediately without waiting for the subscribe to finish. Here's an example in a button OnClick event handler.
Location newLoc = new Location();
GetGPSCoordinates(this.Input.Text).ObserveOnDispatcher().Subscribe(x =>
{
if (x.Results.Count > 0 && x.Results[0].Locations.Count > 0)
{
newLoc = x.Results[0].Locations[0];
Output.Text = "Latitude: " + newLoc.Latitude.ToString() +
", Longtude: " + newLoc.Longitude.ToString();
}
else
{
Output.Text = "Invalid address";
}
});
Output.Text = " Outside of subscribe --- Latitude: " + newLoc.Latitude.ToString() +
", Longtude: " + newLoc.Longitude.ToString();
The Output.Text assignment that takes place outside of Subscribe executes before the Subscribe has finished and displays zeros and then the one inside the subscribe displays the new location info.
The purpose of this process is to get location info that will then be saved in a database record and I am processing multiple addresses sequentially in a Foreach loop. I chose Rx Extensions as a solution to avoid the problem of the async callback as a coding trap. But it seems I have exchanged one trap for another.
Thoughts, comments, suggestions?