Scripting Tips and Best Practices

Prev Next

Overview

This article outlines best practices and tips for creating transaction scriptsfor a robust transaction creation.

What you need:

  1. Knowledge in creating a Transaction Test in Catchpoint.
  2. Knowledge in Scripting Basics.
  3. Transaction Commands list.

Tips and Best Practices

Issues with timing actions

Avoid using pause(). It is perferable to use waitFor() actions.

waitForNoRequest()

This action tells the agent to wait for no HTTP requests on the network for the specified timeValue before continuing onto the next action, or ending the step/test. TimeValue can range from 1000-5000 ms. Thisallows the necessary requests more time to load after document complete.

Syntax:
waitForNoRequest("Time_Value")

Example:

Open("http://www.domain.com")
waitForNoRequest("5000")
setStepName("1. Homepage")

This will wait 5 seconds after the last request was severed to ensure no additional content is yet to be downloaded.

waitForElementPresent()

This action tells the agent to wait for the specified element to be present on the page before continuing onto the next action. TimeValue can range from 50-30000 ms.

Syntax:
WaitForElementPresent(Element, *timeValue)

Example:

WaitForElementPresent(//*[@id="foo"])

*timeValue is optional, default is 20,000ms.

For additional information, see:Multi Step Transaction Actions: WaitForNoRequest vs. WaitForElementPresent

Issues with dynamic links

When building a transaction with multiple steps, be aware of dynamic links within the use-case. Any link that exists now and could be replaced with a different link in a given time falls under this category. Consideran example of an ecommerce site when the use-case is "go to homepage and choose the first product from today's offer". This type of product links change on a daily basis and care shouldbe taken to select an item, which is always the first in the list.

Sample scenario is discussed below:

clickAndWait("//a[@href='/productsample1?b=discount&otracker=brandoffers']")

The above action performs a click on an anchor tag with href='/productsample1?b=discount&otracker=brandoffers' and waits for the entire page to load. When the product is replaced with a new one, this would fail as the link differs. In such scenarios, the element's static attribute needs to be considered, such aselement id or class name.
Use indexing when there are multiple elements on the page with the same class or ID, when inventory changes, or when a drop-down menu has no labels or is dynamic:

//click the second divwith an ID of 'login'
click("(//div[@id='login'])[2]")
//select the third option within the select
select("//*[@class='select']", "index=3")

Typing and Clicking issues

The first two things to try when there is an issue where a click or type command doesn't work are using typeKeys and clickMouseAt.

typeKeys()

Simulates keystroke events on the specified element, as though the value wastyped key-by-key. This is a convenient method for calling keyDown, keyUp, keyPress for every character in the specified string and is useful for dynamic UI widgets (like auto-completing combo boxes) that require explicit key events.

Syntax:
typeKeys(locator, value)

This will trigger JavaScript in most cases where type will not.

Example:

open("http://www.google.com")   typeKeys("//*[@name='q']", "Catchpoint")

clickMouse()

This command is similar to click(), but clickMouse() fires more mouse trigger events and more likely to trigger any attached JavaScript.

Syntax:
clickMouse(locator)
This will trigger JavaScript in most cases where click will not.

Example:

clickMouse("//*[@id='ele_58']")

fireEvent()

Use fireEvent() to trigger events when typeKeys() or clickMouse() don't work
Check the compatible event by going into the Developer Tools > Event Listeners.

Syntax:
fireEvent(//*[@id=''], "mousedown")

runScript()

When all else fails, use **runsScript()**to run a script on a page when Selenium commands aren't working. It creates a new "script" tag in the body. This accepts JavaScript, and jquery but mustbe included in the page to work. Multiple statements mustbe in one line.

Syntax:
runScript(script)

Example:

runScript(document.getElementById('ele_id').click();)

runScript($('#inp_id').val('string'); ('#inp_id').trigger('change'); $('#ele_id').trigger('click');)

Wrong content loading

Verifying that the loaded page is the expected one is essential. If the correct page is not verified, it is recommended to abort thetest case,investigate the cause and fix the issue(s). A few assert verbs are discussed below:

assertHttpResponseCode(): Validates the root-request's response-code. assertElementPresent(): Validates the element presence in DOM.
assertTextPresent(): Validates the pattern existence on the page.

Syntax:
assertHttpResponseCode("pattern")
assertElementPresent("locator")
assertTextPresent("pattern")

Example:

open("www.catchpoint.com")
waitForNoRequest("3000")
setStepName(1.Homepage)
assertHttpResponseCode("200")
assertElementPresent("//a[text()='PRODUCTS']")
assertTextPresent("Free Trial")

Additional Tips

If there is no button present to submit a form on a page

//this will submitthe first form on the page
submit(//form)

or

//this will simulate the user hitting the enter key
runScriptAndWait("var event = document.createEvent("HTMLEvents");   event.initEvent("keypress", true, false); event.keyCode=13;")

If asite does A/B testing use an "or" in the locator syntax

//this will use the first locatorpresent for the click command
click("//*[@id='foobar' or @alt='Bar Foo' or text()='Foo Bar' or text()='Bar Foo']")

When troubleshooting anXPath run the below command in Chrome Dev Tools console to test its accuracy

//this will execute the XPath and output the elementin the console
$x("//*[@id='foo']")

Populate AJAX calls bytriggeringkeyboard events.

fireEvent("//*[@id='one']", "focus")
typeKeys("//*[@id='one']", "two")
fireEvent("//*[@id='one']", "keydown")
fireEvent("//*[@id='one']", "keypress")
fireEvent("//*[@id='one']", "keyup")
fireEvent("//*[@id='one']", "change")
fireEvent("//*[@id='one']", "blur")

Simulating the mouse click on an element using x,ycoordinates, best for flash websites by using clickMouseAt()

clickMouseAt("//*[@id='test']", "5,5")
clickMouseAtAndWait("//*[@id='test']", "5,5")

Entering Advance dates for booking websites, maybe to choose a date 7 days in advance

type("//*[@id='depart_date']", "${timeformat("MM/DD/YYYY", 7, 7)}")
type("//*[@id='return_date']", "${timeformat("MM/DD/YYYY", 10, 10)}")

Inputing and submitting a search string from a test box

//This inputs the string "book" in the text box and submits it
typeKeysAndWait("//([@id='three'])", "book")

In a Transaction test, there may be instances where we need to split steps

Add suffix "andWait" to the seleniumcommand so that the scripting engine understands that after the current verb a new step begins.

Cross-domain iframes

Working with iframes canbe complex. This is especially true when they are cross-domain and access to elements within them is restricted. A workaround to this is to load just the iframe again in the main window. This allows access to the elements within the iframe.
Following JavaScript within the runScript action, reloads the iframe with its matching ID in the main window.

runScript(window.location.replace(document.getElementById('iframe_ID').src);)

Naming a step

setStepName(): Adds a logical step name, which helpsin troubleshooting if it is unclear what step/locator does when the particular step fails.

Syntax:
setStepName("Step_Name")

Example:

//This will set the step name as "1. Homepage"
open("http://www.google.com")
typeKeys("//*[@name='q']", "Catchpoint")
setStepName("1. Homepage")