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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Use CasperJS’s evaluate() method. It crosses from your CasperJS script into the opened page, where window, document, page globals and DOM nodes exist. Call the page function inside that callback, pass arguments after the callback, and return a simple value if the outer script needs the result.

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

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

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

casper.run();

The callback is evaluated in the remote page context, much like entering JavaScript in that page’s browser console. Your CasperJS code remains outside the page. That context boundary explains both the correct pattern and most errors.

The context boundary: CasperJS script versus the page

CasperJS runs an outer automation script. The site you opened runs in a separate page context. A function declared by the site, such as window.greet, is therefore not an ordinary local function in your CasperJS file. Calling greet('Ada') directly from the outer script will fail unless you defined a separate function there.

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

evaluate() is the gate between those environments. Code inside its callback can use the page’s window, document, globals and DOM. Code outside it can use the CasperJS API, logging and flow control. Values must cross the gate as arguments or return values.

Prerequisites and correct timing

  • Create a CasperJS instance and start or open the URL that contains the function.
  • Run the evaluation only after the relevant page has loaded and its scripts have defined the function.
  • Use the CasperJS and PhantomJS versions available in your environment. CasperJS 1.1.0-DEV documentation is legacy material, so confirm that your runtime can load the target site before relying on it for modern applications.

If a function is installed by a later navigation, an AJAX application boot sequence or a user action, put the evaluation after that event rather than immediately after start().

Three ways to execute a page function

Method When to use it What it does
evaluate() The page is already at the right state in the current step. Runs a callback in the current page context immediately within that CasperJS step.
thenEvaluate() You want a queued step in a fluent sequence. Adds page-context evaluation to the CasperJS step queue.
thenOpenAndEvaluate() You want to navigate and evaluate the newly opened page. Combines opening a location with evaluation against its remote DOM.

Call immediately with evaluate()

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

casper.start('https://example.com/', function () {
    var title = this.evaluate(function () {
        return document.title;
    });

    this.echo('Title: ' + title);
});

casper.run();

Use this.evaluate() inside a CasperJS step so that this is the Casper instance. The callback itself is not executed with the Casper instance as its this value; it is page code.

Queue the call with thenEvaluate()

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

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

thenEvaluate() is convenient when the call belongs in a sequence of navigation, clicks, waits and assertions. If you need the returned value for a later outer step, assign it in a callback step instead:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
var casper = require('casper').create();
var greeting;

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

Open a URL and evaluate with thenOpenAndEvaluate()

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

casper.start()
    .thenOpenAndEvaluate('https://example.com/', function (selector) {
        var node = document.querySelector(selector);
        return node ? node.textContent : null;
    }, '#headline')
    .then(function () {
        this.echo('Remote text: ' + this.result);
    })
    .run();

The combined method is useful when the URL itself is part of the step sequence. Check your installed CasperJS API for the exact result handling available in your version; the essential rule remains that the callback executes against the page opened by that step.

Passing arguments and returning results

Pass arguments after the callback, in positional order. The callback receives them as parameters:

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

casper.start('https://example.com/', function () {
    var value = this.evaluate(function (selector, replacement) {
        var element = document.querySelector(selector);
        if (!element) {
            return { ok: false, error: 'Element not found' };
        }
        element.textContent = replacement;
        return { ok: true, text: element.textContent };
    }, '#status', 'Ready');

    this.echo(JSON.stringify(value));
});

casper.run();

Keep the crossing data simple and serializable: strings, numbers, booleans, arrays and plain objects are the safest choices. Do not expect a DOM node, a page closure or the Casper instance to become a usable object in the other environment. Return a property such as textContent, an attribute, a boolean or a plain object instead.

The positional form is preferable to the old object-style argument habit. Legacy object arguments remain for backward compatibility in the API documentation, but the documented positional form avoids cases where the older form fails.

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

Calling globals, methods and DOM-backed functions

Calling a page-defined global

casper.start('https://example.com/', function () {
    var answer = this.evaluate(function (a, b) {
        if (typeof window.addNumbers !== 'function') {
            return { ok: false, error: 'addNumbers is unavailable' };
        }
        return { ok: true, value: window.addNumbers(a, b) };
    }, 2, 3);

    this.echo(JSON.stringify(answer));
});

Testing typeof window.someFunction gives you a useful diagnostic instead of an opaque “not a function” failure. If the function is namespaced, use its full path, such as window.app.utils.refresh(), inside the callback.

Using the DOM before invoking a function

casper.start('https://example.com/', function () {
    this.evaluate(function () {
        var button = document.querySelector('[data-action="refresh"]');
        if (button) {
            button.click();
        }
    });
});

Everything that touches document belongs inside evaluated code. For straightforward extraction, CasperJS conveniences such as fetchText() and getElementInfo() may be simpler than writing an evaluation callback, but they do not change the context rule.

Using __utils__ and seeing page-side messages

CasperJS can inject a client-side utility object named __utils__. Its helpers are available inside evaluated page code. For example:

casper.start('https://example.com/', function () {
    this.evaluate(function () {
        __utils__.echo('Message from the page context');
    });
});

casper.run();

__utils__ is optional. Ordinary page functions need only evaluate(). CasperJS also documents a bookmarklet that exposes __utils__ in a regular browser console; that is a browser-console convenience, not a replacement for evaluating code in your CasperJS run.

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

Why “browser console” can be misleading

The phrase means “execute code as if you were using the console for the opened page.” CasperJS does not turn its command prompt into Chrome or Firefox DevTools, and it does not make page globals local to your script. The practical equivalent is a closure passed to evaluate(), with explicit arguments crossing into the page.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common failures and fixes

Symptom Likely cause Fix
ReferenceError or “function is not defined” The call was made outside the page context, or the page has not defined the function yet. Move the call inside evaluate() or thenEvaluate(); place it after the correct navigation or page initialization step.
“Cannot read property … of null” A selector returned no element. Check the selector in the evaluated callback, return a diagnostic object, and wait for the page state that creates the element.
An outer variable is undefined in the callback Local CasperJS variables are not automatically page globals. Pass the value after the callback and declare a matching callback parameter.
A return value is always empty or unusable The callback returned nothing, or returned a non-serializable object such as a DOM node. Use an explicit return and convert the result to text, a primitive, an array or a plain object.
The function runs before it exists The evaluation step was queued before the relevant script or navigation completed. Move to a later step, use an appropriate wait, or evaluate after opening the target URL with thenOpenAndEvaluate().
The old argument syntax behaves inconsistently Legacy object-style arguments are being used. Use positional arguments after the callback, as in evaluate(function (value) { ... }, value).

Reliability, performance and security considerations

  • Make calls deterministic: check that globals and selectors exist and return structured status data for assertions.
  • Keep callbacks small: perform page-local work in one callback, then return only the data the outer script needs. Large transfers and complex object graphs are harder to serialize.
  • Respect navigation: a page change replaces the remote DOM and can remove functions installed by the previous document. Re-evaluate after navigation.
  • Do not trust page data: treat returned strings as untrusted input when logging, storing or passing them to another system.
  • Limit side effects: a function invoked through evaluate() can mutate the page just as it can from a browser console. Use a test account and avoid destructive actions in production pages.
  • Account for legacy engines: CasperJS/PhantomJS-era behavior may differ from current Chromium browsers, especially on sites using modern JavaScript, TLS, module loading or bot detection. A successful callback in an old runtime is not proof of compatibility with every current site.

Or skip the browser setup

If your actual goal is to obtain a clean image or PDF of a page rather than execute a page function, ScreenshotNeo makes the capture a single HTTP request. It accepts the cookie or consent banner like a visitor, removes more than 60 known consent platforms plus newsletter popups and chat widgets before the shot, and bills only clean captures. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed; the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers.

For a complete parameter list, see the ScreenshotNeo documentation. This cURL call saves a WebP image:

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

The service also has an MCP server for Claude, Cursor and other MCP clients, with take_screenshot, get_page_info and capture_pdf tools. One thousand screenshots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to get an API key.

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

Frequently Asked Questions

Can I call a function that is defined inside a JavaScript module?

Only if the page exposes it through an accessible global or another DOM-triggerable interface. A module-local function is not automatically a property of window, so expose a deliberate entry point or invoke the feature through the page’s public UI.

How can I tell whether the callback ran in the page?

Return a simple marker such as { ok: true, title: document.title } and print it from the outer CasperJS step. If document is unavailable, the code was not evaluated in the remote page context.

Does evaluate() open developer tools?

No. It executes JavaScript in the opened document’s context without opening a graphical DevTools console.

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.

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.