Selenium-webdriver wait(condition, timeout) timeout is ignored - javascript

I am attempting to wait for a success toast after editing an item in a table.
It appears the selenium is not taking into account the timeout time that I have provided to the wait function.
What am I missing? I shouldn't have to provide a ridiculously high number(which only works sometimes) to make this work when I only need ~7 seconds.
driver.wait(until.elementIsVisible(driver.findElement(By.className('alert-success'))), 999999999999999999999999999999999999999999999999).then(function () {
return driver.findElement(By.className('table-striped')).getText().then(function (text) {
expect(tableState).toNotEqual(text);
done();
driver.quit();
});
});

Related

Async/Await: subsequent awaits are not waiting for ones prior to finish before running themselves

I am having a problem with my Protractor script.
When i run each of the awaits i need them to have completed before the next one has started. Some of the functions being run take time to complete (upto 60 seconds). The problem is not the awaits seem to be waiting for the previous one to complete before running themselves. Does anyone have any ideas? Much appreciated!
*The webpage used in the code is a dummy one as the one i am using is locally held and wouldn't show for anyone trying this
describe('Verify title in the webpage', function () {
// ############### Environment Setup ####################
it('Verify title of Test webpage', async function (done) {
await fileLink.invokeJetState("Idle", browser.params.printerName) // ("Desired JetState", Printer IP/Name)
await fileLink.invokeError("7", browser.params.printerName) // ("Index_No", Printer IP/Name)
await browser.get('https://www.webpagetest.org/'); //Launch Browser and load webpage
// Verify correct data is held within title bar
await expect(browser.getTitle()).toBe('Application 1');
done();
await fileLink.invokeReboot(browser.params.printerName)
});
});

While loop not executing inside callback

Inside the catch of a promise
.catch((message) => {
console.log(message)
var newUrl = url
chrome.tabs.create({url: newUrl}, function(response) {
console.log(response.status)
status = 'loading'
while (status == 'loading') {
setTimeout(function() {
console.log(response.status)
status = response.status
}, 3000)
}
})
})
I'm trying to write the catch in the way that it will open up a new page, wait for it to finish loading, then grab the new cookies
I feel like Im taking crazy pills as this seems super straight forward. However its never printing out response.status
I want it to wait to check response.status every 3 seconds and once the page has loaded it will end the loop.
What am I doing wrong?
The way You've wrote it you've made an infinite loop, which will put tons of setTimeouts on browser's event queue.
setTimeout also put's code there, but it puts it with "3sec plus" delay note.
In practice you tell your browser - set infinite timeouts for me, and after it's finished, please do console.log after 3 seconds. This won't happen.
You should probably use setInterval instead

Code halts unexpectedly on backend of my wix site

I wrote an asynchronous function which is supposed to check if a given url returns a '200' from a get and otherwise wait a few seconds to try again a limited number of times. The code works just fine when I run it in my computer using node but when I transfer it to backend it only checks for the site once and then immediately stops when receiving an error. What am I doing wrong?
async function wait(url,delay=10000,attp=3){
let t0 = new Date(Date.now());
let attempts = 0;
console.log('starting...');
async function check(){
if(attempts<attp){
console.log('ATTEMPTS: ',attempts);
return await request.get(url).on('error',
async function(err){
console.log('ERROR: ',err);
attempts+=1;
return await setTimeout(()=>{check()},delay);
}).on('response',
async function(response){
if(response.statusCode===200){
let t1 = new Date(Date.now());
wixData.insert('pagSeguroTimeStats', { 'time': (t1 - t0) / 1000. });
return '200';
}else{
attempts+=1;
console.log('not 200');
return await setTimeout(()=>{check()},delay);
}
});
}else{
return '404';
}
}
return check();
}
Seems that there is a limit to how much time a backend function can run. From the Wix Code forum, it seems that the limit is 14 seconds, although this doesn't look like an official number from Wix.
The 14 second limit only applies to web functions.
Time
Wix allows web modules called from the frontend, HTTP functions, and router hooks to run for up to 14 seconds. This limitation applies to both free and premium sites. Any of these methods that take longer than 14 seconds receives a 504 response code. Note that after 14 seconds the code might still execute, but the connection to the client is closed so the results do not appear in the frontend. This error message appears in your log:
/backend/.js(w)/ timed out because it exceeded the maximum execution time.
I've got a .js function that just stop, and I get no error or anything.

Chrome requests taking much longer than other browser requests

One of the users of my website noticed a severe delay in loading times for a infinite scroll function which makes a GET request to my API. While testing it, it only seems to happen in Chrome and Opera, the other browsers provide a near seamless experience.
So after some testing, I decided to do some time logging (sorry I can't post inline images on here due to too little reputation):
These logs are from the same calls, and as you can see chrome takes about 3000ms while firefox is around 90ms. IE/Edge have the same performance as Firefox.
To further the mystery, the network tab seems to report the ms correctly (around 100ms with some exceptions, but nowhere near 3000ms):
Now for the actual code I'm calling:
loadMore() {
console.time('start load');
//some extra stuff here
console.timeEnd('start load');
console.time('state api call');
this.$APIService.getCards(this.deckId, this.page, this.searchInput, this.lastId)
.then(res => {
console.timeEnd('actual call');
console.timeEnd('state api call');
//some more stuff here
})
}
the "this.$APIService.getCards" call is just my apihandler:
getCards (deckId, page, searchInput,lastId) {
console.time('actual call');
return Api().get('cards?deckId=' + deckId + '&lastId='+lastId + '&search='+ searchInput)
},
where "Api()" is my axios object:
axios.create({
withCredentials: true,
baseURL: baseURL
})
Another thing to note is that my server only receives the request after the delay, so that would correspond with the network tabs stating it only takes around 100ms.
So, does anyone have any idea of why this might be happening? As you can see I literally have the time logs start right before the request and end them right upon receiving a result. Why would there be a delay before executing the call only in Chrome?
Thanks in advance!

long-poll jQuery.ajax() fails to callback after phone sleeps?

My web app uses the 'long poll' method to keep up to date with the latest data from my server. The server only responds when it has new data, which can be many minutes apart. (It is a heating control system where you only see updates when room temperatures changes or somebody changes the settings).
var version = "0";
function updater() {
$.ajax({
type: "POST",
url: "/listen",
data: version,
success: function (data) {
version = handleUpdates(data);
updater();
},
error: function () {
setTimeout(updater, 1000);
}
});
}
It works fine on desktop browsers and on phones except in one case. I have found that on android phones with Chrome something odd happens after the phone has gone to sleep for more then about 10 minutes. The post request seems to be dropped, which I guess is reasonable since the phone is asleep. In the Chrome debugger's Network tab, the Status Text of the POST request says (canceled).
The problem is when I wake the phone up while the request is cancelled, neither the success() or error() function is called, and my web app never gets updated. $.ajax() has broken its promise to call me back.
The problem only happens on some devices. I have been able to do a few ad-hoc tests by borrowing devices off friends. So far I have only seen the problem on android phones. But not is the phone is connected to a charger. I have not seen it on any tablets, on apple devices or windows PCs.
I have tried adding a timeout to the ajax settings:
timeout: 120 * 1000,
This helps because the error() function is eventually called up to 2 minutes after the wake up. But I'd like the user to see updates within 1 or 2 seconds. I don't want to make the timeout so short because it would create unnecessary server traffic.
I have also tried detecting whether device is asleep by looking for lateness in a one second setInterval as described in Can any desktop browsers detect when the computer resumes from sleep?.
When I detect the wake up, I abort() the post and start another. This helps in most cases. But it turns out to be unreliable. Sometimes time events seem to keep ticking normally during sleep and the post request gets cancelled anyway. And it it does not feel like a reliable fix.
I am using latest version of jQuery: (2.1.2) and Chrome (47).
I not sure this will work or not, I cannot test it now but give it a try
$(window).focus(function() {
updater();
});
I've had problems in the past with JavaScript calls getting suspended when the phone goes to sleep. The solution I ended up with was to use window.setInterval() which seems to suspend, but come back to life when the phone is woken up.
So I would recommend setting an interval which cancels the call every so often and reinitiates it. This might help it survive through a phone sleep.
Something roughly like:
var myCall = $.ajax({...});
Window.setInterval (refreshCall(), 10000);
function refreshCall (){
myCall.abort ();
myCall = $.ajax({...});
}
How about a higher-level watcher function like this:
var restartTimer = null;
function updater(){
$.ajax({
type: "POST",
url: "/listen",
data: version,
success: function (data) {
version = handleUpdates(data);
clearTimeout(restartTimer);
updater();
},
error: function () {
clearTimeout(restartTimer);
setTimeout(updater, 1000);
}
});
}
// Kick it when the phone wakes up.
$(window).focus(function(){
restartTimer = setTimeout(function(){
initializeAll();
}, 6000);
updater();
});
You know that the $(window).focus will fire when the phone wakes up, so you try updater() as Almis suggests, but with a fail-safe timer. If updater fires (on laptops or iOS), the timer is canceled and all is well, but if updater is dead, the fail-safe timer fires in 6 seconds and reboots your entire app by calling initializeAll().
How about a setInterval, that stores the time it was called, then compares the last time it was called to the current time - if your interval is 10 seconds and the time passed since the last run was 5 minutes, you can assume you've just woken from sleep? Then abort the current ajax call, and restart it.
The best answer is "don't do that". You're having the server wait to respond while it tracks for changes at the server side. Just have the server respond and have the jQuery ping on an interval. You can include lastchanged or haschanged if you want to prevent actually refreshing when there's no status change, but if the server is doing the same work either way, just let it respond and wait for the next poll.
setInterval(function () {
$.post({"/listen", version, function (data) {
if(data.haschanged)
version = handleUpdates(data);
}).fail(function () {
// any error correction on failed call
});
}, 1000);

Categories

Resources