The execute javascript interaction step allows you to execute arbitrary JavaScript or TypeScript code as part of your test flow. This is useful for performing custom logic, calculations, or interacting with APIs that are not directly accessible through other test steps.
'execute javascript' interaction option in a test step

'execute javascript' interaction option in a test step, 05/2025

If the executed javascript throws an exception or prints an error to stderr, the execute javascript step fails.

Sandbox or browser execution

The code can run in 2 different contexts:
  1. Sandbox: The code runs in a secure, isolated environment and cannot access the Playwright runtime or browser context directly. This restriction is in place for security and stability reasons.
  2. Browser: The code runs in the browser context and can access browser context directly. This is useful for performing custom on your application like setting cookies, etc.

Sandbox isolation and limitations

  • No direct access to Playwright or browser context: Your script cannot interact with page elements, cookies, or the DOM directly.
  • Resource limits:
    • Runtime: Scripts are limited in execution time to prevent infinite loops and slow tests.
    • Memory: Scripts have a capped memory allocation.
    • Network: Outbound network requests may be restricted or rate-limited.

Browser isolation and limitations

  • Code will be executed in the browser context and can access browser context directly. e.g. window, document, etc.
  • You can access existing dynamic variables (set by previous steps) directly through the context object: context.variableName
  • You can set dynamic variables by returning an object from your function: return { variableName: value }
'execute javascript' interaction option executed in browser context

'execute javascript' interaction option executed in browser context, 07/2025

Using dynamic variables in browser context

When running JavaScript in the browser context, you have two special features:
  1. Access existing dynamic variables through the context object:
// Example: Using existing dynamic variables in browser context

// Access a dynamic variable set by a previous step
const documentId = context.documentId;

// Use it in your browser code
console.log(`Working with document: ${documentId}`);

// You can access any dynamic variable set by previous steps
if (context.userName) {
  document.getElementById("greeting").textContent =
    `Hello, ${context.userName}!`;
}
  1. Set dynamic variables by returning an object from your function:
// Example: Setting dynamic variables by returning an object

// Extract values from the page
const pageTitle = document.title;
const userCount = document.querySelectorAll(".user-item").length;

// Return an object to set multiple dynamic variables at once
return {
  pageTitle: pageTitle,
  userCount: userCount,
  currentUrl: window.location.href,
};
After this script runs, you can reference the dynamic variables in later steps using $$pageTitle, $$userCount, and $$currentUrl.

Setting dynamic variables in sandbox context

You can create dynamic variables by calling a helper function setDynamicVariable. These variables can be used in subsequent steps of your test. For example, if your script creates a new document in your application and receives a document ID in the response, you can expose this ID as a dynamic variable:
// Example: Creating a document and exporting its ID as a dynamic variable
async function main() {
  const response = await fetch("https://api.example.com/documents", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ title: "My Document" }),
  });
  if (!response.ok) {
    throw new Error(`Response status: ${response.status}`);
  }
  const data = await response.json();
  setDynamicVariable("documentId", data.id);
}

main();
After this script runs, you can reference the dynamic variable in later steps using $$documentId.
Example: Exporting a dynamic variable from a javascript step

Example: Exporting a dynamic variable from a JavaScript step

Using dynamic variables in javascript steps

In sandbox context

In the sandbox environment, you can use dynamic variables in your test steps by using the getDynamicVariable function. For example, if you have a dynamic variable $$documentId, you can use it in a step like this:
// Example: Using a dynamic variable in a step
async function main() {
  const response = await fetch(
    "https://api.example.com/documents/" + getDynamicVariable("documentId"),
  );
  if (!response.ok) {
    throw new Error(`Response status: ${response.status}`);
  }
  const data = await response.json();
  setDynamicVariable("documentName", data.name);
}

main();

Using secret template variables

You can use secret template variables in your test steps by using the decrypt function. For example, if you have a secret template variable API_KEY, you can use it in a step like this:
  1. Create a secret template variable in the Environment variables.
Example: Using a secret template variable in a javascript step

Example: Using a secret template variable in a javascript step

  1. Use the decrypt function to decrypt the secret template variable in your test step.
// Example: Using a secret template variable in a step
async function main() {
  const response = await fetch("https://api.example.com/tasks/", {
    headers: {
      "x-api-key": decrypt("$API_KEY"),
    },
  });
  if (!response.ok) {
    throw new Error(`Response status: ${response.status}`);
  }
  const tasks = await response.json();
  setDynamicVariable("noOfTasks", tasks.length);
}

main();
With getDynamicVariable you can access all dynamic variables from previous javascript or “extract value” steps.

Helper functions

The following helper functions are available:
  • setDynamicVariable(name, value): Set a dynamic variable.
  • getDynamicVariable(name): Get a dynamic variable.
  • decrypt(name): Decrypt a template variable.

Logging

You can log messages to the console using the console.log function.
// Example: Logging a message
async function main() {
  console.log("Hello, world!");
}

main();
You will see the log in the test trace.
Example: Logging a message

Example: Logging a message

Error handling

You can throw errors using the throw statement or output with console.error will be considered as an error and the step will fail.
// Example: make the step fail
async function main() {
  console.error("Something went wrong!");
  // or
  throw new Error("Something went wrong!");
}

main();

Best practices

  1. Keep scripts short and efficient to avoid hitting resource limits.
  2. Validate outputs before logging dynamic variables to prevent errors in later steps.
  3. Avoid sensitive operations since scripts run in an isolated environment with limited permissions.
  4. Use dynamic variables to pass data between steps and make your tests more flexible.
By leveraging the execute javascript step, you can extend your tests with custom logic while maintaining security and reproducibility.