ruby on rails - Capybara and JavaScript: checking for visibility requires huge amounts of time! How to optimise? -


while creating javascript functionality in rails, use ugly capybara specs me assuring works. 1 of these specs looks this:

it 'creates report document', js: true   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 created.' end 

i know it's ugly spec, noticed takes huge amount of time: 40secs!

finished in 41.86 seconds (files took 0.44731 seconds load) 

here's spec has javascript activated. although it's smaller (and 1 full page load happens), think time needs improportionally less 1 above:

it 'allows remove existing finding', js: true, focus: true   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 

it takes 6-7secs:

finished in 6.62 seconds (files took 0.52104 seconds load) 

so wonder why first 1 needs time. full spec suite around 400 specs , took around minute, adding new spec increases 2 minutes! isn't acceptable.

so: how can js spec improved? have many visible: false statements? or many and change { ... } stuff? maybe both in interaction?

when removing lines have visible: false in them, goes faster:

finished in 6.39 seconds (files took 0.41315 seconds load) 

i use capybara (2.5.0), rspec (3.3.0), rails (4.2.1), , poltergeist (1.7.0) phantomjs (1.9.8) on osx el capitan.

your test slow becauase you're running capybaras waiting behavior. #has_css?/have_css wait capybara.default_max_wait_time seconds matching elements appear on page before responding false if don't. when expect element not on page want using #has_no_css?/have_no_css (or not_to #has_css?/have_css since end being same thing) since return element not found.

has_css?(....)  #will wait until element appears or default_max_wait_time has_no_css?(....)  #will wait until element gone or default_max_wait_time 

basically in case, don't want using change matcher has_css? because doesn't allow use method match possible on each side of action. if want keep change matcher potential option pass small wait value has_css? wait: 0.5 or decrease max wait time item, may need tweaked allow whatever actions occur on page complete


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -