无法在使用Selenium和PHPUnit的knockout启用页面中模糊输入元素


Unable to blur input element in Knockout-enabled page using Selenium with PHPUnit

我有一个页面用于编辑我的应用程序中的类别。它使用Twitter Bootstrap进行布局,非常简单。它看起来像这样:

+===========================================
| page header - contains menus, etc.
+===========================================
 Category Editor
 +----+------------+-------------------+
 | ID |   Status   | Name              |
 +----+------------+-------------------+
 |  1 |  [active]  | Category Name 1   |
 |  2 | [inactive] | Category Name 2   |
 | ... more rows ...                   |
 +----+------------+-------------------+
 [Add new row] [Save]

(方括号内的项为按钮)

该页面基本上是一个列出所有类别的表,以及它们的ID值和一个切换它们状态的按钮(activeinactive)。我使用Knockout来绑定表行&它们对我的模型的价值

表单的工作方式是这样的:

  1. 要将状态从活动更改为非活动(反之亦然),请单击该按钮。这将更新视图模型并更改按钮中的文本。

  2. 要编辑类别名称,单击它。这将隐藏名称(在<span>中)并在相同的表单元格中显示<input>元素。当你输入完新名称后,离开(模糊)输入元素:更新后的名称将被显示,输入元素将再次隐藏。

  3. 要保存你所有的编辑,点击保存按钮。

就我所知一切正常。现在我想用Selenium编写一些测试来测试这个功能。我使用的是Selenium server 2.38.0和PHPUnit。

我遇到的问题是,无论如何,我不能让输入元素模糊。我在谷歌上搜索了很多不同的东西,找到了很多不同的建议。我试过:

  1. 使用Selenium的keyPress方法发送一个制表符到输入元素(我已经尝试过"'t", "'9", "''t", "''9", '${KEY_TAB}')

  2. 使用Selenium的type方法发送一个制表符(与上面相同的字符串)

  3. 使用Selenium的click方法点击不相关的页面元素

  4. 使用Selenium的mouseDownAtmouseUpAt来模拟鼠标按下一个不相关的页面元素。

  5. 设置fireEvent发送"blur"到输入元素

  6. fireEvent发送一个"focus"到输入元素,紧接着另一个fireEvent发送一个"blur"事件

  7. fireEvent发送一个"focusout"到输入元素

有人知道如何模糊使用硒的输入元素吗?

编辑:为了它的价值,我已经缩小到Firefox的问题。

问题

这似乎是Selenium和Firefox 31.0的问题。我可以使用Firefox的Selenium IDE插件和Selenium Server来复制它。

问题来了:

在我的页面标记中,我有一个包含单元格的表,如下所示:

<td data-bind="click: handleNameClick" class="form-group">
    <span class="item-name" data-bind="text: name, visible: !isEditing()"></span>
    <input required type="text" class="form-control" data-bind="value: name, visible: isEditing(), hasFocus: isEditing">
</td>
  1. 当单击<td>时,我的视图模型上的handleNameClick()方法被调用。这个方法看起来像这样:

    自我。handleNameClick = function() {self.isEditing(真正的);}

  2. isEditingtrue时,<input>可见,<span>隐藏;当false时,<span>可见,<input>隐藏。

  3. hasFocus绑定是用来处理blur事件的——当<input>失去焦点时,isEditing的值从true变为false,并且<input>被隐藏。

这最后一步在Chrome中工作很好,无论是在硒控制下还是当我使用表单时。在Selenium控制下,不是在Firefox中工作。

解决方案

为了解决这个问题,我创建了一个变通方法,其中handleNameClick在视图模型中的项目上迭代,并在将isEditing设置为true之前将isEditing设置为false。我的handleNameClick方法现在看起来像这样:

self.handleNameClick = function() {
    // iterate over the parent's items array and set isEditing to false
    // for all of them
    //
    $.each(self.parent.items(), function (i, v){ v.isEditing(false); });
    // now set isEditing = true for this item
    //
    self.isEditing(true);
}

其中self.parent是视图模型,并在每个项目实例化时传递给构造函数。

不是最好的解决方案,但它可以工作,并可能使页面更有弹性。