Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use CasperJS’s evaluate() method to call a JavaScript function that belongs to the page you opened. The callback runs inside the page context, with access to window, document, page globals and DOM nodes—essentially as if the code had been entered in that page’s browser console.

For example, if the page defines window.greet:

var casper = require('casper').create();

casper.start('https://example.com/', function () {
    var result = this.evaluate(function (name) {
        return window.greet(name);
    }, 'Ada');

    this.echo('Result: ' + result);
});

casper.run();

The important boundary is that CasperJS’s outer script and the remote page are different JavaScript environments. Code that needs the page’s functions or DOM must cross that boundary through an evaluation callback.

Understand the CasperJS page-context boundary

CasperJS runs your automation code outside the page. The opened site runs its own code inside a browser page context. A function declared by the site, such as window.greet, is therefore not a function in the outer CasperJS scope.

evaluate() is the gate between those environments. CasperJS serializes the callback and its arguments, executes the callback in the remote page, and returns a serializable result to the outer script. The callback can use:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • window and page-defined globals
  • document and DOM APIs
  • Elements and values currently present in the opened page

It cannot automatically see local variables from the surrounding CasperJS function or the CasperJS instance itself. Pass any required values as arguments.

Call a page function immediately with evaluate()

Use this.evaluate() inside a CasperJS step when the correct page is already open and the call belongs at that exact point in the script.

var casper = require('casper').create();

casper.start('https://example.com/', function () {
    var greeting = this.evaluate(function (name) {
        // This code runs in the opened page.
        return window.greet(name);
    }, 'Ada');

    this.echo(greeting);
});

casper.run();

The callback is the place to invoke the page function. The value returned by the callback is assigned to greeting in the outer CasperJS script.

Call a function that changes the page

A callback does not have to return a value. It can call a page function that changes the DOM or another page-side state.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
casper.start('https://example.com/', function () {
    this.evaluate(function (text) {
        window.setBannerText(text);
    }, 'Captured by CasperJS');
});

After the callback, use CasperJS methods such as fetchText() or getElementInfo() to inspect the resulting page from the outer script.

Queue the call with thenEvaluate()

thenEvaluate() is the chaining form. It adds an evaluation step to CasperJS’s sequence, so the callback runs when execution reaches that step.

var casper = require('casper').create();

casper.start('https://example.com/')
    .thenEvaluate(function (name) {
        window.greet(name);
    }, 'Ada')
    .run();

Use this form when you are building a sequence of navigation, waiting, interaction and page-code steps. It is equivalent in purpose to adding a then() step and calling evaluate() inside it.

Return a value from a queued evaluation

casper.start('https://example.com/')
    .then(function () {
        var title = this.evaluate(function () {
            return document.title;
        });
        this.echo('Title: ' + title);
    })
    .run();

Only values that CasperJS can transfer across the page boundary should be returned. Prefer strings, numbers, booleans, arrays and plain data objects. Do not expect a returned DOM node to remain a live node in the outer script.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Open a URL and evaluate it with thenOpenAndEvaluate()

When the operation is simply “open this location, then run page code,” CasperJS provides thenOpenAndEvaluate() as a shortcut.

var casper = require('casper').create();

casper.start('about:blank')
    .thenOpenAndEvaluate('https://example.com/', function (expected) {
        return document.title === expected;
    }, 'Example Domain')
    .then(function () {
        this.echo('Title matched: ' + this.result);
    })
    .run();

Keep navigation and evaluation in the same logical step when the page function depends on the newly opened document.

Pass arguments instead of capturing outer variables

Arguments go after the callback. CasperJS passes them into the page-context function in the same order.

var label = 'Ada';

casper.start('https://example.com/', function () {
    var result = this.evaluate(function (name, suffix) {
        return window.greet(name) + suffix;
    }, label, '!');

    this.echo(result);
});

The page callback cannot read label merely because it exists in the outer script. Passing it explicitly makes the boundary clear and avoids a ReferenceError.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use the documented positional argument form. CasperJS keeps an older object-style argument form for backward compatibility, but its API documentation warns that it can fail in some cases.

Use the DOM exactly where the page function runs

DOM access belongs inside the evaluation callback. For example, this reads an element’s text in the page and returns a plain string:

casper.start('https://example.com/', function () {
    var text = this.evaluate(function (selector) {
        var element = document.querySelector(selector);
        return element ? element.textContent.trim() : null;
    }, '#headline');

    this.echo(text === null ? 'Not found' : text);
});

Do not write document.querySelector() directly in the outer CasperJS function; that environment is not the page’s DOM. If a page function is attached under a namespace, call the full path inside the callback, for example window.app.refresh().

Optional page-side console output

CasperJS provides an injected client-side utility object named __utils__. Its echo() helper can send a message from evaluated page code to the CasperJS console:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
casper.thenEvaluate(function () {
    __utils__.echo('Message from the page context');
});

This utility is optional. Ordinary page functions work without it. CasperJS also documents a bookmarklet that exposes __utils__ in a regular browser console.

Make sure the function exists before calling it

The examples assume the target function has been defined by the time evaluation runs. A function created by a later script, a delayed application bootstrap or a navigation that has not finished will not be available yet.

  • Place evaluate() in a step after the relevant navigation.
  • Use thenEvaluate() when the call must be ordered after earlier CasperJS steps.
  • Inside the callback, check a function before invoking it when the page is variable:
casper.thenEvaluate(function (name) {
    if (typeof window.greet !== 'function') {
        return { ok: false, reason: 'greet is not defined' };
    }
    return { ok: true, value: window.greet(name) };
}, 'Ada');

Returning a small data object makes failures explicit without trying to transfer a function or DOM object back to CasperJS.

Troubleshoot common failures

Symptom Likely cause Fix
ReferenceError: greet is not defined The call was made outside the page context, or the page has not defined the function yet. Invoke it inside evaluate() and move the step after the page’s script has loaded.
window.greet is undefined The function is not global, uses a namespace, or is created later. Call its actual namespace path, or wait until the application bootstrap has completed.
document is undefined DOM code was placed in the outer CasperJS script. Move the DOM operation into the evaluation callback.
An outer variable is undefined in the callback Closures from the CasperJS environment are not automatically imported into the page. Pass the value after the callback and declare the matching parameter.
The result is undefined The callback did not use return, or the expression produced no value. Return the value explicitly and keep it to simple serializable data.
An element lookup returns null The selector is wrong, the element is inserted later, or the page changed after navigation. Verify the selector in the page, run the evaluation at the correct step, and test for null before reading properties.
Arguments behave unpredictably with an object The legacy object-style argument form can fail in some cases. Use positional arguments after the callback.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

A complete pattern for a page function and DOM result

This script opens a page, calls a page-defined function with an argument, then reads the resulting heading. Replace the URL, function name and selector with those used by your site.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
var casper = require('casper').create({
    verbose: true,
    logLevel: 'warning'
});

casper.start('https://example.com/', function () {
    var response = this.evaluate(function (name) {
        if (typeof window.greet !== 'function') {
            return { ok: false, error: 'window.greet is unavailable' };
        }
        return { ok: true, value: window.greet(name) };
    }, 'Ada');

    if (!response || !response.ok) {
        this.die(response && response.error ? response.error : 'Page function failed');
    }

    this.echo('Function returned: ' + response.value);
});

casper.then(function () {
    var heading = this.evaluate(function () {
        var node = document.querySelector('h1');
        return node ? node.textContent.trim() : null;
    });

    this.echo('Heading: ' + (heading || '[missing]'));
});

casper.run();

CasperJS and its PhantomJS-based runtime are legacy tooling. The documented context and argument behavior still explains how these scripts are structured, but compatibility with modern browsers, sites and JavaScript runtimes depends on the versions and environment you use.

Or skip the browser setup

If your goal is a clean screenshot rather than executing a page function, ScreenshotNeo makes one HTTP request and returns a PNG, JPEG, WebP or PDF. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled.

Only clean shots are billed. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.

See the ScreenshotNeo documentation for parameters and response details.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and yearly billing provides two months free.

Create a free ScreenshotNeo account to get the 1,000 monthly screenshots without adding a card.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.