spec/capybara_spec.rb in sequenceserver-2.0.0.beta1 vs spec/capybara_spec.rb in sequenceserver-2.0.0.beta3

- old
+ new

@@ -1,51 +1,6 @@ -require 'spec_helper' -require 'sauce_whisk' -require 'capybara/rspec' -require 'selenium-webdriver' - -RSpec.configure do |config| - config.include Capybara::DSL -end - -describe 'a browser', :js => true do - before do |scenario| - Capybara.app = SequenceServer.init - Capybara.server = :webrick - Capybara.javascript_driver = :selenium - Capybara.default_max_wait_time = 30 - - Capybara.register_driver :selenium do |app| - capabilities = { - name: scenario.full_description, - platform: ENV['platform'], - browserName: ENV['browserName'], - browserVersion: ENV['browserVersion'], - build: ENV['TRAVIS_BUILD_NUMBER'], - 'tunnel-identifier': ENV['TRAVIS_JOB_NUMBER'] - } - url = "https://#{ENV['SAUCE_USERNAME']}:#{ENV['SAUCE_ACCESS_KEY']}" \ - "@ondemand.saucelabs.com:443/wd/hub".strip - - Capybara::Selenium::Driver.new(app, browser: :remote, url: url, - desired_capabilities: capabilities) - end - end - - before :each do |scenario| - jobname = scenario.full_description - Capybara.session_name = "#{jobname} - #{ENV['platform']} - " \ - "#{ENV['browserName']} - #{ENV['browserVersion']}" - - @driver = Capybara.current_session.driver - - # Output sessionId and jobname to std out for Sauce OnDemand Plugin to - # display embeded results - @session_id = @driver.browser.session_id - puts "SauceOnDemandSessionID=#{@session_id} job-name=#{jobname}" - end - +describe 'a browser', type: :feature, js: true do it 'properly controls blast button' do visit '/' fill_in('sequence', with: nucleotide_query) page.evaluate_script("$('#method').is(':disabled')").should eq(true) @@ -71,43 +26,272 @@ end it 'can run a simple blastn search' do perform_search query: nucleotide_query, databases: nucleotide_databases + page.should have_content('BLASTN') end it 'can run a simple blastp search' do perform_search query: protein_query, databases: protein_databases + page.should have_content('BLASTP') end it 'can run a simple blastx search' do perform_search query: nucleotide_query, databases: protein_databases + page.should have_content('BLASTX') end it 'can run a simple tblastx search' do perform_search query: nucleotide_query, databases: nucleotide_databases, method: 'tblastx' + page.should have_content('TBLASTX') end it 'can run a simple tblastn search' do perform_search query: protein_query, databases: nucleotide_databases + page.should have_content('TBLASTN') end - after :each do |scenario| - @driver.quit - Capybara.use_default_driver - if scenario.exception - SauceWhisk::Jobs.fail_job @session_id - else - SauceWhisk::Jobs.pass_job @session_id + ### Test aspects of the generated report. + + it "can download FASTA of each hit" do + # Do a BLASTP search. protein_query refers to the first two sequence in + # protein_databases[0], so the top hits are the query sequences themselves. + perform_search(query: protein_query, + databases: protein_databases.values_at(0)) + + # Click on the first FASTA download button on the page and wait for the + # download to finish. + page.execute_script("$('.download-fa:eq(0)').click()") + wait_for_download + + # Test name and content of the downloaded file. + expect(File.basename(downloaded_file)). + to eq('sequenceserver-SI2.2.0_06267.fa') + expect(File.read(downloaded_file)). + to eq(File.read("#{__dir__}/sequences/sequenceserver-SI2.2.0_06267.fa")) + end + + it "can download FASTA of selected hits" do + # Do a BLASTP search. protein_query refers to the first two sequence in + # protein_databases[0], so the top hits are the query sequences themselves. + perform_search(query: protein_query, + databases: protein_databases.values_at(0)) + + # Select first hit for each query and click 'FASTA of 2 selected hits'. + page.check('Query_1_hit_1_checkbox') + page.check('Query_2_hit_1_checkbox') + page.click_link('FASTA of 2 selected hit(s)') + wait_for_download + + expect(File.basename(downloaded_file)).to eq('sequenceserver-2_hits.fa') + expect(File.read(downloaded_file)).to eq(File.read("spec/sequences/sequenceserver-2_hits.fa")) + end + + it "can download FASTA of all hits" do + # Do a BLASTP search. protein_query refers to the first two sequence in + # protein_databases[0], so the top hits are the query sequences themselves. + perform_search(query: protein_query, + databases: protein_databases.values_at(0)) + + # Click 'FASTA of all hits'. + page.click_link('FASTA of all hits') + wait_for_download + + expect(File.basename(downloaded_file)).to eq('sequenceserver-2_hits.fa') + expect(File.read(downloaded_file)).to eq(File.read("spec/sequences/sequenceserver-2_hits.fa")) + end + + it "can download alignment for each hit" do + # Do a BLASTP search. protein_query refers to the first two sequence in + # protein_databases[0], so the top hits are the query sequences themselves. + perform_search(query: protein_query, + databases: protein_databases.values_at(0)) + + # Click on the first Alignment download button on the page and wait for the + # download to finish. + page.execute_script("$('.download-aln:eq(0)').click()") + wait_for_download + + # Test name and content of the downloaded file. + expect(File.basename(downloaded_file)).to eq('Query_1_SI2_2_0_06267.txt') + expect(File.read(downloaded_file)). + to eq(File.read("#{__dir__}/sequences/Query_1_SI2_2_0_06267.txt")) + end + + it "can download Alignment of selected hits" do + # Do a BLASTP search. protein_query refers to the first two sequence in + # protein_databases[0], so the top hits are the query sequences themselves. + perform_search(query: protein_query, + databases: protein_databases.values_at(0)) + + # Select first hit for each query and click 'Alignment of 2 selected hits'. + page.check('Query_1_hit_1_checkbox') + page.check('Query_2_hit_1_checkbox') + page.click_link('Alignment of 2 selected hit(s)') + wait_for_download + + expect(File.basename(downloaded_file)).to eq('alignment-2_hits.txt') + expect(File.read(downloaded_file)).to eq(File.read("spec/sequences/alignment-2_hits.txt")) + end + + it "can download Alignment of all hits" do + # Do a BLASTP search. protein_query refers to the first two sequence in + # protein_databases[0], so the top hits are the query sequences themselves. + perform_search(query: protein_query, + databases: protein_databases.values_at(0)) + + # Click 'Alignment of all hits'. + page.click_link('Alignment of all hits') + wait_for_download + + expect(File.basename(downloaded_file)).to eq('alignment-2_hits.txt') + expect(File.read(downloaded_file)).to eq(File.read("spec/sequences/alignment-2_hits.txt")) + end + + it 'can download BLAST results in XML and tabular formats' do + # Do a BLASTP search. protein_query refers to the first two sequence in + # protein_databases[0], so the top hits are the query sequences themselves. + perform_search(query: protein_query, + databases: protein_databases.values_at(0)) + + page.click_link('Standard tabular report') + wait_for_download + expect(File.basename(downloaded_file)).to eq('sequenceserver-std_tsv_report.tsv') + clear_downloads + + page.click_link('Full tabular report') + wait_for_download + expect(File.basename(downloaded_file)).to eq('sequenceserver-full_tsv_report.tsv') + clear_downloads + + page.click_link('Full XML report') + wait_for_download + expect(File.basename(downloaded_file)).to eq('sequenceserver-xml_report.xml') + clear_downloads + end + + it 'can show hit sequences in a modal' do + # Do a BLASTP search. protein_query refers to the first two sequence in + # protein_databases[0], so the top hits are the query sequences themselves. + perform_search(query: protein_query, + databases: protein_databases.values_at(0)) + + # Click on the first sequence viewer link in the report. + page.execute_script("$('.view-sequence:eq(0)').click()") + + within('.sequence-viewer') do + page.should have_content('SI2.2.0_06267') + page.should have_content(<<~SEQ.chomp) + MNTLWLSLWDYPGKLPLNFMVFDTKDDLQAAYWRDPYSIP + LAVIFEDPQPISQRLIYEIRTNPSYTLPPPPTKLYSAPIS + CRKNKTGHWMDDILSIKTGESCPVNNYLHSGFLALQMITD + ITKIKLENSDVTIPDIKLIMFPKEPYTADWMLAFRVVIPL + YMVLALSQFITYLLILIVGEKENKIKEGMKMMGLNDSVF + SEQ end + + # Dismiss the first modal. + page.execute_script("$('.sequence-viewer').modal('hide')") + + # Click on the second sequence viewer link in the report. + page.execute_script("$('.view-sequence:eq(1)').click()") + + within('.sequence-viewer') do + page.should have_content('SI2.2.0_13722') + page.should have_content(<<~SEQ.chomp) + MSANRLNVLVTLMLAVALLVTESGNAQVDGYLQFNPKRSA + VSSPQKYCGKKLSNALQIICDGVYNSMFKKSGQDFPPQNK + RHIAHRINGNEEESFTTLKSNFLNWCVEVYHRHYRFVFVS + EMEMADYPLAYDISPYLPPFLSRARARGMLDGRFAGRRYR + RESRGIHEECCINGCTINELTSYCGP + SEQ + end end + it 'disables sequence viewer links if hits are longer than 10kb' do + # BLASTN transcripts against genome. nucleotide_query refers to two fire + # ant transcripts and nucleotide_databases[0] is subset of the fire ant + # genome (few longest scaffolds). We expect sequence viewer links to be + # disabled for all hits of this search. + perform_search(query: nucleotide_query, + databases: nucleotide_databases.values_at(0)) + + # Check that the sequence viewer links are disabled. + page.evaluate_script("$('.view-sequence').is(':disabled')").should eq(true) + end + + it 'can download visualisations in svg and png format' do + # Do a BLASTP search. protein_query refers to the first two sequence in + # protein_databases[0], so the top hits are the query sequences themselves. + perform_search(query: protein_query, + databases: protein_databases.values_at(0)) + + ## Check that there is a circos vis and unfold it. + page.should have_content('Circos') + page.execute_script("$('.circos > .grapher-header > h5').click()") + sleep 1 + + page.execute_script("$('.export-to-svg:eq(0)').click()") + wait_for_download + expect(File.basename(downloaded_file)).to eq('Circos-visualisation.svg') + clear_downloads + + page.execute_script("$('.export-to-png:eq(0)').click()") + wait_for_download + expect(File.basename(downloaded_file)).to eq('Circos-visualisation.png') + clear_downloads + + + ## Check that there is a graphical overview of hits. + page.should have_content('Graphical overview of hits') + + page.execute_script("$('.export-to-svg:eq(1)').click()") + wait_for_download + expect(File.basename(downloaded_file)).to eq('Alignment-Overview-Query_1.svg') + clear_downloads + + page.execute_script("$('.export-to-png:eq(1)').click()") + wait_for_download + expect(File.basename(downloaded_file)).to eq('Alignment-Overview-Query_1.png') + clear_downloads + + + ## Check that there is a length distribution of hits. + page.should have_content('Length distribution of hits') + page.execute_script("$('.length-distribution > .grapher-header > h5').click()") + sleep 1 + + page.execute_script("$('.export-to-svg:eq(2)').click()") + wait_for_download + expect(File.basename(downloaded_file)).to eq('length-distribution-Query_1.svg') + clear_downloads + + page.execute_script("$('.export-to-png:eq(2)').click()") + wait_for_download + expect(File.basename(downloaded_file)).to eq('length-distribution-Query_1.png') + clear_downloads + + ## Check that there is a kablammo vis of query vs hit. + page.should have_content('Graphical overview of aligning region(s)') + + page.execute_script("$('.export-to-svg:eq(3)').click()") + wait_for_download + expect(File.basename(downloaded_file)).to eq('Kablammo-Query_1-SI2_2_0_06267.svg') + clear_downloads + + page.execute_script("$('.export-to-png:eq(3)').click()") + wait_for_download + expect(File.basename(downloaded_file)).to eq('Kablammo-Query_1-SI2_2_0_06267.png') + clear_downloads + end + ## Helpers ## def perform_search(query: , databases: , method: nil) # Load search form. visit '/' @@ -119,22 +303,23 @@ find('.dropdown-toggle').click find('.dropdown-menu li').click end click_button('method') - # switch to new window because link opens in new window + # Switch to new window because link opens in new window page.driver.browser.switch_to.window(page.driver.browser.window_handles.last) - # Check that results loaded. + # It is important to have this line or the examples end prematurely with a + # failure. page.should have_content('Query') end def nucleotide_query - File.read File.join __dir__, 'nucleotide_query.fa' + File.read File.join(__dir__, 'sequences', 'nucleotide_query.fa') end def protein_query - File.read File.join __dir__, 'protein_query.fa' + File.read File.join(__dir__, 'sequences', 'protein_query.fa') end def nucleotide_databases [ 'Solenopsis invicta gnG subset',