水豚在查找和填写第一个表单元素时遇到问题
Capybara having trouble finding and filling in first form element
Capybara 似乎无法通过该表单元素标签内的显示文本 找到页面上的第一个表单元素。
Capybara 可以通过该标签的 for
值找到第一个表单元素,这看起来很奇怪。我在想 DOM 还没有加载,水豚可以连续搜索 for
值而不是 labels
中显示的文本?
这是我的相关表单元素的样子:
所以我应该能够通过显示的标签文本获取这些元素中的每一个:
fill_in "First Name", with: "foo"
fill_in "Last Name", with: "bar"
fill_in "Title", with: "some title"
这是我的规格:
scenario "with minimum fields while passing validations", js: true do
visit "/"
click_link "New Contact"
fill_in "First Name", with: "foo"
fill_in "Last Name", with: "bar"
fill_in "Title", with: "some title"
click_button "Create Contact"
expect(page).to have_content "Success."
expect(page).to have_content "foo bar"
end
它没有找到 First Name
表单元素,所以它没有填写它。它找到了 Last Name 元素和 Title 元素,因为我假设 DOM 有届时已满载:
这是html:
然而,奇怪的是:当我更改填写名字时:
fill_in "First Name, with: "foo"
收件人:
fill_in "contact_first_name, with: "foo"
它现在有效,但我不想使用 contact_first_name
的 for
值来获取该表单元素。我想使用显示的标签文本,因为我可以使用 Title
和 Last Name
.
我错过了什么?为什么我不能使用 "First Name" 来获取 First Name 表单元素?
Update:事实证明,如果我将 sleep 1
放在 `fill_in "First Name" 之前,其中: "foo"然后就可以了!根据@TomWalpole 下面的评论,似乎有一个 javascript 库在阻碍?以下是我包含的所有 javascripts:
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require twitter/typeahead.min
//= require nested_form_fields
如果页面加载缓慢,尤其是涉及到某些 Javascript 和/或 CSS 动画,请尝试将 Capybara.default_max_wait_time
提高到例如30 秒(默认为 2 秒)。 fill_in
应该开始工作了。
fill_in
以及大多数其他 Capybara 方法是 "synchronized",即它会重试搜索字段直到默认的最大等待时间,并且仅当在此之后未找到时时间,它失败了。
Capybara 实际上是在查找输入并填充它,但随后该值被删除了。这是因为您有一些 JS 库在 Capybara 填充元素后将 functionality/behavior 添加到输入中。一旦 JS 增加了输入,它就会将其值重置为输入值 属性(与已更改的值属性相反),最终将其设置回空白。在第一个 fill_in 之前休眠是一种解决方法,除此之外这意味着弄清楚元素上的 JS 是什么 运行 并在调用 [=13 之前等待可检测到的变化(如果有的话) =].
Capybara 似乎无法通过该表单元素标签内的显示文本 找到页面上的第一个表单元素。
Capybara 可以通过该标签的 for
值找到第一个表单元素,这看起来很奇怪。我在想 DOM 还没有加载,水豚可以连续搜索 for
值而不是 labels
中显示的文本?
这是我的相关表单元素的样子:
所以我应该能够通过显示的标签文本获取这些元素中的每一个:
fill_in "First Name", with: "foo"
fill_in "Last Name", with: "bar"
fill_in "Title", with: "some title"
这是我的规格:
scenario "with minimum fields while passing validations", js: true do
visit "/"
click_link "New Contact"
fill_in "First Name", with: "foo"
fill_in "Last Name", with: "bar"
fill_in "Title", with: "some title"
click_button "Create Contact"
expect(page).to have_content "Success."
expect(page).to have_content "foo bar"
end
它没有找到 First Name
表单元素,所以它没有填写它。它找到了 Last Name 元素和 Title 元素,因为我假设 DOM 有届时已满载:
这是html:
然而,奇怪的是:当我更改填写名字时:
fill_in "First Name, with: "foo"
收件人:
fill_in "contact_first_name, with: "foo"
它现在有效,但我不想使用 contact_first_name
的 for
值来获取该表单元素。我想使用显示的标签文本,因为我可以使用 Title
和 Last Name
.
我错过了什么?为什么我不能使用 "First Name" 来获取 First Name 表单元素?
Update:事实证明,如果我将 sleep 1
放在 `fill_in "First Name" 之前,其中: "foo"然后就可以了!根据@TomWalpole 下面的评论,似乎有一个 javascript 库在阻碍?以下是我包含的所有 javascripts:
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require twitter/typeahead.min
//= require nested_form_fields
如果页面加载缓慢,尤其是涉及到某些 Javascript 和/或 CSS 动画,请尝试将 Capybara.default_max_wait_time
提高到例如30 秒(默认为 2 秒)。 fill_in
应该开始工作了。
fill_in
以及大多数其他 Capybara 方法是 "synchronized",即它会重试搜索字段直到默认的最大等待时间,并且仅当在此之后未找到时时间,它失败了。
Capybara 实际上是在查找输入并填充它,但随后该值被删除了。这是因为您有一些 JS 库在 Capybara 填充元素后将 functionality/behavior 添加到输入中。一旦 JS 增加了输入,它就会将其值重置为输入值 属性(与已更改的值属性相反),最终将其设置回空白。在第一个 fill_in 之前休眠是一种解决方法,除此之外这意味着弄清楚元素上的 JS 是什么 运行 并在调用 [=13 之前等待可检测到的变化(如果有的话) =].