I am trying to set an ID to a SelectItem (to its options list, more precisely) in order to be able to identify it during Selenium Grid 2 tests and find no way to do it. What I need is to find the list and select (click) a value on it.
Tried and failed intents:
setID()
and ensureDebugId()
are not available in SelectItemsetName()
don't leave any trace in the generated HTMLIt is impossible to find the options list on the form that contains the SelectItem. SelectItem consists of separate elements:
If you set an ID to the form that contains this component in order to localize it through className
you can't spot the pickList, as it's getting generated when the picker is clicked and the generated code is placed out of the form bounds, so you can't find it within the form. It is possible to find it on the whole document, but in case of having more than one lists there is no way to know which list belongs to which SelectItem.
Any advice is welcome. Thank you in advance.
UPDATE: I would like to clarify something to avoid misunderstandings: I know that there are plenty different opinions about the different Selenium tools and versions and the best ways to use it with Smart GWT. This question is not entering these discussions. It is limited to the boundaries indicated in the question title: Selenium Grid 2 tests with WebDriver.
Some background: When coding our GWT components, we identify some of them (carefully, no duplications) with setID()
method for testing purposes, we don't care that these identifiers may be read in the resulting HTML. (Using ensureDebugId()
distorted our view, for some reason. Besides, Isomorphic guys recommended to forget it, anyway.) But setID()
is not available for FormItem
, i.e. we could not set an ID to SelectItem
(which extends from FormItem
) in order to write a test where the first not empty option would be selected.
What I could find is that a SelectItem
lets you set the picker icon name, something that we never used and/or needed:
selectItemInstance.setPickerIconName("someName");
This name is later present in the generated HTML. So we decided to make use of it and assign this way an ID, just like in case of setID()
. The WebDriver
methods allow you later find the SelectItem
element by this name following these steps:
1) find the form (that has the SelectItem
element inside) by its ID
2) find all the SelectItem
elements inside the form
formElement.findElements(By.className("selectItemControl"));
3) select the one that has the pickerIconName equal to the ID assigned with setPickerIconName()
(looping through the found elements):
selectItemElement.findElement(By.xpath("//*[@*='" + pickerIconNameID + "']"));
4) when found, click on it to get the options list generated
pickerElement.click();
NOTE: The options list is generated not before the first click on the SelectItem
element and then stays on, changing from visible to invisible. When generated, it is out of the boundaries of the form that contains the corresponding SelectItem
. This may be a problem, because if you have more than one SelectItem
elements in the window (which is likely), you have to find the correct options list. Several criterias might be applied to find it. We chose options list's location as the easiest and the most reliable one: the options list that "sticks" to the SelectItem
element should be the right one.
5) find all the options lists on the window:
driver.findElementsByClassName("pickListMenuBody")
6) choose the right options list for the SelectItem
: using getLocation()
and getSize()
methods of WebElement
, check which of options list found intersects/touches the SelectItem
element ("selectItemControl") found through steps 2 and 3
That's it, from here on just choose the necessary item in the "listTable" (contained inside the options list element, i.e. "pickListMenuBody"), as you probably did more than once.
Remember to take the loading time into account when searching for elements and keep your utility/infrastructure code separated from test code, otherwise this will become a mess.
This is not the most elegant solution, but it works for us and I am sure that the GWT and Selenium teams, in time, will offer something better.
Any comments and suggestions (limited to the use of Selenium Grid 2) are welcome. Thank you.