[英]How to select a Javascript generated option using Capybara
我有一个用于Sales_Opportunity的输入表单,并且我使用Javascript在“添加新公司”(Sales_Opportunity owners_to Company)的选择下拉菜单的底部添加了一个选项,用户可以选择现有公司或添加新公司使用此选项)。 如果用户单击“添加新公司”,则该页面将打开该公司的Bootstrap3 Modal框形式,提交后(如果成功),该页面将添加一个带有新创建的公司名称的新选项,并自动选择此选项。 上面的代码运行完美,现在我正在尝试编写Rspec / Capybara测试,以确保将来不会中断(我知道-我应该先编写测试,但是作为一个新手,我发现它更容易在浏览器中进行测试,然后编写测试,以便以后可以在其他Jquery / Modal对象上重复使用。)
无论如何-这是失败的测试(来自“我的用户”页面):
it 'can add a new company via the sales opportunity form'do
page.click_link('Add sales opportunity')
expect(page).to have_content('Add new company')
page.select('Add new company', :from => "Company")
page.fill_in('Company name', with: "Modal Company")
page.find("#modal-form").click_button("Save")
expect(page).to have_content("Modal Company")
end
用户单击“添加销售机会”,并转到该销售机会的表单。 Rspec测试在“ page.select('Add new company',:from“ Company”)”行上失败-因此看来该行之前的行之有效,而Capybara正在等待内容显示在页面上。下一行(page.select)显然不等待内容加载。
我上面的测试执行相同的操作-但它们从数据库中选择了一家现有公司,并将其传递以生成Sales_Opportunity,因此我知道我的部分代码工作正常,并且他们正在从同一位置选择公司-向下,以便Capybara可以在“选择”字段中找到其他元素。
如果我的jQuery是有用的:
$(function() {
//select the companies select dropdown and add in a "add new" item
(function () {
$('#sales_opportunity_company_id').append($('<option></option>', {
text: 'Add new company',
}))
})();
//select the "add company" field and open a modal to insert a new company into the DB with Ajax
$('#sales_opportunity_company_id').on('change', function() {
if ($(this).val() == 'Add new company') {
// Hide the submit button if "Add new company is selected"
$('.well .btn').hide();
var newvalue = false;
//call a modal for adding a new company
$('#competitor_modal').modal('show');
//select the input field automatically
$('.modal').on('shown.bs.modal', function() {
$("#company_company_name").focus();
});
//get the organization_id
var Org;
Org = $('#organization_id').attr('data-organizationid');
//pass the organization_id to the hidden text box
$('#company_organization_id').val(Org);
}
else {
$('.well .btn').show();
$input = $('#company_error');
$input.closest('.form-group').removeClass('has-error').find('.warning-block').html('');
}
});
//add a warning to the company selector if the "add new company" field is checked and no company was added
$('.modal').on('hide.bs.modal', function() {
if ($('#sales_opportunity_company_id').val() == 'Add new company') {
$input = $('#company_error');
$input.closest('.form-group').addClass('has-error').find('.warning-block').addClass('col-md-8-offset-4').html('Select a Company from the list above, or add a new company to enable saving');
$input.closest('.form-group .select').addClass('has-error');
$("#sales_opportunity_company_id")[0].selectedIndex = -1;
}
else {
$(this).clear_previous_errors();
}
});
});
如何让水豚去选择这个新添加的物品? 我注意到wait_until在Capybara的v2中已弃用,因此似乎不再是一个选择(我使用的是2.3.0)。
编辑:这是完整性测试失败的结果;
1) User pages sales opportunities can add a new company via the sales opportunity form
Failure/Error: page.select('Add new company', :from => "Company")
Capybara::ElementNotFound:
Unable to find option "Add new company"
# ./spec/requests/user_pages_spec.rb:186:in `block (3 levels) in <top (required)>'
有任何想法吗?
编辑2:
好的,所以我现在尝试了一系列项目,并且得到了一些奇怪的结果。
使用以下水豚测试:
it 'can add a new company via the sales opportunity form'do
page.click_link('Add sales opportunity')
expect(page).to have_content('Add new company')
sleep(2)
print page.html
#page.select('Add new company', :from => "Company")
page.fill_in('Company name', with: "Modal Company")
page.find("#competitor_modal").click_button("Save")
expect(page).to have_content("Modal Company")
end
行“ expect(page).to have_content('添加新公司')”没有引发任何错误。 但是从下面打印的html可以看出,我的页面上也没有实际显示该元素。 知道Javascript为什么在这里不起作用吗?
<div class="form-group" id= "company_error">
<label class="col-md-4 control-label" for="sales_opportunity_company_id">Company</label>
<div class ="col-md-8", id="company_select">
<select id="sales_opportunity_company_id" name="sales_opportunity[company_id]"><option value="23398">Test Company</option></select>
</div>
<span class="warning-block"></span>
</div>
我终于设法解决了这个问题-我需要使用Poltergeist gem才能在无头浏览器中运行javascript,还需要使用粘贴在底部的代码来确保用于测试的数据库可以看到彼此的数据(否则,进行身份验证方法无效)。
最终工作水豚/ Rspec / Poltergeist测试:
it 'can add a new company via the sales opportunity form', js: true do
page.click_link('Add sales opportunity')
page.select('Add new company', :from => "Company")
page.fill_in('Company name', with: "Modal Company")
page.find("#competitor_modal").click_button("Save")
page.has_select?('Company', :selected => 'Modal Company')
end
确保用户规范仍然有效的代码(在spec / support / shared_db_connection.rb中):
class ActiveRecord::Base
mattr_accessor :shared_connection
@@shared_connection = nil
def self.connection
@@shared_connection || retrieve_connection
end
end
# Forces all threads to share the same connection. This works on
# Capybara because it starts the web server in a thread.
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
我使用Railscast#391来完成大部分工作,但同时使用极其有用的Capybara方法进行了很多调试:
print page.html
该页面显示了Javascript的实际运行时间,并允许我使用正确的方法在页面上找到它。
也感谢您的帮助@Mohamed Yakout!
我认为您需要使用以下步骤:
Given(/^I wait for (\d+) seconds?$/) do |n|
sleep(n.to_i)
end
然后使用此代码And I wait for 2 seconds
在此page.click_link('Add sales opportunity')
之后And I wait for 2 seconds
page.click_link('Add sales opportunity')
允许选择#sales_opportunity_company_id
加载选项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.