Browser Scripts

Browser scripts automate headless Chrome web browsers, for high-level testing of complex websites and web applications. They are executed by browser bots.

Real browser load testing is awesome when you want the absolute most realistic load test possible, or when protocol scripting is too tricky to work with your site.

If you’ve worked with browser automation tools like Selenium, Puppeteer, or Playwright, you already understand the concept of browser scripts. Loadster’s implementation is based on Playwright.

Steps in a Browser Script

Each step in your browser script represents an action taken by the user in their web browser. A browser script could have just a single step (loading a page) or many (navigating, clicking, typing, waiting, etc).

You can also write your own JavaScript to be executed on the page or in Loadster’s own environment.

Loadster always executes browser steps sequentially.

A navigate step is like putting a URL into the browser’s location bar. If this is the initial step in your script, it opens a fresh browser context and navigates to that location. If there were previous steps, this step leaves the current location and navigates to a new one.


A click step clicks an element on the page.

You can specify the element with a DOM selector like #id or .class or title. Longer, more complicated selectors like iframe[0] form[name='registration'] input[0] are also supported. If the element is not found on the page initially, the bot will automatically wait a while for the element to appear.

As you can imagine, click steps are useful for clicking on links or buttons, just like a human user might do.


A type step simulates typing text into an input element, such as a text field or textarea.

You can specify the input element to type into with a DOM selector like #username or form input.username. If the element is not found on the page initially, the bot will automatically wait a while for the element to appear.

Typing into fields is useful when your script needs to log in, fill out a form, and so on.


A select step can choose an option from an HTML select element on the page.

You’ll need to specify the select element with a DOM selector like #countries or form select[name=countries]. If the select element is not found on the page initially, the bot will automatically wait a while for the element to appear.

You’ll also need to specify which of the options to select from the list. The option can be specified by name, value, or index. For example, let’s say your select tag has the following HTML markup:

<select name="countries">
  <option value="CR">Costa Rica</option>
  <option value="HR">Croatia</option>
  <option value="CU">Cuba</option>

If you wanted to select Croatia, your step could specify CR to select by value, "Croatia" with double quotes to select by name, or [1] with square brackets to select by index.


To interact with a file input element, like <input type="file"/>, Browser Bots can use a Files step. Executing a files step is equivalent to clicking on the file picker, opening up the file chooser dialog, and choosing a file from your local filesystem in a real browser.

When you add a files step to your script, you get to specify what file(s) it should use. Your local file’s content becomes part of your script, so when the bots later run the script out on the Loadster engine, they have the file data and no longer need access to your local filesystem.


Browser Bots can evaluate arbitrary JavaScript inside the automated browser. This is great if you need to do special on-page automation at a more granular level than you can accomplish with individual steps. This is a big topic, and we cover a few of the possibilities in Evaluate Blocks.


A scrape step captures the entire DOM from your browser in real time. This is helpful when you are scripting, since it allows you to see what elements exist on the page.


When scripting, you can take a screenshot of the bot’s browser at any time. It’s often helpful to see what the bot is seeing.

Taking a screenshot is CPU intensive for Loadster’s engines, but has no impact on your server, so in a load test screenshot steps are skipped.


A wait step makes the bot pause temporarily, much like a real user might do when viewing a page and before navigating to the next page.

Wait steps are important for a realistic script: if you create a script without wait times, your test will probably not be representative of normal user behavior, so you might have to discount the validity of the results. Try to include realistic wait times in your script.

Wait steps can be skipped over in certain situations, like when you’re running the script as a monitor or playing the script in Fast Play mode in the script editor.

Wait For

Instead of waiting for a fixed amount of seconds, you can wait for a certain element to be in a certain state. The element can be any selector, and the states are:

  • visible - The element exists in the DOM and is not transparent, hidden, or behind another element.
  • hidden - The element exists in the DOM, but is hidden by CSS or obscured by another element.
  • attached - The element exists in the DOM.
  • detached - The element has been removed from the DOM.

If the element never achieves the desired state, the step will eventually time out.

Code Blocks

Much like the code blocks in protocol scripts, a code block in a browser script is executed in Loadster’s own environment, and not in the browser. That means they do not have direct access to the variables in the browser’s context, such as window or document. It’s usually best to use an evaluate step if you need to access those.

In code blocks, you have access to modern ECMAScript syntax like the () => {} arrow functions and const and let, as well as common parsing functionality like JSON.parse(str) and XML.parse(str).

Code blocks are very powerful, and you could in fact create an entire script in a single code block. Read more about them in the Code Blocks section.

Interestingly, you also have access to a browser object that you can use to programmatically control the very same browser that the bot is controlling in this browser script! For example:

browser.type('#username', 'sloth');
browser.type('#password', 'chunk');'form[name=login] input[type=submit]');


let documentTitle = browser.eval('document.title');

Code blocks are very powerful, and you could in fact create an entire script in a single code block. Read more about them in the Code Blocks section.

Selectors in Browser Scripts

Most of the browser steps perform an action on a specific element on the page, such as a button or text input or anchor link. The way to specify that element is with a selector.

If you’re recording with the Loadster Recorder browser extension, it will make its best attempt at finding a short and reasonable selector for every recorded interaction. You might occasionally need, or want, to update them to improve consistency and readability.

Types of Selectors

There are several types of selectors. Most of our examples feature CSS-style selectors, but you can also use other kinds in your scripts, like XPath selectors and text selectors.

CSS Selectors

If you’ve used Cascading Style Sheets, you’re familiar with the selectors. Here are a few examples of CSS selectors.

form#login button[type="submit"]
ul.vehicles li:nth-child(1) a

For a more comprehensive unofficial source on CSS selectors with lots more examples, check out CSS Selectors: The Full Reference Guide.

XPath Selectors

If you use a selector starting with // or .., it’s assumed to be an XPath selector. Browsers natively support XPath selectors with Document.evaluate(selector), so if you’re testing an XPath selector and a real browser can handle it, chances are Browser Bots will too.


For more examples of XPath selectors, you might have a look at this XPath Cheat Sheet.

Text Selectors

Often, you’ll want to specify an element based on the text it contains, without a lengthy path. This is easy. Just wrap the text in quotes, and it will be treated as a text selector, and resolve to any DOM element with text content matching the text.

"Sign me up!"    ==>    <button>Sign me up!</button>
"Documentation"  ==>    <a href="/docs/">Documentation</a>

Other Selectors

Browser Bots use Playwright for browser automation, which supports a wide range of selectors that aren’t documented here. Most, if not all, of the selectors supported by Playwright will work with Browser Bots.

Using Selectors with Inline Frames (iframes)

Ordinary selectors in browsers are limited to a single document, and won’t work if you need to resolve an element nested in an inline frame. However, Browser Bots have a special extension that allows them to resolve CSS-style selectors inside iframes.

Here are a few examples of CSS-style selectors pointing to elements in iframes that wouldn’t work normally, but do work with Browser Bots:

/* the #login element in the first iframe loaded on the page */
iframe[0] #login

/* a .cc-number field in the iframe named "payment" */
iframe[name="payment"] .cc-number

/* the input element in a frame with a name starting with __privateStripeFrame */
iframe[name^="__privateStripeFrame"] input

Recording a Browser Script

Recording a script from your web browser is often the easiest way to get started, and it works the same way for browser scripts as it does for protocol scripts.

Installing the Loadster Recorder browser extension

To record your browser traffic and make a Loadster script, you’ll need the free Loadster Recorder for Chrome or Loadster Recorder for Firefox.

After you’ve installed the extension in your browser, expand it by clicking the Loadster icon in your browser’s toolbar. You can toggle the switch to enable or disable sharing your browsing activity with Loadster.

The browser extension is open source and you can review the source code on GitHub.

Recording your browser activity

To start recording, open a new or existing browser script and hit Record. Loadster will start communicating with the Loadster Recorder browser extension.

Enter the URL of the first page you want to record.

When you hit Start Recording, Loadster will open a new browser tab to that location. Whatever you do in that browser tab will be recorded as an event and show up in the recording log. Traffic in your other browser tabs is not recorded.

Click Stop Recording when you’re finished.

Immediately after you stop the recording, you’ll see a list of all of the recorded browser actions. You can choose to exclude any actions that you don’t want in your script.

Playing Browser Scripts

Playing a script in the editor is your chance to discover and fix any errors in your script before running a load test. When you play a script in the editor, it runs with just a single bot, and this is a quick way to avoid problems ahead of time.

There are two ways to play a script: Fast Play and Play.

Fast Play and Play
Fast Play and Play

Either mode will play each step in the script sequentially, but Fast Play shortens all wait times, while Play keeps them as is. Wait times are often unnecessary when scripting, but important when running an actual load test.

As your script plays through each step, you will see flashing lights to show which step is active, and a status displayed when the step finishes.

You can stop script playback at any time by clicking on the Stop button in the toolbar.

Viewing script logs and timeline

After you play a browser script in the editor, the Logs and Timeline tabs appear, with more information about the script that you just played.

The Logs tab displays output from each step, and any errors that may have occurred.

The Timeline tab shows you screenshots from your browser after each step, so you can check if the browser state is what you expected.

If you notice a problem in the logs or timeline after script playback, you may need to dig deeper to find out what went wrong.

Troubleshooting with the script logs

As your script plays, Loadster shows you a realtime log of the steps being executed, and the results of each step.

Skimming through the logs can often give you all the information you need to know if your browser script is playing correctly, and if not, to diagnose and fix script errors.

Troubleshooting with the timeline

The browser screenshots in the timeline often show you everything you need to find and fix problems with your script.

Hovering a tile in the timeline surfaces more information about the step. Clicking it expands the tile for a full view.

Editing Browser Scripts

You probably already noticed that you can add, edit, drag, and remove steps to edit your script.

Here are a few things that work for all kinds of steps:

  • Add a step by clicking the toolbar button with the relevant step type.
  • Select a step or steps by clicking (or shift-clicking) in a neutral area of a step, such as the left handle.
  • Copy and paste steps by selecting them and using your ordinary keyboard shortcuts (control-c/v or command-c/v). You can even copy and paste them between scripts.
  • Duplicate a step by hovering and clicking on the duplicate icon on the right-hand side of the step.
  • Delete a step by hovering and clicking on the delete icon on the right-hand side of the step.
  • Disable or enable a step by hovering and clicking the toggle icon on the right-hand side of the step. Disabled steps remain in your script but are not played (like commenting them out).
  • Drag to reorder steps by clicking in a neutral area, such as the left handle, and dragging to a new position.

Aside from that, each type of step has its own attributes that you can edit separately.

Editing wait steps

Wait steps are simple. They simply make the bot pause execution of the script for a certain number of seconds.

A wait step
A wait step

To change the duration, click the number of seconds, and enter a new number.

Having realistic wait times is important. You should try to make your scripts run at the same cadence a real user would. If your wait times are unrealistic, your load test results related to the number of concurrent users will be too.

Editing browser steps

Most of the other steps, like navigate steps and click steps, allow you to specify which element to act upon with a DOM selector. Some steps, like type steps, also accept another parameter, which is the text to be entered into the field.

You can use variables and expressions to inject dynamic data into these fields. For example, load testing a login form is more realistic when each simulated user enters a different username and password.

Browser Scripting Best Practices

Fortunately, real browser load testing ensures that the behavior of the browser itself (loading resources in parallel, executing client-side JavaScript, etc) is highly realistic.

It is still important to choose the right user behavior to simulate in your script, however. Browser scripts should have realistic wait times so the cadence of page navigations and clicks is similar to that of a human user.

After all, the results of your load test are only as accurate as the assumptions going in to it.


  • Review your script to make sure it reflects real user behavior. You might want to review it with other people involved in the project.
  • Make sure the script has realistic wait times.
  • If you’re testing a web application, make sure to parameterize any request data that should be unique per user.
  • Play the script to make sure it runs properly with a single bot, before launching a load test with many bots.


  • Simply record and play back a script without taking time to understand what it does.
  • Use inaccurate wait times,or no wait times at all, because unrealistic wait times will cause unrealistic results.
  • Load test someone else’s site without their permission.

Load Testing with Browser Scripts

To run a multi-user load test with your browser script, start by creating a test scenario and then run a load test!

Browser scripts are the more expensive scripting option that Loadster offers, since running lots of real browsers is quite resource intensive. For complex web applications, there is no better way to run a load test than with real browsers. That said, if you are on a tight budget or you’re testing a simple site or API, check out Loadster’s protocol scripts for a lower-cost alternative.