---
title: "Testing Extjs Application With Selenium : Few Pointers"
url: https://thecancerus.com/testing-extjs-application-with-selenium-few-pointers/
date: 2010-12-12
modified: 2010-12-12
author: "ican"
description: "On a project that I am working on we needed to create few automated tests using selenium. Our frontend is completely written in Extjs. Being new to testing using selenium,..."
categories:
  - "general"
tags:
  - "automated tests"
  - "extjs"
  - "selenium"
word_count: 1109
---

# Testing Extjs Application With Selenium : Few Pointers

On a project that I am working on we needed to create few automated tests using selenium. Our frontend is completely written in Extjs.

Being new to testing using selenium, I searched the web and here are few useful advices that I found.

The most comprehensive one was by [Ates Goral](http://magnetiq.com/) on [stackoverflow](http://stackoverflow.com/questions/107314/any-suggestions-for-testing-extjs-code-in-a-browser-preferably-with-selenium).
> The biggest hurdle in testing ExtJS with Selenium is that ExtJS doesn't render standard HTML elements and the Selenium IDE will naively (and rightfully) generate commands targeted at elements that just act as decor -- superfluous elements that help ExtJS with the whole desktop-look-and-feel. Here are a few tips and tricks that I've gathered while writing automated Selenium test against an ExtJS app.
>
> ## General Tips
>
>
> ### Locating Elements
>
> When generating Selenium test cases by recording user actions with Selenium IDE on Firefox, Selenium will base the recorded actions on the ids of the HTML elements. However, for most clickable elements, ExtJS uses generated ids like "ext-gen-345" which are likely to change on a subsequent visit to the same page, even if no code changes have been made. After recording user actions for a test, there needs to be a manual effort to go through all such actions that depend on generated ids and to replace them. There are two types of replacements that can be made:
>
> ### Replacing an Id Locator with a CSS or XPath Locator
>
> CSS locators begin with "css=" and XPath locators begin with "//" (the "xpath=" prefix is optional). CSS locators are less verbose and are easier to read and should be preferred over XPath locators. However, there can be cases where XPath locators need to be used because a CSS locator simply can't cut it.
>
> ### Executing JavaScript
>
> Some elements require more than simple mouse/keyboard interactions due to the complex rendering carried out by ExtJS. For example, a Ext.form.CombBox is not really a <select> element but a text input with a detached drop-down list that's somewhere at the bottom of the document tree. In order to properly simulate a ComboBox selection, it's possible to first simulate a click on the drop-down arrow and then to click on the list that appears. However, locating these elements through CSS or XPath locators can be cumbersome. An alternative is to locate the ComoBox component itself and call methods on it to simulate the selection:
> var combo = Ext.getCmp('genderComboBox'); // returns the ComboBox components
> combo.setValue('female'); // set the value
> combo.fireEvent('select'); // because setValue() doesn't trigger the event
>
> In Selenium the runScript command can be used to perform the above operation in a more concise form:
> with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
>
>
> ### Coping with AJAX and Slow Rendering
>
> Selenium has "*AndWait" flavors for all commands for waiting for page loads when a user action results in page transitions or reloads. However, since AJAX fetches don't involve actual page loads, these commands can't be used for synchronization. The solution is to make use of visual clues like the presence/absence of an AJAX progress indicator or the appearance of rows in a grid, additional components, links etc. For example:
> Command: waitForElementNotPresent
> Target: css=div:contains('Loading...')
>
> Sometimes an element will appear only after a certain amount of time, depending on how fast ExtJS renders components after a user action results in a view change. Instead of using arbitary delays with the pause command, the ideal method is to wait until the element of interest comes within our grasp. For example, to click on an item after waiting for it to appear:
> Command: waitForElementPresent
> Target: css=span:contains('Do the funky thing')
> Command: click
> Target: css=span:contains('Do the funky thing')
>
> Relying on arbitrary pauses is not a good idea since timing differences that result from running the tests in different browsers or on different machines will make the test cases flaky.
>
> ### Non-clickable Items
>
> Some elements can't be triggered by the click command. It's because the event listener is actually on the container, watching for mouse events on its child elements, that eventually bubble up to the parent. The tab control is one example. To click on the a tab, you have to simulate a mouseDown event at the tab label:
> Command: mouseDownAt
> Target: css=.x-tab-strip-text:contains('Options')
> Value: 0,0
>
>
> ### Field Validation
>
> Form fields (Ext.form.* components) that have associated regular expressions or vtypes for validation will trigger validation with a certain delay (see the validationDelay property which is set to 250ms by default), after the user enters text or immediately when the field loses focus -- or blurs (see thevalidateOnDelay property). In order to trigger field validation after issuing the type Selenium command to enter some text inside a field, you have to do either of the following:
>
> - **Triggering Delayed Validation** ExtJS fires off the validation delay timer when the field receives keyup events. To trigger this timer, simply issue a dummy keyup event (it doesn't matter which key you use as ExtJS ignores it), followed by a short pause that is longer than the validationDelay:
> Command: keyUp
> Target: someTextArea
> Value: x
> Command: pause
> Target: 500
>
>
> - **Triggering Immediate Validation** You can inject a blur event into the field to trigger immediate validation:
> Command: runScript
> Target: someComponent.nameTextField.fireEvent("blur")
>
>
>
>
> ### Checking for Validation Results
>
> Following validation, you can check for the presence or absence of an error field:
> Command: verifyElementNotPresent  
> Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
>
> Command: verifyElementPresent  
> Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
>
> Note that the "display: none" check is necessary because once an error field is shown and then it needs to be hidden, ExtJS will simply hide error field instead of entirely removing it from the DOM tree.

Check out PHPCamp a place to share news, views and articles that are useful to [PHP community](http://phpcamp.net/?utm_medium=blog_post&utm_source=amiworks_co_in&utm_campaign=phpunit_win7).
> ## Element-specific Tips
>
>
> ### Clicking an Ext.form.Button
>
>
> - **Option 1**
> Command: click Target: css=button:contains('Save')
> Selects the button by its caption
> - **Option 2**
> Command: click Target: css=#save-options button
> Selects the button by its id
>
>
> ### Selecting a Value from an Ext.form.ComboBox
>
> Command: runScript
> Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
>
> First sets the value and then explicitly fires the select event in case there are observers.
Second useful tip was about how to continue to run the test when some test fails, it was by [Patrick Lightbody](http://blog.browsermob.com/2010/06/advanced-handling-of-page-timeouts-in-selenium/)
> try {
> selenium.waitForPageToLoad(timeout);
> } catch (e) {
> // this will happen after 90 seconds
> // todo: recover and send the browser to the the next URL
Another useful tip that I found was by [radu](http://www.jslog.com/testing-extjs-with-selenium-automating-ui-tests) that solved the issues caused by auto-generated id by ExtJS.
> Selenium tests for ExtJS should rely on CSS selectors.
> //table[contains(@class,'seleniumOkButton')]
Finally the most important and useful is the [documentation of Testing_Selenium](http://pear.php.net/package/Testing_Selenium/docs/0.4.4/Selenium/Testing_Selenium.html) which lists all the supported functions of selenium RC.

One more thing version 0.4.4 of Testing_Selenium pear pacakge has a missing function *getNumber* [check this bug report](http://pear.php.net/bugs/bug.php?id=12689) to get that function.