Reputation: 1638
I have a automated script written in javascript, the task it should accomplish is to click on Get Tasks
button, which triggers ajax call and results of the call are displayed in table, the next step is to check the table, if there is a task, script accepts it by clicking on Accept
button, else, script clicks on Get Tasks
button.
Task seems simple so I wrote following script:
function clickGetTasksButton() {
return new Promise(resolve => {
document.getElementsByClassName("get-tasks-btn").click();
resolve();
});
}
function waitForSpinner() {
return new Promise((resolve) => {
let spinInterval = setInterval(() => {
let spinner = document.querySelector('.spinner');
if (!spinner) {
console.log("Spinner is gone... ");
clearInterval(spinInterval);
resolve(document.getElementsByClassName("task-card").length > 0)
}
}, 50)
});
}
function driver() {
clickGetTasksButton().then(() => {
waitForSpinner().then((result) => {
//Script should either accept task or repeat the whole process
});
});
}
I am struggling with adding following logic:
if there is Accept
button, then click on it, else click on Get Tasks
button and repeat.
I thought of using recursions, but I am afraid that at some point it will throw stack overflow exception.
Upvotes: 0
Views: 32
Reputation: 708206
You can just freely recurse from a .then()
handler. Because the stack has already completely unwound before a .then()
handler is called, there is no stack buildup when you just call driver()
again or whatever other top level function you want to call from within a .then()
handler.
For example, you can do this:
function driver() {
return clickGetTasksButton().then(() => {
waitForSpinner().then((result) => {
//Script should either accept task or repeat the whole process
if (taskWaiting) {
return processTasks();
} else {
return driver();
}
});
});
}
or flattened a bit:
function driver() {
return clickGetTasksButton().then(waitForSpinner).then(result => {
//Script should either accept task or repeat the whole process
if (taskWaiting) {
return processTasks();
} else {
return driver();
}
});
}
Also note that clickGetTasksButton
does not need to return a promise as it appears to be entirely synchronous. Also, you can't directly call .click()
on the results of document.getElementsByClassName()
. That function returns an array-like list (an HTMLCollection
object) that doesn't have a .click()
method. I don't know whether you intend to get the first DOM element in that list and call .click()
on it or if you want to loop through the list calling .click()
on each one.
And, your setInterval()
should probably use a bit longer interval than 50ms. You want to give some cycles to the webpage itself to do its job. You're kind of hammering it here 20 times per second. I'd say set it to something like 200
. And, hopefully this doesn't take long to run because if this is a mobile device, this will hammer battery life and maybe even get pre-empted by the host browser (to save battery).
Upvotes: 2