Selenium:如何在定位动态填充的查找字段选项时避免使用thread.sleep

huangapple go评论75阅读模式
英文:

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

问题

我在网页上有一个动态查找Salesforce组件。

<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">

当我输入前3个字母后,选项会动态显示,然后我必须选择一个选项。这是选择后组件的HTML代码:

<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="">

以下是我用于选择值的Selenium-Java代码:

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);

现在的问题是动态生成的选项需要时间来填充,我无法获取发送键值后显示的选项的定位符。因此,在这种情况下,我不能等待选项出现。所以我被迫在这种情况下使用Thread.sleep。因此,如果选项在指定的时间内没有填充,我的脚本有时会失败。那么,有没有办法避免使用Thread.sleep,仍然等待选项在发送键后填充并继续执行脚本而不会失败?

英文:

I have a dynamic lookup salesforce component on the webpage.

Selenium:如何在定位动态填充的查找字段选项时避免使用thread.sleep

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

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:

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

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

	wait.until(ExpectedConditions.visibilityOf(newLoanObj.txtBranch()));		
	newLoanObj.txtBranch().sendKeys(data.get(&quot;Branch&quot;));
	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?

答案1

得分: 1

以下是翻译好的部分:

(summarised from the comments on the question)

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

在不看HTML的情况下,以下是一个有效的方法:
(做得好 @Huzefa)


```plaintext
String strDynamicXPath = &quot;//*[contains(text(),&#39;&quot; + data.get(&quot;Branch&quot;) + &quot;&#39;)]&quot;; wait.until(ExpectedConditions.elementToBeClickable(By.xpath(strDynamicXPath)));
newLoanObj.txtBranch().sendKeys(Keys.ARROW_DOWN); 
newLoanObj.txtBranch().sendKeys(Keys.ENTER); 

字符串strDynamicXPath会查找包含所需文本的任何相对元素,然后使用[1]返回第一个实例。它的范围很广,可能需要更准确一些,但如果它能工作,那就是一个选择。

值得一提的是,@Huzefa尝试在没有使用键的情况下访问对象,但这是不成功的。已更新答案,删除了一个替代代码块,因为它不起作用。


还值得考虑的是测试方法:(稍微更新了一下)

> 考虑不要从下拉列表中选择 - 直接输入所需的完整值。
> 在不了解您的应用程序配置的情况下,我会假设查找值和选择是供应商测试过的开箱即用(OOTB)功能,除非您对其进行了定制,否则没有测试它的价值。
> 虽然您可能是最终用户,但这并不是这个测试的目的;如果必须测试查找功能,那么创建一个专门的测试用例,然后如果需要等待10秒,那也无所谓,因为这只是一次性活动。我建议您考虑简化流程,直接输入完整值。


<details>
<summary>英文:</summary>

(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&#39;s wide sweeping and could do with being more accurate but if it works then it&#39;s an option.


It&#39;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&#39;t work.


----------


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

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

</details>



# 答案2
**得分**: 0

请使用显式等待来完成这个操作。在Selenium 4中的代码如下所示:

```java
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".....")));
    
// 使用该元素

只翻译了代码部分,不包括注释。

英文:

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(&quot;.....&quot;);

// use the element

huangapple
  • 本文由 发表于 2020年8月12日 19:45:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63375833.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定