【问题标题】:How to locate, using Xpath, an input field without using its id如何使用 Xpath 定位输入字段而不使用其 id
【发布时间】:2016-12-21 20:23:22
【问题描述】:

我正在使用具有以下 HTML 的网页,我想使用页面对象内的 text_field 来识别 <span> 内的第一个 <input> 字段。

<div id="131:">  Please enter your name:
<span class="autocompspan " style="position:static;">
    <input style="position: static;" class="autocompinput yui-ac-input" id="132:" name="132:" 
    onfocus="juic.fire(&quot;132:&quot;,&quot;_focus&quot;,event);" 
    onchange="juic.fire(&quot;132:&quot;,&quot;_despatchChange&quot;,event);" 
    onblur="juic.fire(&quot;132:&quot;,&quot;_blur&quot;,event);" size="60" 
    onkeydown="juic.fire(&quot;132:&quot;,&quot;_onkeydown&quot;,event);" 
    onkeyup="juic.fire(&quot;132:&quot;,&quot;_onkeyup&quot;,event);" aria-disabled="false" value="" 
    role="combobox" aria-autocomplete="list" aria-owns="132:_divList" 
    aria-activedescendant="132:_divAD" findtype="proxy" delimchar="" hideusername="false" 
    fetchusername="false" autocomplete="off" type="text">
    <input value="" id="132:_hidden" name="132:_hidden" type="hidden">
</span>
</div>

如果我使用:id =&gt; '132:' 来识别该字段,则一切正常。 IE。 text_field(:target_user_name, :id =&gt; '132:' ) 有效。

问题是这个 HTML 是由底层应用程序 (SAP) 生成的,它并不总是为 &lt;input&gt; 字段 id 生成相同的值,因此不能依赖使用 id 来一致地识别元素. 因此,鉴于上面的 HTML,我还有什么其他方法可以可靠地找到这个 &lt;input&gt; 字段。

我尝试了以下方法,但均无效。他们中的大多数都超时等待元素被定位。

text_field(:target_user_name, :xpath => "//*[@class='autocompinput yui-ac-input' and @role = 'combobox']" )
text_field(:target_user_name, :xpath => "//*[@class='autocompinput' and @role = 'combobox']" )
text_field(:target_user_name, :xpath => "//span/input[@class='autocompinput yui-ac-input' and @role = 'combobox']" )
text_field(:target_user_name, :xpath => "//input[@class='autocompinput yui-ac-input' and @role = 'combobox']" )
text_field(:target_user_name, :class => 'autocompinput yui-ac-input')

有什么想法吗?

【问题讨论】:

  • 作为用户,您将如何识别文本字段?可能有一些用户可见的文本让用户知道该文本字段的用途。我会使用该文本及其与该字段的关系来进行识别。
  • 有一个 div,其中包含围绕输入的跨度周围的一些字段标签。
  • 关于上面的评论 - 在这种情况下,XPATH 看起来会是什么样子会找到输入字段?本来以为我输入字段属性的 XPATHS 会起作用。
  • 这将取决于 HTML 到底是什么。 XPath 非常依赖于 HTML 的结构,因此如果您可以扩展您的 HTML sn-p 以包含该外部 div,将会有所帮助。
  • 刚刚更新了 sn-p 以显示外部 div。

标签: xpath watir watir-webdriver page-object-gem


【解决方案1】:

当一个元素没有唯一可识别的属性时,你应该查看它周围的元素。在这种情况下,有用户可见的文本可以帮助用户识别字段的用途。相同的文本可用于标识 Watir 中的元素。

由于周围的div 仅包含标签文本,您可以通过其文本搜索该div 并获取其中唯一的文本字段:

browser.div(text: 'Please enter your name:').text_field

作为页面对象访问器:

text_field(:target_user_name) { div_element(text: 'Please enter your name:').text_field_element }

【讨论】:

  • 谢谢贾斯汀今晚我会试一试。为了保持一致性,如果可能,我尝试专门使用页面对象帮助程序而不是 browser.element 调用。有没有办法使用 text_field 助手来完成这个。如果没有,那么我将使用 browser.div
  • 是的,你可以通过定义一个块在访问器中做类似的事情。已添加示例。
  • 嗯 - 在这种情况下仍然找不到 div。我使用“browser.div(文本:'请输入目标用户名:').text_field”搜索并收到消息“30秒后超时,等待{:text =>“请输入目标用户名:”,: tag_name=>"div"} 被定位 (Watir::Exception::UnknownObjectException)"。 '请输入目标用户名:'是 div 的实际文本,类似于我在原始帖子中的示例。
  • 这很有趣。它适用于只包含提供的 HTML 的页面。输出browser.div(id: '131:').text(修改为当时自动生成的ID)会得到什么?我想知道 div 中是否还有其他文本导致精确文本匹配失败。
  • 我将要搜索的文本更改为使用正则表达式,即 /请输入目标用户名:/ 它可以工作。所以 div 文本中可能有换行符或其他内容
【解决方案2】:

首先,Watir 旨在让您不必使用 XPATH。

这取决于页面上有多少不同的元素/id,但我发现使用正则表达式通常适用于动态生成的 id。所以要么抓住 id 并在其他地方使用它:

id = browser.text_field(id: /\d\d\d/).tr(':', '')

或者直接使用:

text_field(:target_user_name, id: /\d\d\d:/)

【讨论】:

  • 我希望不必使用 XPATH,但找不到解决方法。我考虑过使用正则表达式,但有 32 个字段与 ** id=\'\d\d\d:\"** 模式匹配。虽然我尝试过的其中一个 XPATH 将输入元素的属性合并在一起会工作......但他们没有
  • 还有一堆不同的 id #s,而不仅仅是添加到 #s 的东西(如 132:_hidden)?
  • 有 75 个 id,其值以 3 位数字开头,后跟一个冒号。其中 32 个只是 3 位数字,后跟一个冒号。其他 43 个在冒号后有其他文本。
  • 你能提供一个完整的页面吗,我也许可以帮助不太脆弱的独特定位器
  • 整个页面大约有 450 多行,所以宁愿不发布。刚刚更新了 sn-p 以显示周围的 div。尽管我的问题仍然是为什么我不能使用例如尝试列表中的第三项找到输入字段。如果我进入 Chrome 中的开发工具并进行 XPath 搜索,它就可以工作。谢谢。
【解决方案3】:

在这种特殊情况下,您可以使用下面的 xpath 检查“请输入您的姓名:”文本之后的第一个输入字段:

//div[text()='Please enter your name:']//following::input[1]

一般来说,如果您遇到没有唯一标识符的字段,您可以依赖静态文本或字段,然后使用 xpath 函数,例如跟随、前置等。

【讨论】:

  • 谢谢,会试试这个。如何在此文本字段之后找到文本为“OK”的第一个按钮?我会使用 //following::button[text()='OK']
  • 我的意思是 - 我如何找到该 div 字段之后的第一个按钮,其文本为“OK”?我会使用 //following::button[text()='OK']
  • 是的,您绝对可以使用它,但请确保在使用 xpath 函数之前尝试使用唯一标识符,例如 id、名称等(如果可用)。
  • 输入字段有一个唯一的id,但它是由底层系统动态生成的,不保证在执行之间是相同的。
  • 好的。在这种情况下,您可以使用 xpath 函数。
猜你喜欢
  • 1970-01-01
  • 2013-07-15
  • 1970-01-01
  • 2021-08-17
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 2021-06-18
  • 1970-01-01
相关资源
最近更新 更多