> For the complete documentation index, see [llms.txt](https://docs.thousandeyes.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/development-guide/robust-transaction-scripts/optimizing-transaction-scripts.md).

# Optimizing and Troubleshooting Transaction Scripts

This article describes some basic optimizations, some of which are also important for troubleshooting during script development.

## Use Markers for Timing

You can use start and stop markers to capture the timing for any user workflow or business transaction, for example Add to Cart, Submit Order, or a custom back-end query. The workflow timing will be called out on the **Waterfall** tab for the transaction test view.

You can use custom marker timings as a metric when configuring transaction test alert rules. Marker timing is also available as a metric on many of the Cloud & Enterprise Agents dashboard widgets as well.

Markers are useful in several ways:

* Identify where a script section starts and stops.
* Identify when a process takes longer than expected.
* By comparing a marker against an Agent’s waterfall, you can also verify that the page finished loading before the `marker.stop()` entry.

Steps to add markers to your script:

1. Include "markers" in the **thousandeyes** import line at the top of the script:

   ```
   import { driver, browser, credentials, markers } from 'thousandeyes';
   ```
2. Within your script, add markers to delineate between the beginning and ending of each step. For example, to add timings for displaying a particular navigation menu:

   ```
   markers.start('Navigate menu');
   markers.stop('Navigate menu');
   ```

The Selenium webdriver used by the ThousandEyes browser synthetics testing feature waits for a page or frame load if a `click()` triggers a new page load. This can result in inaccurate marker timings unless you start the new marker before the click, as shown below:

```
// More accurate markers at click()
async function markerClick (selector, markerStop, markerStart) {
    await driver.findElement(selector);
    await markers.stop (markerStop);
    await markers.start(markerStart);
    await click(selector);
}
```

## Use Screenshots for Troubleshooting

Although screenshots add time to a script, they are also useful troubleshooting tools during script development. Generally, you can use screenshots when you need to know the state of the screen before an action takes place. Note that interim screenshots aren’t always saved if the test completes successfully as described in [Screenshots in Transaction Test Views](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/getting-started/screenshots-in-transaction-test-views).

Consider the following guidelines:

* Do not include screenshots within markers, because that skews the marker timings.
* Use screenshots selectively in the final script, because they add time.
* Pair markers, screenshots, and **Console Logs** for the same selected run, agent, and round when you troubleshoot a transaction test. Use markers to bracket the script step, screenshots to confirm the page state, and a small number of intentional console messages to capture sanitized runtime context.
* Avoid logging credentials, tokens, session identifiers, personal data, or repeated status messages that do not help isolate the failure. For the full transaction test troubleshooting workflow, see [Using the Transaction Test View](https://docs.thousandeyes.com/product-documentation/internet-and-wan-monitoring/viewing-data/using-the-transaction-test-view#troubleshooting-with-the-transaction-test-view).

Add this line to your script to take a screenshot:

```
await driver.takeScreenshot();
```

## Choose the Right Element Identifiers

If you see issues in the test view on the ThousandEyes platform saying “unable to locate target element”, try using your browser’s developer tools to look for the XPath of the target element. (XPath is a query language for selecting nodes from an XML document.)

Below is example of a simple use of XPath:

```
await click(By.xpath(`//*[@id="l_id1:impPost1"]/div/div[3]/input[1]`));
```

## Use Sleeps and Human Delay Sparingly

All steps involving web page elements have implicit waiting conditions. For example, `click(By.xpath('//button'))` implicitly waits for the `//button` element to be present. If you need to check for a specific element state, you can use `until()`. See [Waiting for Events](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/transaction-scripting-reference#waiting-for-events) for examples.

Increasing the human delay, and adding sleeps, are great tools during troubleshooting but they pose two issues: skewed marker times, and increased time to completion. The advice is to use these tools during script development, and then remove them or do other fine-tuning before deploying the ThousandEyes transaction test in a production environment.

Once you have a script working using the JavaScript `sleep()` function, you can shave off time by minimizing sleeps, and by keeping the human delay at 550ms, which is the inherent or default behavior. Any additional waits should be done via conditionals or sleeps. Note that you do not need to import `sleep()` in order to use it.

If you must pause in order to wait for an element to be visible, or to be in a specific state, you can import `until()` from the selenium-webdriver library, and then use a 'wait for condition' command similar to the ones described in [Waiting for Events](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/transaction-scripting-reference#waiting-for-events).

You can import `until()` from selenium-webdriver as follows:

```
import { By, Key, until } from 'selenium-webdriver';
```

Below is an example of a simple “wait until” condition, which is making sure that the specified page element has actually been rendered and can be interacted with, vs. when it first appears in the Document Object Model (DOM).

```
await driver.wait(until.titleIs('webdriver - Google Search'), 1000);
```

An example of adding a sleep for 1 second is as follows:

```
await driver.sleep(1000);
```

Remember to use sleeps mainly during development, but only sparingly in production.
