0

I have the following problem. I have this structure of HTML code:

<p class="description">
    lorem ipsum, bla bla bla 
    <a href="# onclick="somemethod(id)">click</a>
</p>
<p class="description">
    lorem ipsum, bla bla bla
</p>
<p class="description">
    lorem ipsum, bla bla bla 
    <a href="# onclick="somemethod(id)">click</a>
</p>

Now I need to click via CasperJS on every "a" in paragraphs with class 'description'.

I try this:

while (selector = document.querySelector('p.description a')) {
    casper.then(function () {
        this.click(selector);
        console.log('click');
    })
}

but it doesn't work.

Are there any possibilities how to do this?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
XWizard
  • 319
  • 6
  • 17

1 Answers1

0

You have two problems.

  • You cannot use document and casper at the same time, because document is only available inside of the page context (casper.evaluate()), but casper is not available in the page context.
  • You need to iterate over the clickable elements either fully in the page context or fully outside.

CSS selectors

If all <p> elements have the same parent and there are no other elements in between, then you can simply use CSS selectors to achieve this:

casper.then(function(){
    var numberOfElements = this.getElementsInfo("p.description").length;
    for(var i = 1; i <= numberOfElements; i++) {
        this.click("p:nth-child("+i+") a");
    }
});

Note that it's not possible to select :nth-child based on the class, so this also assumes that no <p> elements are there without the "description" class.

XPath expressions

It's possible to make this much more robust, by using XPath expressions, because they are much more expressive.

var x = require("casper").selectXPath;
...
casper.then(function(){
    var numberOfElements = this.getElementsInfo("p.description").length;
    for(var i = 1; i <= numberOfElements; i++) {
        this.click(x("(//p[contains(@class,'description')])["+i+"])/a"));
    }
});

where (//p[contains(@class,'description')])["+i+"]) means that a NodeList (//p[contains(@class,'description')]) of p elements is built which all contain "description" as part of their "class" attribute. Then e.g. (nodeList)[3]) selects the third element from that list.


If you want to iterate inside of the page context, then you need to use a click function inside of the page context.

Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222