mstottrop
mstottrop

Reputation: 589

Count every elements inside an iFrame with CasperJS

I am searching for a way to count every element inside a div. The problem is, the div is inside an iFrame.

casper.then(function() {
        this.echo(this.evaluate(function() {
             __utils__.getElementByXPath('//*[@id="main-frame"]', __utils__.findAll('#design-scrollbox-0')).length;
        }));
    });

What I trying to do above is:

I'd love if you could point my in the right direction. Sadly, I cannot use a jQuery version > 1.7, so jQuery.contents is not an option.

Upvotes: 3

Views: 2612

Answers (3)

Adeel Imran
Adeel Imran

Reputation: 13966

You can always do this $('ul').children().length this will tell you all the children element in the selector. Hope it helps.

Upvotes: 0

Artjom B.
Artjom B.

Reputation: 61922

You could inject some other jQuery version, but you don't need it, since CasperJS provides a convenient way of changing into the iframe and doing stuff in its context. casper.withFrame is a shortcut for the PhantomJS functions page.switchToChildFrame and page.switchToParentFrame. It creates a new step from the callback where further steps can be nested.

There are certainly different types to count elements, but probably the easiest is using

casper.getElementsInfo(selector).length

This is the function for printing the number of links I use for the proofs-of-concept:

function printLinks(){
    try{
        this.echo("elements: " + this.getElementsInfo("a").length);
    } catch(e) {
        this.echo("CAUGHT: " + e);
    }
}

Proof-of-concept for iframes:

casper.start("http://jsfiddle.net/anjw2gnr/1/")
    .then(printLinks)
    .withFrame(0, printLinks)
    //.withFrame(1, printLinks)
    .then(function() {
        console.log('Done', this.getCurrentUrl());
    })
    .run();

prints

elements: 33
elements: 2

Proof-of-concept for frames:

casper.start("https://docs.oracle.com/javase/7/docs/api/index.html")
    .then(printLinks)
    .withFrame(0, printLinks)
    .withFrame(1, printLinks)
    .then(function() {
        console.log('Done', this.getCurrentUrl());
    })
    .run();

prints

CAUGHT: CasperError: Cannot get information from a: no elements found.
elements: 210
elements: 4024

So, if you want to count elements, but don't want to use a try-catch block, this is better:

casper.exists(selector) ? casper.getElementsInfo(selector).length : 0

Upvotes: 4

Tom Ritsema
Tom Ritsema

Reputation: 468

You can use Casper's switchToChildFrame (see for example this link) to get 'into' the iframe.

(untested):

casper.then(function() {
    // switch the context to first child frame
    this.page.switchToChildFrame(0);

    // ... execute casper commands in iframe context

    // and switch back to parent frame if you need to
    this.page.switchToParentFrame();

    // ... execute casper commands in parent page context
});

To count elements you could try (untested also):

casper.then(function() {
    var amount_elements = this.evaluate(function() {
        var elements = document.querySelectorAll("#design-scrollbox-0");
        // you can store in the DOM:
        window.amount_elements = elements.length;
        // and return the amount
        return elements.length;
    });
});
// the object stored in the DOM can be used later on:
casper.then(function() {
    var amount_elements = this.evaluate(function() {
        return window.amount_elements;
    });
});

Upvotes: 2

Related Questions