Capybara 和 JavaScript:检查可见性需要大量时间!如何优化
Capybara and JavaScript: checking for visibility requires huge amounts of time! How to optimise?
在Rails中创建一些JavaScript功能时,我使用了一些丑陋的Capybara规范来帮助我确保一切正常。其中一个规范如下所示:
it 'creates a report document', js: true do
visit new_project_report_document_path @project
expect(page).to have_active_navigation_items 'Projects'
expect(page).to have_breadcrumbs 'A4AA 2.0', 'Projects', 'Project test name', 'Reports', 'Create'
expect(page).to have_headline 'Create Report'
expect {
select 'Template 1', from: 'report_report_template_id'
}.to change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}']", visible: true }.from(false)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_name[disabled]", visible: false}.from(true)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_description[disabled]", visible: false}.from(true)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_intro[disabled]", visible: false}.from(true)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_content[disabled]", visible: false}.from(true)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_outro[disabled]", visible: false}.from(true)
expect(page).to have_css "[data-template-inputs-id='#{@report_template_1.id}'] #report_name", text: @report_template_1.name
expect(page).to have_css "[data-template-inputs-id='#{@report_template_1.id}'] #report_description", text: ''
expect(page).to have_css "[data-template-inputs-id='#{@report_template_1.id}'] #report_intro", text: @report_template_1.intro
expect(page).to have_css "[data-template-inputs-id='#{@report_template_1.id}'] #report_content", text: @report_template_1.content
expect(page).to have_css "[data-template-inputs-id='#{@report_template_1.id}'] #report_outro", text: @report_template_1.outro
expect {
select 'Template 2', from: 'report_report_template_id'
}.to change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}']", visible: true }.from(true)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_name[disabled]", visible: false}.from(false)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_description[disabled]", visible: false}.from(false)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_intro[disabled]", visible: false}.from(false)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_content[disabled]", visible: false}.from(false)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_1.id}'] #report_outro[disabled]", visible: false}.from(false)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_2.id}']", visible: true }.from(false)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_2.id}'] #report_name[disabled]", visible: false}.from(true)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_2.id}'] #report_description[disabled]", visible: false}.from(true)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_2.id}'] #report_intro[disabled]", visible: false}.from(true)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_2.id}'] #report_content[disabled]", visible: false}.from(true)
.and change { page.has_css? "[data-template-inputs-id='#{@report_template_2.id}'] #report_outro[disabled]", visible: false}.from(true)
expect(page).to have_css "[data-template-inputs-id='#{@report_template_2.id}'] #report_name", text: @report_template_2.name
expect(page).to have_css "[data-template-inputs-id='#{@report_template_2.id}'] #report_description", text: ''
expect(page).to have_css "[data-template-inputs-id='#{@report_template_2.id}'] #report_intro", text: @report_template_2.intro
expect(page).to have_css "[data-template-inputs-id='#{@report_template_2.id}'] #report_content", text: @report_template_2.content
expect(page).to have_css "[data-template-inputs-id='#{@report_template_2.id}'] #report_outro", text: @report_template_2.outro
fill_in 'report_name', with: 'newname'
fill_in 'report_description', with: 'newdescription'
fill_in 'report_intro', with: 'newintro'
fill_in 'report_content', with: 'newcontent'
fill_in 'report_outro', with: 'newoutro'
click_button 'Create Report'
expect(page).to have_flash 'Report was successfully created.'
end
我知道这是一个丑陋的规格,但我注意到的是它需要大量的时间:大约 40 秒!
Finished in 41.86 seconds (files took 0.44731 seconds to load)
这是另一个激活了 JavaScript 的规范。虽然它要小得多(并且只发生一个完整的页面加载(,但我认为它所需的时间比上面的时间少得不成比例:
it 'allows to remove an existing finding', js: true, focus: true do
visit edit_project_boilerplate_copy_path(@boilerplate_copy.project, @boilerplate_copy)
click_link 'Remove finding'
expect {
click_button 'Update Boilerplate'
} .to change { Finding.count }.by -1
end
大约需要 6-7 秒:
Finished in 6.62 seconds (files took 0.52104 seconds to load)
所以我想知道为什么第一个需要这么多时间。我的完整规格套件大约有 400 个规格,大约需要一分钟,所以通过添加新规格,它增加到近 2 分钟!这是不可接受的。
那么:如何改进我的JS规范?它与许多visible: false
声明有关吗?还是许多and change { ... }
的东西?也许两者在互动?
当删除所有带有visible: false
的行时,它会更快:
Finished in 6.39 seconds (files took 0.41315 seconds to load)
我在OSX El Capitan上使用capybara(2.5.0(,rspec(3.3.0(,rails(4.2.1(和poltergeist(1.7.0(和phantomjs(1.9.8(。
你的测试太慢了,你遇到了水豚等待行为。 #has_css?/have_css
将等待最多 Capybara.default_max_wait_time 秒,让匹配的元素出现在页面上,如果没有,则以 false 响应。 当您希望某个元素不在页面上时,您希望使用 #has_no_css?/have_no_css(或not_to #has_css?/have_css,因为它们最终是同一件事(,因为一旦找不到该元素,就会返回。
has_css?(....) #will wait until element appears or default_max_wait_time
has_no_css?(....) #will wait until element is gone or default_max_wait_time
基本上,在您的情况下,您不想将change
匹配器与has_css一起使用,因为它不允许您使用在动作的每一侧尽快匹配的方法。 如果您真的想保留change
匹配器,一个可能的选择是将一个小的等待值传递给has_css? wait: 0.5
或会减少该项目的最大等待时间的东西,但可能需要进行调整以允许页面上发生的任何操作实际完成
- Java脚本时间添加
- Json数据包含日期和时间格式
- 如何根据时间运行不同的脚本
- 用每小时的差值填充数组/列表-从下拉列表中给定两个时间值
- 在wordpress一定时间后更改自定义字段
- 以可优化的方式使用requirejs加载模板
- 更改angularjs中的日期-时间格式
- 将当前时间添加到我的页面上的特定部分
- 门户网站:当地时间有多有用
- 如何优化这个jquery循环的执行时间
- 优化静态场景的Three.JS渲染时间
- Capybara 和 JavaScript:检查可见性需要大量时间!如何优化
- 优化长时间点击事件
- 优化快速 + 滑动 HTML 渲染时间
- 在固定时间内优化议程约会之间的路线
- 有没有办法进一步优化这个JavaScript(将当前时间与开放时间进行比较)
- 优化加载时间,同时支持禁用JavaScript的浏览器
- 优化函数以创建垂直时间轴
- 在任何时间日期选择器中以编程方式设置时区偏移量
- 网站优化-页面加载时间&DOM操作