Tuesday, February 12, 2013

PRACTICUM: Selenium 2 Testing Tools Beginner's Guide: Finding Elements



This is the next installment (in progress) of my PRACTICUM series. This particular grouping is going through David Burns' "Selenium 2 Testing Tools Beginner's Guide".

Note: PRACTICUM is a continuing series in what I refer to as a somewhat "Live Blog" format. Sections may vary in time to complete. Some may go fast. Some may take much more time to get through. Updates will be daily, they may be more frequent. Feel free to click refresh to get the latest version at any given time. If you see "End of Section" at the bottom of the post, you will know that this entry is finished :).



Chapter 5: Finding Elements

Some may be looking at this entry and thinking "wait, didn't we do this already?" Yes, in a way, this was the point of chapter 2, but this time around we are going to focus on finding elements with the WebDriver API. As its name implies, WebDriver has a number of commands that can be used/called, and these all make up the "Driver" part of WebDriver, and those commands can help us access the elements we need for our tests.

Finding an element on the page by its ID

The nice thing about looking for an element by its ID is that, well, the statement to do that is pretty straightforward:

((FindsById)driver).findElementById("secondajaxbutton");

If we enter this in the test, here's what we see:

Each of the tests will use the following stub.



Note: you'll need to change "Webdriver" to "WebDriver" to get TestExample1.java to compile.

For good measure, so that we see we are starting from a known good origin... proof that the test ran and completed successfully :).


If it didn't find the element, then we'd see something like this:




WebDriver will throw an exception if there's no element by that name (NoSuchElementFoundException).

This next example creates a list of WebElements. The benefit to running this version is that, if it fails, it won't throw an exception. Instead, it will return a list that is size zero (specifically, it has nothing in it).







Finding an Element on the Page by its Name

When we look for an element by its name, the process is similar to what we just used to look for an ID. Also, just like the ID example, in this singular example, if an element is not found, an exception will be thrown.



Note: if you want to keep the examples as a handy little reference, you can set up another test method and stash them in there. If you do, though, modify your variables so that the instances created will be unique. Also, I love the fact that the IDE lets you collapse methods and classes so that, if you aren't making changes, you can just minimize them to one line, so we can focus on the current example. Hmmm, my resistance to this IDE might be crumbling a little ;).

Now, I know what you're thinking… hey, is there an elements example for Name like there is for ID? Yep, there is, and it works much the same way. Good thing, because while in reality there's likely only to be any one item with a particular ID, the chance of having lots of elements with the same name is very possible. The approach is likewise similar to the example for ID:



Similar to the elements example for id, this name examples list option will not throw an exception if the element is not found. It will also return a list that has a size of zero.



Finding an Element on the Page by Their ClassName

So far, these examples all follow a pattern, and that, frankly, is nice to see. Looking for an element by ClassName looks very similar to the previous two element types. If we have more than one element that has the same class name, this approach will return the first ClassName element that it gets. Additionally, this will throw an exception if we do not find the element.



The elements example works the same way.




In addition to ClassName, there's also an option to look for an item by CSS selector by using findElementByCssSelector or findElementByCssSelector



Note: if you ran this example as displayed, you would get an exception because storetext isn't a CSS selector.

Finding an Element on the Page by XPath

We can use XPath to help us find elements as well. XPath is a more expensive option, but it does work, especially if we are looking for multiple items. The following example shows both the single and list approaches to using findElementByXPath and findElementsByXPath:


Finding an Element on the Page by its Link Text

If you are looking for a link that has a particular text string in it, you're in luck. findElementByLinkText and findElementsByLinkText fills the bill. Also, it uses the same format as the other examples (I figure by now I don't need to overdo the point, right? Still, this time, Dave gives us a slightly different approach, as well as a different page to go to:





Finding Elements Using a More Generic Method

Each of the methods we have used up to this point are specific and defined to their scope. Plus side, their easy to spot and easy to implement. Down side, change your mind for how to access  an element, and you may have a bunch of updating to do. There's a more "generic" way to do this that doesn't call on the specific method, but instead calls it internal to the findElement() and findElement() methods. To do this, we enter the commands as follows:



The rules we've learned for the specific methods work in this way as well. single instance will throw an exception if its not found, the list option will not, but will return a list value of zero.



Finding if an Element Exists Without Throwing an Error

All of the examples we have seen up to this point have a similar reaction when the singular version of getElement() is called. If there's no element there, then it throws an exception. We have also seen that, if we don't want to deal with exceptions, we can also call getElements() and set it up to look at the list value and verify the value is 0. Depending on our goals, the list check may be the best option.

Waiting for Elements to Appear on the Page

The bane of a test automators existence is to have an element not be there when we need it. For many of us, the way we have dealt with this in the past is that we have put in sleep statements or other ways to place a delay in the test. the problem with doing this is that, if we wait, and the element isn't there, we have wasted that time. If the element is there, we still have to wait the allotted and pre-programmed amount of time. Once or twice, not a big deal. Over thousands of tests, it could prove to be a major time suck. thus, we want a more dynamic approach to how we handle waiting for elements to appear. WebDriver does this by using implicit and explicit waits.

Implicit Waits

An Implicit Wait is where we tell Selenium to wait for a certain amount of time before it throws an exception due to not finding an element. Here's an example as to how this can be used:



Explicit Waits

Explicit waits are what we use when we know what we want to happen and the error needs to fit that situation. The example David gives looks like this.



Well, we were on a roll here, but alas, I don't know what or why this isn't working. I may be able to figure it out as I dig into this more, but I don't want to hold up the rest of the review, so I'm just going to have to let this one hang as is for a bit.

So there it is, some examples of finding elements using Java and running them singly or in groups (the older test causes method has every single listing listed in this chapter running simultaneously. It'll work as a reference repository while I get more savvy as to how the use the API. Someday, I hope to know and remember enough that I won't need the cheat sheet, but I'm not there just yet. Hope to be soon enough, though :).


End of Section.

No comments: