> 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/transaction-scripting-tips.md).

# Transaction Scripting Tips and Tricks

This article is a continuation of [Optimizing and Troubleshooting Transaction Scripts](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/development-guide/robust-transaction-scripts/optimizing-transaction-scripts).

## Choosing Better Element Selectors

The most common optimization for transaction scripting involves making your CSS element selectors simpler and more reliable. Below are some examples of selectors and how to improve them.

To clarify, an element is any item on the page, and a CSS selector is a method of describing said element. The CSS selector could then be a name, category, ID, iframe, etc.

### Avoid Dynamically Generated IDs

Some auto-generated selectors will identify an element using an ID that appears to be unique and stable, but that is actually dynamically generated. For example:

```
await driver.findElement(By.css('#tabZoneId278'));
```

The element ID `tabZoneId278` is very likely to be a dynamic element ID that was generated by a UI framework, so it may not persist over time.

### Avoid Overly Specific Selectors

In other cases, you'll find the auto-generated selectors will resort to selectors that are overly specific and too reliant on element hierarchies, like the example below:

```
await driver.findElement(By.Css('#nm-streaming-container > div.streamingNewsContainer.nsw-subscription-type-realTime.defaultTemplates.news-hideInsight.news-hideSentiment.header-auto-resize.news-hideHeader.news-results-item-insight2-shrinked.news-results-item-sentiment-shrinked.nsw-four-columns > div.news-results.news-list-table.newsSection.streamingTopSection > div');
```

The above example includes three parent-child levels, separated by >, with additional CSS class selectors with a . separator. If possible, find a selector that is simpler while still uniquely identifying the element on the page.

### Working With Single Page Apps

Single page applications (SPAs) often present a challenge. A single-page app dynamically rewrites the current web page as the user interacts with the page, instead of loading a new page every time the user clicks on something. Because the nature of the page is dynamic, generating a transaction script with static/specific selectors to target a specific page element will not consistently work. It is better to target a class, or use something like regex that can select something in a more fluid manner. Here's an example of clicking on the "call" button in Microsoft Teams:

```
await click(By.css('#app-bar-20c3440d-c67e-4420-9f80-0e50c39693df .icons-filled'));
```

The problems with the above are that these elements are dynamic and the long strings of random-seeming characters are non-intuitive, and non-human readable​​. This type of random string often indicates a randomly generated selector. The same selector could be different every time that same user connected, or could be different for different device types. General Selector Guidelines Here are some general guidelines and suggestions for selecting robust and simple CSS selectors:

* For CSS selectors, avoid relying on parent-child selectors as much as possible. This example shows a selector with no children, which is the preferred way to do it:

  ```
  await click(By.css('#positions-securityGroup-Equity-collapsed > .sch'));
  ```
* Don't use sleeps. If you find yourself using `await driver.sleep(3000)` because “it just seems to make things work”, review [Use Sleeps and Human Delay Sparingly ](https://docs.thousandeyes.com/product-documentation/browser-synthetics/transaction-tests/development-guide/robust-transaction-scripts/optimizing-transaction-scripts/#use-sleeps-and-human-delay-sparingly)and look for ways to get rid of the sleep if you can.

### Criteria for Choosing the Right Element Selector

Let’s say you know which page element you want to focus on, and what to avoid doing, but you’re unsure of what to do next. Here’s a simple guideline: Look for an attribute, ID, or class that seems unlikely to change over time.

#### Unique Human-Readable ID

Find a unique, human-readable ID. For example you might find something like `<button id="continue_button">`. You could use that ID in your transaction script as follows:

```
await click(By.css(`#continue_button`));
```

#### Unique Class Names

Look for unique class names. For the element that you want to use, is it the only element on the page that uses that class name? If so, you can do something similar to the following:

```
await click(By.css(".chat-window-textbox"));
```

#### Unique Attribute Values

Look for unique attribute values, like `<button aria-label="Dismiss">`. This assumes that there’s only one Dismiss button on the page.

```
await click(By.css(`[aria-label="Dismiss"]`));
```

#### Unique Combination of Type, Class, Value

Use combinations of element type, class type, and/or attribute values to achieve element uniqueness. For example, the line below identifies an element named `<textBox name="loginfmt">` by element type and attribute value. The element must be a text box, and it must have the name **loginfmt**.

```
await click(By.css("textBox[name='loginfmt']"));
```

#### XPath Search

Another approach is to use XPath to search for an element by its text value. For example, to identify a button named **Continue** that’s implemented as `<button>Continue</button>`, do the following:

```
// Click on a `button` element with text 'Continue'
await click(By.xpath(`//button[text()="Continue"]`));
```

#### Unique Sibling-Ancestor Combination

Finding unique selectors based on combinations of siblings or ancestors can often yield simple and reliable results.

```
await click(By.css(`[data-resin-target="primarybutton"] > .btn-content > span`));
```
