Selenium: How to avoid using thread.sleep while locating dynamically populated lookup field options

Viewed 152

I have a dynamic lookup salesforce component on the webpage.

![Dynamic Lookup salesforce component

<input lightning-basecombobox_basecombobox="" id="input-19" type="text" role="textbox" autocomplete="off" placeholder="Search undefined..." maxlength="255" aria-autocomplete="list" required="" class="slds-input slds-combobox__input" aria-controls="dropdown-element-19" data-position-id="lgcp-1000001" aria-describedby="help-message-18">

After I type first 3 letters, the options are displayed dynamically and I have to select the option. This is the HTML code for the component after selection:

<input lightning-basecombobox_basecombobox="" id="input-19" type="text" role="textbox" autocomplete="off" placeholder="Bandra West Branch" maxlength="255" required="" class="slds-input slds-combobox__input slds-combobox__input-value" aria-controls="dropdown-element-19" data-position-id="lgcp-1000007" aria-describedby="help-message-18" readonly="">

And this is my Selenium-Java code for selecting the value:

    wait.until(ExpectedConditions.visibilityOf(newLoanObj.txtBranch()));        
    newLoanObj.txtBranch().sendKeys(data.get("Branch"));
    Thread.sleep(2500);
    newLoanObj.txtBranch().sendKeys(Keys.ARROW_DOWN);
    newLoanObj.txtBranch().sendKeys(Keys.ENTER);

Now, the problem is the dynamically populated options takes time to populate and I can not get the locator for the options displayed after sending the key values. Thus I cant use wait for the options to appear. So I am forced to use thread.sleep in this case. So my script fails sometime if the options are not populated within the specified time. So what is the way out to avoid using thread.sleep and still wait till the options are populated after send keys and continue script execution without failures?

2 Answers

(summarised from the comments on the question)

Without seeing the html, the following is an approach that works: (good job @Huzefa)

String strDynamicXPath = "//*[contains(text(),'" + data.get("Branch") + "')]"; wait.until(ExpectedConditions.elementToBeClickable(By.xpath(strDynamicXPath)));
newLoanObj.txtBranch().sendKeys(Keys.ARROW_DOWN); 
newLoanObj.txtBranch().sendKeys(Keys.ENTER); 

The xpath finds any relative element with //* that contains the required text and returns the first instance of it with [1]. It's wide sweeping and could do with being more accurate but if it works then it's an option.

It's worth a note that @Huzefa tried to access the object without the keys, but this was unsuccessful. Updated the answer to remove an alternative code block as it didn't work.


Also worth consideration here is the testing approach.: (updated a little it)

Consider not selecting from the drop down - type in the full value that is required. Without knowing your application configuration I would assume that lookup value and select is Out-Of-The-Box (OOTB) functionality tested by the vendor, unless you've customised it there's no value in testing it. While you're (probably) testing as the end user, this isn't the purpose of this test; If you must test the lookup functionality, create a specific test for it then if it has a 10 seconds wait it doesn't matter as it's only a one-off activity. I would suggest you think about cutting the corner, type the full value

Please use explicit wait for this. Code in selenium 4 looks like this

WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(20));
wait.until(ExpectedConditions.visibilityOfElementLocatedBy(By.xpath(".....");

// use the element
Related