Reputation: 332
I am trying to build a script using nightmarejs that would be able to click a button over and over again , like that youtube button that's at the bottom of the comments section which loads older comments each time you press it (example: youtube.com/watch?v=pZISJqJbQuU&list=RDpZISJqJbQuU#t=3) and stop when there is no more button to be clicked.
I have tried calling evaluate , only for end() method to be called first and cancel the process . I have tried using setTimeout , setInterval , then(), converting the loop into a recursion. Everytime either evaluate() will complete it's job but not quit (just hanging) or quit before completing it's job because of a race condition with end().
Is there any experienced nightmarejs user out there ?
function youtube_button_clicker(group) {
var nightmare = Nightmare({
show: true
});
nightmare
.goto(url)
.inject('js', 'jquery-3.1.0.js')
.then(
() => nightmare.
evaluate(function() {
for (i=0;i>LEN;i++)
{ setTimeout(() => { $(button_element).click() }, i * 2000); }
return "done"
}))
.catch(function (error) {
console.error('Search failed:', error);
});
}
Remove the .end() method and it hangs, put the .end() back again and it skips the process - quits early. What can I do ?
Upvotes: 1
Views: 542
Reputation: 2468
.evaluate()
functions cannot be asynchronous, at least not until #819 (or something like it) is included. In other words, evaluating with setTimeout()
is not going to work. Additionally, I don't think that would be a particularly good route to go in this case, even if it were possible out of the box.
As an aside, you might want go give this example in nightmare-examples
a read. It gives a brief primer on chaining multiple operations and looping.
You could probably get away with a recursive function, but you'll have to be careful to enforce a stop condition. (You may also want to have a look at #625, the action is scrolling but the problem is similar.) From the hip, I think something like this might get you close:
var iterations = 0;
var reclick = function(nm) {
return nm
.click('#some-button')
.wait('#element-you-check-for')
.then(function() {
// you could also use `.visible()` or something before this `.then()`
// depends on your use case
// here, I'm using the number of iterations
if (iterations++ < 10) {
return reclick(nm);
}
return;
});
}
nightmare
.goto('http://my-domain.tld')
.then(function() {
return reclick(nightmare);
})
.then(function(){
// ... other actions
})
Upvotes: 1