Search code examples
gwtselenium-webdriversmartgwtselenium-grid

A way to identify SmartGWT SelectItem in Selenium Grid 2 (WebDriver) tests


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:

  1. The usual methods for this purpose setID() and ensureDebugId() are not available in SelectItem
  2. The method setName() don't leave any trace in the generated HTML
  3. It is impossible to find the options list on the form that contains the SelectItem. SelectItem consists of separate elements:

    • label(title)
    • textInput(selected value)
    • picker(button to display the options drop-down list)
    • pickList(the options drop-down list)

    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.


Solution

  • 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.