【问题标题】:Behat/Mink - trouble finding buttonsBehat/Mink - 找不到按钮
【发布时间】:2014-04-23 19:35:05
【问题描述】:

我的测试应用程序是由外部供应商开发的,因此我无法控制 HTML 结构。该应用程序极其繁重 Javascript 和 Ajax,具有大量动态生成的按钮和自动完成列表。

换句话说,页面的特征是它们被填充:

  • 没有固定 ID 的元素(ID 是动态生成的,并且具有 数字或其他动态添加到其中的文本)
  • 某些类也会发生同样的情况
  • 大多数情况下,按钮没有与之关联的文本,因为它们是用于查找列表的自定义编码“向下”箭头 (不是查找列表,而是隐藏的 div)或“+”和“-”图标 最大化或最小化部分内容。 -

因此很难识别这些元素,尤其是按钮。

我正在尝试编写一个通用的“我单击 y 附近的按钮”类型的步骤,这样就没有必要将每个按钮(假设我什至可以用它来识别它们)硬编码到每个按钮中测试。

这背后的想法是,通常至少在按钮附近有某种标签。

我要做的是找到文本标签,然后查看同一范围内是否有按钮,如果没有,则通过父元素移动'后退',并检查内部是否有按钮每个父级的范围,最多5个父级。

这种方法可能会出现各种各样的问题,但我只是想知道这是否能正常工作。我遇到了一些问题。

首先我尝试使用Xpaths,所以我通过以下方式获得了父级的Xpath:

$parentelement = $element->getParent();

$parentXpath->getXpath();

这会给我一个 Xpath :(//html//span[text()='Cost center'])[1] 并且一直向上移动通过父元素,它们将依次变为:

(//html//span[text()='Cost center'])[1]/..[1]

(//html//span[text()='Cost center'])[1]/..[1]/..[1]

等等。

实际的按钮位于:(//html//span[text()='Cost center'])[1]/..[1]/..[1]//button,但它必须通过所有父元素才能到达那里,因此它将以 (//html//span[text()='Cost center'])[1]//button 开头并应以 (//html//span[text()='Cost center'])[1]/..[1]/..[1]//button 结尾,它应该在哪里找到按钮.

尝试使用我使用的 Xpath:

$button_element = $session->getPage()->find('xpath',$parentXpath."//button")

我很快看到'find'命令在你的xpath字符串前面附加了一个//html,所以它尝试使用的Xpath最终是(对于每个父Xpath,但使用这个作为例子):

(//html(//html//span[text()='Cost center'])[1]/..[1])

然后我去掉括号和 //html,留下:

//span[text()='Cost center'][1]/..[1]

但是当我尝试时:

$button_element = $session->getPage()->find('xpath',$strippedParentXpath."//button")

我收到以下错误:

SyntaxError: Failed to execute 'evaluate' on 'Document': The string '(//html//span[text()='Cost center'][1]/..[1]//button)[1]' is not a valid XPath expression

但是,Firepath 可以执行此表达式并且不会显示语法错误,尽管它没有找到实际的按钮(因为按钮实际上位于上一层,Firepath 确实可以找到它)。

所以我的问题 1 是:我的 Xpath 出了什么问题,我无法在查找中使用它?它实际上看起来好像//span[text()='Cost center'][1]//button 没有抛出相同的异常,因为正如我所说,我正在循环通过父 Xpath,它以//span[text()='Cost center'][1]//button 开头。它在//span[text()='Cost center'][1]/..[1]//button 上崩溃。

我的第二个选择是每次都获取父元素,从在页面上查找文本开始,然后使用 findbutton 功能在父元素范围内搜索按钮。

循环遍历父元素(最多 5 个):

$parentelement = $parentelement->getParent();

$butonelement = $parentelement->findbutton('xxx');

换句话说,在父元素的范围内找到任何按钮。我遇到的问题是如何指定一个通用的“按钮”。

必须将一些文本与按钮相关联(如上面的“xxx”所示)。

但这是应​​用程序中按钮的典型示例:

<button class="autocomplete_button" type="button" id="button_OM_1">&nbsp;</button>

该类被多次使用,并且 ID 是自动生成的,并且始终不是同一个数字。由于类指定了图像,因此没有与按钮关联的文本。

问题 2:那么我如何使用“findbutton”来一般地找到没有特定区别特征的“按钮”?请注意,我实际上确实尝试过 findbutton("button"),冒着在按钮某处可能有一个“按钮”的机会,但这也不起作用。至少,它不能始终如一地工作,我的意思是当我运行几次测试时,相同的测试随机似乎找到或找不到相同的按钮。

【问题讨论】:

  • 对此的旁注:不要将alt 用于buttons - 它不会起作用,尽管DocBlock 建议它会。使用title 或其他东西。我花了太长时间解决这个问题。

标签: xpath behat mink


【解决方案1】:

在对此问题进行更多调查后,我发现以下内容: 我试图通过“向上”遍历 div 的范围并跨越文本(使用 xpath)来找到与一段文本最近的按钮的方法实际上是有效的。

不工作的是 SAHI,我将其用作 Web 驱动程序。换句话说,这不是 Behat/Mink 问题,而是 SAHI 特定问题。

我使用 Selenium2 尝试了相同的代码,它执行得很好。

我仍然需要问题 2 的答案 - 如何在没有特定参数(例如 ID、名称或值)的情况下使用 findbutton(),但我会看看是否可以单独在 Behat 用户上找到该问题的答案组,因为我确实认为这是一个 Behat/Mink 特定问题。

【讨论】:

  • 你有与按钮相关的标签吗?
【解决方案2】:

我通常使用 css 选择器,并使用它导航到按钮所在的类和 ID。
我认为它比 xpath 更容易,就像你可以使用一样

 $this->getSession ()->getPage ()->find ( 'css', '.parrent1 .parrent2 .autocomplete_button ' );

我认为这会对您有所帮助,因为您知道在每种情况下要使用哪个按钮

【讨论】:

  • 感谢您的反馈,但我不确定我们是否在同一页面上。我实际上并不知道按钮的类或 ID 或父元素,因为这些通常是使用 javascript 动态生成的。同时,我对为什么我的 Xpath 方法不起作用进行了更多调查,并且我有一个答案,我将在下面发布。
猜你喜欢
  • 1970-01-01
  • 2017-01-25
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多