Selenium Inspector is an add-on on top of Selenium for simplifying automated testing of Web components, pages and applications, especially those written using JSF.
Selenium Inspector provides an API similar to that of Selenium in many respects, but is simpler to use in many cases and provides a bit higher level of abstraction. It doesn't replace Selenium, but provides an additional API that you can use if you find it more appropriate for your actual needs. You can use both Selenium and Selenium Inspector APIs at the same time. Selenium's API is concentrated in the com.thoughtworks.selenium.Selenium class, which provides a list of methods for sending commands to a browser (and receiving a result if needed), and the entire variety of commands is combined in a single list regardless of their very different purposes and applicability. Selenium Inspector provides a higher-level API with object-oriented design that is centered around inspection of a single element, and provides different APIs depending on type of element. As a result there are the following advantages:
In order to get started with Selenium Inspector – you need to perform the following steps:
<html>
<head>
<title>Simple Test Page</title>
</head>
<body>
<form id="formId" action="/yourApplication/doAction.jsp" method="post">
<input id="inputField" name="inputField" type="text" />
<input id="submitButton" type="submit" value="Submit"/>
</form>
</body>
</html>
The test case to perform simple check over this page can look like the following code:
public class SimpleTestCase extends SeleniumTestCase {
@BeforeClass
public static void initSeleniumFactory() {
SeleniumHolder seleniumHolder = SeleniumHolder.getInstance();
SeleniumFactory factory = new SeleniumWithServerAutostartFactory(4444, "*firefox","http://localhost:8080");
seleniumHolder.setSeleniumFactory(factory);
}
@Test
public void submitData() {
openAndWait("/yourApplication/simpleTestPage.html");
InputInspector inputField = new InputInspector("inputField");
inputField.assertElementExists();
inputField.type("Test Data to Submit");
getSelenium().click("submitButton");
ServerLoadingMode.getInstance().waitForLoad();
inputField.assertValue("Test Data to Submit");
}
}
Now you know how to start using Selenium Inspector library in your test cases. Please read the sections below to get more details on SeleniumTestCase class and overview of existing element inspectors.
There are two ways to get Selenium Inspector source code:
Currently you need a modified version of selenium-server.jar to use Selenium Inspector — it contains additional JavaScript utilities in user-extensions.js. You can find a modified version of Selenium server inside the distribution of Selenium Inspector, the file is called patched-selenium-server.jar. Also you can easily modify any version of Selenium Server to use it with Selenium Inspector. You can do it in two easy ways:
Selenium Inspector provides a base class for test cases: SeleniumTestCase.The main methods in SeleniumTestCase class are:
With Selenium Inspector library your possible test case can be as easy as this piece of code:
openAndWait("http://yourdomain.com/webapplication/complexTestPage.jsp");
ElementInspector textElement = element("elementWithText");
textElement.assertText("Text inside element");
ElementInspector lastChild = window().document().lastChild();
assertEquals("div",lastChild.nodeName());
Note that there's the utility getSelenium() method in SeleniumTestCase class that returns an instance of Selenium class.
The major concept in Selenium Inspector is a notion of element inspector. An instance of ElementInspector class is bound to an appropriate DOM element and provides a lot of possibilities for manipulating, navigating, and inspecting this element. The SeleniumTestCase.element(String locator) method returns an instance of ElementInspector class, and it's the easiest way to get element inspectors, but you can study the hierarchy below the ElementInspector class, and instantiate the appropriate sub-classes directly in cases when it's appropriate.
The meaning of most of the methods in ElementInspector is obvious when looking at method names. In general there are the following groups of methods:
Please study the ElementInspector class yourself to see all possibilities.
Many of the element inspection and manipulation methods duplicate those found in the Selenium class, though not all of the Selenium class methods have counterparts in ElementInspector yet. This is going to be implemented with time. If you can't find some feature that is present in Selenium class, but you need to do this for the inspected element, you can convert ElementInspector to element locator string using the asSeleniumLocator method, and execute the required selenium command in this way. Here's an example:
ElementInspector field = ...;
getSelenium().removeAllSelections(field.asSeleniumLocator());
The ElementInspector class is just a common base class that is applicable for inspecting all kinds of DOM elements. It doesn't make any difference for inspecting different types of DOM nodes and can be used in this way, though there's a higher level of abstraction that simplifies inspection of more complex HTML elements such as <table> and <ul>. This is solved by creating subclasses of ElementInspector class for different HTML elements. For example there's TableInspector, and UlInspector. These classes have all of the features of the ordinary ElementInspector, but provide additional features, for example there are header/body/footer methods for receiving appropriate table section tags. Here are some examples of what you can do with this higher-level API:
TableInspector table = new TableInspector("tableId");
table.header().assertElementExists(false) // ensure that the table doesn't have a header
table.column(1).assertStyle("color: gray; background: yellow"); // ensure that all cells in the second column have gray color and yellow background
In turn the UlInspector class has the liElements() method that returns the list of child <li> inspectors for your convenience.
UlInspector ulInspector = new UlInspector("ulElementId");
final List<LiInspector> liElements = ulInspector.liElements();
for (LiInspector liInspector : liElements) {
assertEquals("liElementClassName", liInspector.className());
}
The InputInspector provides various <input> tag specific methods, such as type(), name(), value(), disabled(), etc.
InputInspector inputText = new InputInspector("inputTextId");
assertFalse(inputText.disabled());
inputText.focus();
assertFalse(inputText.disabled());
assertEquals("inputTextName",inputText.name());
assertEquals("submit", inputText.type());
inputText.keyPress(13);
Instances of HTML element inspectors can be created directly by instantiating appropriate classes. Usually there are two constructors: one receiving element locator, and one receiving ElementInspector instance.
The hierarchy of HTML-specific inspectors is not finished and is being created. Please study the existing hierarchy of HTML-specific inspectors yourself to see all possibilities.
You can create new inspectors for existing HTML elements or for other libraries/abstractions. All you need to do is to extend your inspectors from appropriate classes of existing inspectors hierarchy. Implementing new functionality for inspecting HTML elements, JSF components or pages will help you to write tests faster, make your code cleaner and give you better opportunities to concentrate more on your test case functionality instead of dealing with Selenium-related issues.
As a start point and useful example, we suggest you to take a look at OpenFaces Inspectors—a package of selenium inspectors created for easier testing of OpenFaces JSF components.