0

Background: I'm an intern tasked with learning Selenium; my organization plans on having QA/Testing use it to simplify testing. We use JSF and WebSphere Application Server.

One of the persistent issues I (and other users) have had with using Selenium is identifying input elements that have dynamically generated ID attributes. Simply put, I don't know how the ID's are generated or when they change, so hard-coding the ID's into the test case is right out.

Fortunately, I figured out two solutions to the problem. I'm not sure which is better, and as a result I'm not sure which I should recommend.

1) I could use XPATH to locate the element. The devs almost always use the ID attribute when they write up the html, and while JSF will re-assign it on the rendered page, the dev-assigned substring is always (AFAIK) a part of the JSF-generated id. For example:

<input id="name"...>

will be rendered as something like:

<input id="j_id1234567:name"...>

However, a search using XPATH can yield false positives. It also might not stay stable if a dev changes the ID, or if the id-generation algorithm changes.

2.(Recommended by friend who actually works with Selenium) Create empty CSS classes for the input elements, as CSS selectors can be used to locate an element in Selenium., e.g.

<input id = "name"... class="... qa_name">

where .qa_name is empty, and then use driver.findElement.(By.cssSelector(".qa_name")) to locate.

If you create one class per tested element, you have a deterministic way to identify the desired element. What concerns me about this is that

  • I don't know if this will create any overhead while loading the page.
  • The webapp this would be used for has a LOT of input fields.
  • Dev will probably not be thrilled about having to create a bunch of custom CSS for each page.
  • This doesn't seem like a proper use of CSS. I was under the impression that CSS was purely for styling, not giving information about an element.

Are one of these methods more valid than the other, or are these both valid? Also, are my concerns about these methods valid?

2 Answers 2

2

I would focus on looking for the stable portion of the ID. You can use CSS selectors to do this.

driver.findElement(By.cssSelector("input[id^='j_id']");

This is read find an INPUT tag that has an ID that starts with (^) j_id. You can also look for ends with ($) or contains (*).

Read more on CSS Selectors

0

First, you need to identify if there might be some logic to the ID's that you are simply not aware of. You state that Simply put, I don't know how the ID's are generated or when they change which makes me thing that there might be logic to these ID's that you are simply not aware of. As these ID's most likely matter when submitting data (they will likely function as keys in handling POST data), there is a good chance they are deterministic.

If your ID's are really dynamic, you need to go about this the other way. Let's say that you have a dynamically generated input form for a questionnaire. If you think about the way a user would fill out this form, they would not 'enter John Doe in the field with id fld_name'. Instead, they will see an element labeled 'Enter your full name' with a textbox along side it and enter their full name into that textbox. Write your test in that way: look for the logical 'grouping' of elements (such as a table row containing a label with the text 'Enter your full name') and from that level, determine where you need to go (the textbox that is present in the table row)

CSS can be useful as a selector, but should really only be used to identify items by their styling. Adding CSS specifically for UI-tests can easily be replaced by adding a data-dash attribute which is semantically clearer and much less subject to change.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.