Search code examples
javascriptdomclickwaitcasperjs

In CasperJS how do you make wait work?


Why this wait in 'clickOldShares' is not working? Even when I put inside a evaluate the the wait doesn't work. I believe that is a small detail with references, but I'm out of ideas right now.

function clickOldShares(){
  console.log("Waiting for Old Shares");
  element = document.querySelector("#pagelet_scrolling_pager > div > div > a"); 
  console.log("ELEMENT: " + element);
  if(element){
    console.log('click and waiting...');
    element.click();
    console.log('clicked!'+ element);

    //THIS WAIT IS NOT WORKING!!!! I DON'T KNOW WHY!!!!
    this.wait(2000,clickOldShares);

  }
  else {
    console.log("done!");
  }
  return element;
};

//Initializing Casper
casper.start('https://www.facebook.com/', function() {
   console.log("Entering on Facebook"); 
});

//Remote Message Handler - now I can see what happen inside evaluates
casper.on('remote.message', function(msg) {
  this.echo(msg);
})


//Facebook login
casper.then(function(){
    console.log("Login using username and password");
    this.evaluate(function(){
      document.getElementById("email").value = 'foo@bar';
      document.getElementById("pass").value = 'somepass';
      document.getElementById("login_form").submit();
      })
    if(this.exists('#u_0_2 > div:nth-child(1) > div:nth-child(1) > div > a > span')){
      console.log("Login ok!");
    }
    else {
      console.log("Login not ok!");
      casper.exit();
    }
});


    casper.thenOpen("https://www.facebook.com/shares/view?id=1063249230414580" ,function(){
    console.log("Open post with object-id");
  });


casper.thenClick("#pagelet_scrolling_pager > div > div > a",function(){ 
      this.wait(2000,function(){ this.evaluate(clickOldShares)});
 });

Solution

  • this inside of the page context (inside of casper.evaluate()) refers to window and not casper. You can't use casper inside of the page context.

    You need to move stuff around:

    function clickOldShares(){
        var elementAvailable = this.evaluate(function(){
          console.log("Waiting for Old Shares");
          element = document.querySelector("#pagelet_scrolling_pager > div > div > a"); 
          console.log("ELEMENT: " + element);
          if(element){
            console.log('click and waiting...');
            element.click();
            console.log('clicked!'+ element);
          }
          return !!element;
        });
        if (elementAvailable) {
          this.wait(2000, clickOldShares);
        }
    };
    

    and use it like this:

    casper.thenClick("#pagelet_scrolling_pager > div > div > a",function(){ 
        this.wait(2000, clickOldShares);
    });
    

    Since DOM nodes cannot be passed out, you need some kind of representation that a DOM element existed in the page context. This can be easily achieved by coercing the DOM node to boolean with !element and then negating it immediately !!element to check if element is "truthy".