Q:

Click on all 'a' elements in paragraph with specific class in CasperJS

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?

A:

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.

