spec/arachni/browser_spec.rb in arachni-1.2.1 vs spec/arachni/browser_spec.rb in arachni-1.3

- old
+ new

@@ -61,28 +61,28 @@ end describe '.has_executable?' do context 'when there is no executable browser' do it 'returns false' do - Selenium::WebDriver::PhantomJS.stub(:path){ false } - described_class.has_executable?.should be_false + allow(Selenium::WebDriver::PhantomJS).to receive(:path){ false } + expect(described_class.has_executable?).to be_falsey end end context 'when there is an executable browser' do it 'returns true' do - Selenium::WebDriver::PhantomJS.stub(:path){ __FILE__ } - described_class.has_executable?.should be_true + allow(Selenium::WebDriver::PhantomJS).to receive(:path){ __FILE__ } + expect(described_class.has_executable?).to be_truthy end end end describe '.executable' do it 'returns the path to the browser executable' do stub = __FILE__ - Selenium::WebDriver::PhantomJS.stub(:path){ stub } - described_class.executable.should == stub + allow(Selenium::WebDriver::PhantomJS).to receive(:path){ stub } + expect(described_class.executable).to eq(stub) end end describe '#initialize' do describe :concurrency do @@ -97,11 +97,11 @@ @browser = described_class.new( ignore_scope: true ) Arachni::Options.scope.exclude_path_patterns << /sleep/ subject.load @url + '/ajax_sleep' - subject.to_page.should be_true + expect(subject.to_page).to be_truthy end end context false do it 'enforces scope restrictions' do @@ -110,11 +110,11 @@ @browser = described_class.new( ignore_scope: false ) Arachni::Options.scope.exclude_path_patterns << /sleep/ subject.load @url + '/ajax_sleep' - subject.to_page.code.should == 0 + expect(subject.to_page.code).to eq(0) end end context :default do it 'enforces scope restrictions' do @@ -123,93 +123,93 @@ @browser = described_class.new( ignore_scope: false ) Arachni::Options.scope.exclude_path_patterns << /sleep/ subject.load @url + '/ajax_sleep' - subject.to_page.code.should == 0 + expect(subject.to_page.code).to eq(0) end end end describe :width do it 'sets the window width' do @browser.shutdown width = 100 @browser = described_class.new( width: width ) - subject.javascript.run('return window.innerWidth').should == width + expect(subject.javascript.run('return window.innerWidth')).to eq(width) end it 'defaults to 1600' do - subject.javascript.run('return window.innerWidth').should == 1600 + expect(subject.javascript.run('return window.innerWidth')).to eq(1600) end end describe :height do it 'sets the window height' do @browser.shutdown height = 100 @browser = described_class.new( height: height ) - subject.javascript.run('return window.innerHeight').should == height + expect(subject.javascript.run('return window.innerHeight')).to eq(height) end it 'defaults to 1200' do - subject.javascript.run('return window.innerHeight').should == 1200 + expect(subject.javascript.run('return window.innerHeight')).to eq(1200) end end describe :store_pages do describe 'default' do it 'stores snapshot pages' do @browser.shutdown @browser = described_class.new - @browser.load( @url + '/explore' ).flush_pages.should be_any + expect(@browser.load( @url + '/explore' ).flush_pages).to be_any end it 'stores captured pages' do @browser.shutdown @browser = described_class.new @browser.start_capture - @browser.load( @url + '/with-ajax' ).flush_pages.should be_any + expect(@browser.load( @url + '/with-ajax' ).flush_pages).to be_any end end describe true do it 'stores snapshot pages' do @browser.shutdown @browser = described_class.new( store_pages: true ) - @browser.load( @url + '/explore' ).trigger_events.flush_pages.should be_any + expect(@browser.load( @url + '/explore' ).trigger_events.flush_pages).to be_any end it 'stores captured pages' do @browser.shutdown @browser = described_class.new( store_pages: true ) @browser.start_capture - @browser.load( @url + '/with-ajax' ).flush_pages.should be_any + expect(@browser.load( @url + '/with-ajax' ).flush_pages).to be_any end end describe false do it 'stores snapshot pages' do @browser.shutdown @browser = described_class.new( store_pages: false ) - @browser.load( @url + '/explore' ).trigger_events.flush_pages.should be_empty + expect(@browser.load( @url + '/explore' ).trigger_events.flush_pages).to be_empty end it 'stores captured pages' do @browser.shutdown @browser = described_class.new( store_pages: false ) @browser.start_capture - @browser.load( @url + '/with-ajax' ).flush_pages.should be_empty + expect(@browser.load( @url + '/with-ajax' ).flush_pages).to be_empty end end end context 'when browser process spawn fails' do it "raises #{described_class::Error::Spawn}" do - described_class.any_instance.stub(:spawn_phantomjs) { nil } + allow_any_instance_of(described_class).to receive(:spawn_phantomjs) { nil } expect { described_class.new }.to raise_error described_class::Error::Spawn end end end @@ -217,55 +217,55 @@ it 'prefixes each source code line with a number' do subject.load @url lines = subject.source.lines.to_a - lines.should be_any + expect(lines).to be_any subject.source_with_line_numbers.lines.each.with_index do |l, i| - l.should == "#{i+1} - #{lines[i]}" + expect(l).to eq("#{i+1} - #{lines[i]}") end end end describe '#load_delay' do it 'returns nil' do subject.load @url - subject.load_delay.should be_nil + expect(subject.load_delay).to be_nil end context 'when the page has JS timeouts' do it 'returns the maximum time the browser should wait for the page based on Timeout' do subject.load( "#{@url}load_delay" ) - subject.load_delay.should == 2000 + expect(subject.load_delay).to eq(2000) end end end describe '#wait_for_timers' do it 'returns' do subject.load @url - subject.wait_for_timers.should be_nil + expect(subject.wait_for_timers).to be_nil end context 'when the page has JS timeouts' do it 'waits for them to complete' do subject.load( "#{@url}load_delay" ) seconds = subject.load_delay / 1000 time = Time.now subject.wait_for_timers - (Time.now - time).should > seconds + expect(Time.now - time).to be > seconds end it "caps them at #{Arachni::OptionGroups::HTTP}#request_timeout" do subject.load( "#{@url}load_delay" ) Arachni::Options.http.request_timeout = 100 time = Time.now subject.wait_for_timers - (Time.now - time).should < 0.2 + expect(Time.now - time).to be < 0.2 end end end describe '#capture_snapshot' do @@ -286,40 +286,40 @@ received = [] subject.on_new_page do |page| received << page end - captured.should == received + expect(captured).to eq(received) end context '#store_pages?' do context true do subject { @browser.shutdown; @browser = described_class.new( store_pages: true )} it 'stores it in #page_snapshots' do captured = subject.capture_snapshot - subject.page_snapshots.should == captured + expect(subject.page_snapshots).to eq(captured) end it 'returns it' do - captured.size.should == 1 - captured.first.should == subject.to_page + expect(captured.size).to eq(1) + expect(captured.first).to eq(subject.to_page) end end context false do subject { @browser.shutdown; @browser = described_class.new( store_pages: false ) } it 'does not store it' do subject.capture_snapshot - subject.page_snapshots.should be_empty + expect(subject.page_snapshots).to be_empty end it 'returns an empty array' do - captured.should be_empty + expect(captured).to be_empty end end end end @@ -327,12 +327,12 @@ before :each do subject.load( @url + '/with-ajax', take_snapshot: false ) end it 'ignores it' do - subject.capture_snapshot.should be_any - subject.capture_snapshot.should be_empty + expect(subject.capture_snapshot).to be_any + expect(subject.capture_snapshot).to be_empty end end context 'when a snapshot has sink data' do before :each do @@ -345,11 +345,11 @@ sinks << page.dom.execution_flow_sinks end subject.capture_snapshot - sinks.size.should == 1 + expect(sinks.size).to eq(1) end context 'and has already been seen' do it 'calls #on_new_page_with_sink callbacks' do sinks = [] @@ -358,30 +358,30 @@ end subject.capture_snapshot subject.capture_snapshot - sinks.size.should == 2 + expect(sinks.size).to eq(2) end end context '#store_pages?' do context true do subject { @browser.shutdown; @browser = described_class.new( store_pages: true )} it 'stores it in #page_snapshots_with_sinks' do subject.capture_snapshot - subject.page_snapshots_with_sinks.should be_any + expect(subject.page_snapshots_with_sinks).to be_any end end context false do subject { @browser.shutdown; @browser = described_class.new( store_pages: false )} it 'does not store it in #page_snapshots_with_sinks' do subject.capture_snapshot - subject.page_snapshots_with_sinks.should be_empty + expect(subject.page_snapshots_with_sinks).to be_empty end end end end @@ -392,11 +392,11 @@ it 'pushes it to the existing transitions' do transition = { stuff: :here } captured = subject.capture_snapshot( stuff: :here ) - captured.first.dom.transitions.should include transition + expect(captured.first.dom.transitions).to include transition end end context 'when there are multiple windows open' do before :each do @@ -406,50 +406,53 @@ it 'captures snapshots from all windows' do subject.javascript.run( 'window.open()' ) subject.watir.windows.last.use subject.load sink_url, take_snapshot: false - subject.capture_snapshot.map(&:url).sort.should == + expect(subject.capture_snapshot.map(&:url).sort).to eq( [ajax_url, sink_url].sort + ) end end context 'when an error occurs' do it 'ignores it' do - subject.watir.stub(:windows) { raise } - subject.capture_snapshot( blah: :stuff ).should be_empty + allow(subject.watir).to receive(:windows) { raise } + expect(subject.capture_snapshot( blah: :stuff )).to be_empty end end end describe '#flush_page_snapshots_with_sinks' do it 'returns pages with data-flow sink data' do @browser.load "#{@url}/lots_of_sinks?input=#{@browser.javascript.log_data_flow_sink_stub( function: { name: 'blah' } )}" @browser.explore_and_flush - @browser.page_snapshots_with_sinks.map(&:dom).map(&:data_flow_sinks).should == + expect(@browser.page_snapshots_with_sinks.map(&:dom).map(&:data_flow_sinks)).to eq( @browser.flush_page_snapshots_with_sinks.map(&:dom).map(&:data_flow_sinks) + ) end it 'returns pages with execution-flow sink data' do @browser.load "#{@url}/lots_of_sinks?input=#{@browser.javascript.log_execution_flow_sink_stub( function: { name: 'blah' } )}" @browser.explore_and_flush - @browser.page_snapshots_with_sinks.map(&:dom).map(&:execution_flow_sinks).should == + expect(@browser.page_snapshots_with_sinks.map(&:dom).map(&:execution_flow_sinks)).to eq( @browser.flush_page_snapshots_with_sinks.map(&:dom).map(&:execution_flow_sinks) + ) end it 'empties the data-flow sink page buffer' do @browser.load "#{@url}/lots_of_sinks?input=#{@browser.javascript.log_data_flow_sink_stub( function: { name: 'blah' } )}" @browser.explore_and_flush @browser.flush_page_snapshots_with_sinks.map(&:dom).map(&:data_flow_sinks) - @browser.page_snapshots_with_sinks.should be_empty + expect(@browser.page_snapshots_with_sinks).to be_empty end it 'empties the execution-flow sink page buffer' do @browser.load "#{@url}/lots_of_sinks?input=#{@browser.javascript.log_execution_flow_sink_stub( function: { name: 'blah' } )}" @browser.explore_and_flush @browser.flush_page_snapshots_with_sinks.map(&:dom).map(&:execution_flow_sinks) - @browser.page_snapshots_with_sinks.should be_empty + expect(@browser.page_snapshots_with_sinks).to be_empty end end describe '#on_new_page_with_sink' do it 'assigns blocks to handle each page with execution-flow sink data' do @@ -460,13 +463,13 @@ sinks << page.dom.execution_flow_sinks end @browser.explore_and_flush - sinks.size.should == 2 - sinks.should == @browser.page_snapshots_with_sinks.map(&:dom). - map(&:execution_flow_sinks) + expect(sinks.size).to eq(2) + expect(sinks).to eq(@browser.page_snapshots_with_sinks.map(&:dom). + map(&:execution_flow_sinks)) end it 'assigns blocks to handle each page with data-flow sink data' do @browser.javascript.taint = 'taint' @browser.load "#{@url}/lots_of_sinks?input=#{@browser.javascript.log_data_flow_sink_stub( @browser.javascript.taint, function: { name: 'blah' } )}" @@ -476,13 +479,13 @@ sinks << page.dom.data_flow_sinks end @browser.explore_and_flush - sinks.size.should == 2 - sinks.should == @browser.page_snapshots_with_sinks.map(&:dom). - map(&:data_flow_sinks) + expect(sinks.size).to eq(2) + expect(sinks).to eq(@browser.page_snapshots_with_sinks.map(&:dom). + map(&:data_flow_sinks)) end end describe '#on_fire_event' do it 'gets called before each event is triggered' do @@ -494,33 +497,33 @@ end @browser.fire_event @browser.watir.div( id: 'my-div' ), :click @browser.fire_event @browser.watir.div( id: 'my-div' ), :mouseover - calls.should == [ + expect(calls).to eq([ [ "<div id=\"my-div\" onclick=\"addForm();\">", :click ], [ "<div id=\"my-div\" onclick=\"addForm();\">", :mouseover ] - ] + ]) end end describe '#on_new_page' do it 'is passed each snapshot' do pages = [] @browser.on_new_page { |page| pages << page } - @browser.load( @url + '/explore' ).trigger_events. - page_snapshots.should == pages + expect(@browser.load( @url + '/explore' ).trigger_events. + page_snapshots).to eq(pages) end it 'is passed each request capture' do pages = [] @browser.on_new_page { |page| pages << page } @browser.start_capture # Last page will be the root snapshot so ignore it. - @browser.load( @url + '/with-ajax' ).captured_pages.should == pages[0...2] + expect(@browser.load( @url + '/with-ajax' ).captured_pages).to eq(pages[0...2]) end end describe '#on_response' do context 'when a response is preloaded' do @@ -530,12 +533,12 @@ @browser.preload Arachni::HTTP::Client.get( @url, mode: :sync ) @browser.goto @url response = responses.first - response.should be_kind_of Arachni::HTTP::Response - response.url.should == @url + expect(response).to be_kind_of Arachni::HTTP::Response + expect(response.url).to eq(@url) end end context 'when a response is cached' do it 'is passed each response' do @@ -544,12 +547,12 @@ @browser.cache Arachni::HTTP::Client.get( @url, mode: :sync ) @browser.goto @url response = responses.first - response.should be_kind_of Arachni::HTTP::Response - response.url.should == @url + expect(response).to be_kind_of Arachni::HTTP::Response + expect(response.url).to eq(@url) end end context 'when a request is performed by the browser' do it 'is passed each response' do @@ -557,12 +560,12 @@ @browser.on_response { |response| responses << response } @browser.goto @url response = responses.first - response.should be_kind_of Arachni::HTTP::Response - response.url.should == @url + expect(response).to be_kind_of Arachni::HTTP::Response + expect(response.url).to eq(@url) end end end describe '#explore_and_flush' do @@ -570,11 +573,11 @@ url = @url + '/deep-dom' pages = @browser.load( url ).explore_and_flush pages_should_have_form_with_input pages, 'by-ajax' - pages.map(&:dom).map(&:transitions).should == [ + expect(pages.map(&:dom).map(&:transitions)).to eq([ [ { :page => :load }, { "#{@url}deep-dom" => :request }, { "#{@url}level2" => :request } ], @@ -653,18 +656,18 @@ } => :click }, { "#{@url}level6" => :request } ] - ].map { |transitions| transitions_from_array( transitions ) } + ].map { |transitions| transitions_from_array( transitions ) }) end context 'with a depth argument' do it 'does not go past the given DOM depth' do pages = @browser.load( @url + '/deep-dom' ).explore_and_flush(2) - pages.map(&:dom).map(&:transitions).should == [ + expect(pages.map(&:dom).map(&:transitions)).to eq([ [ { :page => :load }, { "#{@url}deep-dom" => :request }, { "#{@url}level2" => :request } ], @@ -695,11 +698,11 @@ } } => :click }, { "#{@url}level4" => :request } ] - ].map { |transitions| transitions_from_array( transitions ) } + ].map { |transitions| transitions_from_array( transitions ) }) end end end describe '#page_snapshots_with_sinks' do @@ -708,13 +711,13 @@ @browser.explore_and_flush pages = @browser.page_snapshots_with_sinks doms = pages.map(&:dom) - doms.size.should == 2 + expect(doms.size).to eq(2) - doms[0].transitions.should == transitions_from_array([ + expect(doms[0].transitions).to eq(transitions_from_array([ { page: :load }, { "#{@url}lots_of_sinks?input=#{@browser.javascript.log_execution_flow_sink_stub(1)}" => :request }, { { tag_name: 'a', @@ -722,68 +725,68 @@ 'href' => '#', 'onmouseover' => "onClick2('blah1', 'blah2', 'blah3');" } } => :mouseover } - ]) + ])) - doms[0].execution_flow_sinks.size.should == 2 + expect(doms[0].execution_flow_sinks.size).to eq(2) entry = doms[0].execution_flow_sinks[0] - entry.data.should == [1] - entry.trace.size.should == 3 + expect(entry.data).to eq([1]) + expect(entry.trace.size).to eq(3) - entry.trace[0].function.name.should == 'onClick' - entry.trace[0].function.source.should start_with 'function onClick' - @browser.source.split("\n")[entry.trace[0].line].should include 'log_execution_flow_sink(1)' - entry.trace[0].function.arguments.should == [1, 2] + expect(entry.trace[0].function.name).to eq('onClick') + expect(entry.trace[0].function.source).to start_with 'function onClick' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_execution_flow_sink(1)' + expect(entry.trace[0].function.arguments).to eq([1, 2]) - entry.trace[1].function.name.should == 'onClick2' - entry.trace[1].function.source.should start_with 'function onClick2' - @browser.source.split("\n")[entry.trace[1].line].should include 'onClick' - entry.trace[1].function.arguments.should == %w(blah1 blah2 blah3) + expect(entry.trace[1].function.name).to eq('onClick2') + expect(entry.trace[1].function.source).to start_with 'function onClick2' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick' + expect(entry.trace[1].function.arguments).to eq(%w(blah1 blah2 blah3)) - entry.trace[2].function.name.should == 'onmouseover' - entry.trace[2].function.source.should start_with 'function onmouseover' + expect(entry.trace[2].function.name).to eq('onmouseover') + expect(entry.trace[2].function.source).to start_with 'function onmouseover' event = entry.trace[2].function.arguments.first link = "<a href=\"#\" onmouseover=\"onClick2('blah1', 'blah2', 'blah3');\">Blah</a>" - event['target'].should == link - event['srcElement'].should == link - event['type'].should == 'mouseover' + expect(event['target']).to eq(link) + expect(event['srcElement']).to eq(link) + expect(event['type']).to eq('mouseover') entry = doms[0].execution_flow_sinks[1] - entry.data.should == [1] - entry.trace.size.should == 4 + expect(entry.data).to eq([1]) + expect(entry.trace.size).to eq(4) - entry.trace[0].function.name.should == 'onClick3' - entry.trace[0].function.source.should start_with 'function onClick3' - @browser.source.split("\n")[entry.trace[0].line].should include 'log_execution_flow_sink(1)' - entry.trace[0].function.arguments.should be_empty + expect(entry.trace[0].function.name).to eq('onClick3') + expect(entry.trace[0].function.source).to start_with 'function onClick3' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_execution_flow_sink(1)' + expect(entry.trace[0].function.arguments).to be_empty - entry.trace[1].function.name.should == 'onClick' - entry.trace[1].function.source.should start_with 'function onClick' - @browser.source.split("\n")[entry.trace[1].line].should include 'onClick3' - entry.trace[1].function.arguments.should == [1, 2] + expect(entry.trace[1].function.name).to eq('onClick') + expect(entry.trace[1].function.source).to start_with 'function onClick' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick3' + expect(entry.trace[1].function.arguments).to eq([1, 2]) - entry.trace[2].function.name.should == 'onClick2' - entry.trace[2].function.source.should start_with 'function onClick2' - @browser.source.split("\n")[entry.trace[2].line].should include 'onClick' - entry.trace[2].function.arguments.should == %w(blah1 blah2 blah3) + expect(entry.trace[2].function.name).to eq('onClick2') + expect(entry.trace[2].function.source).to start_with 'function onClick2' + expect(@browser.source.split("\n")[entry.trace[2].line]).to include 'onClick' + expect(entry.trace[2].function.arguments).to eq(%w(blah1 blah2 blah3)) - entry.trace[3].function.name.should == 'onmouseover' - entry.trace[3].function.source.should start_with 'function onmouseover' + expect(entry.trace[3].function.name).to eq('onmouseover') + expect(entry.trace[3].function.source).to start_with 'function onmouseover' event = entry.trace[3].function.arguments.first link = "<a href=\"#\" onmouseover=\"onClick2('blah1', 'blah2', 'blah3');\">Blah</a>" - event['target'].should == link - event['srcElement'].should == link - event['type'].should == 'mouseover' + expect(event['target']).to eq(link) + expect(event['srcElement']).to eq(link) + expect(event['type']).to eq('mouseover') - doms[1].transitions.should == transitions_from_array([ + expect(doms[1].transitions).to eq(transitions_from_array([ { page: :load }, { "#{@url}lots_of_sinks?input=#{@browser.javascript.log_execution_flow_sink_stub(1)}" => :request }, { { tag_name: 'form', @@ -791,181 +794,181 @@ 'id' => 'my_form', 'onsubmit' => "onClick('some-arg', 'arguments-arg', 'here-arg'); return false;" } } => :submit } - ]) + ])) - doms[1].execution_flow_sinks.size.should == 2 + expect(doms[1].execution_flow_sinks.size).to eq(2) entry = doms[1].execution_flow_sinks[0] - entry.data.should == [1] - entry.trace.size.should == 2 + expect(entry.data).to eq([1]) + expect(entry.trace.size).to eq(2) - entry.trace[0].function.name.should == 'onClick' - entry.trace[0].function.source.should start_with 'function onClick' - @browser.source.split("\n")[entry.trace[0].line].should include 'log_execution_flow_sink(1)' - entry.trace[0].function.arguments.should == %w(some-arg arguments-arg here-arg) + expect(entry.trace[0].function.name).to eq('onClick') + expect(entry.trace[0].function.source).to start_with 'function onClick' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_execution_flow_sink(1)' + expect(entry.trace[0].function.arguments).to eq(%w(some-arg arguments-arg here-arg)) - entry.trace[1].function.name.should == 'onsubmit' - entry.trace[1].function.source.should start_with 'function onsubmit' - @browser.source.split("\n")[entry.trace[1].line].should include 'onClick' + expect(entry.trace[1].function.name).to eq('onsubmit') + expect(entry.trace[1].function.source).to start_with 'function onsubmit' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick' event = entry.trace[1].function.arguments.first form = "<form id=\"my_form\" onsubmit=\"onClick('some-arg', 'arguments-arg', 'here-arg'); return false;\">\n </form>" - event['target'].should == form - event['srcElement'].should == form - event['type'].should == 'submit' + expect(event['target']).to eq(form) + expect(event['srcElement']).to eq(form) + expect(event['type']).to eq('submit') entry = doms[1].execution_flow_sinks[1] - entry.data.should == [1] - entry.trace.size.should == 3 + expect(entry.data).to eq([1]) + expect(entry.trace.size).to eq(3) - entry.trace[0].function.name.should == 'onClick3' - entry.trace[0].function.source.should start_with 'function onClick3' - @browser.source.split("\n")[entry.trace[0].line].should include 'log_execution_flow_sink(1)' - entry.trace[0].function.arguments.should be_empty + expect(entry.trace[0].function.name).to eq('onClick3') + expect(entry.trace[0].function.source).to start_with 'function onClick3' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_execution_flow_sink(1)' + expect(entry.trace[0].function.arguments).to be_empty - entry.trace[1].function.name.should == 'onClick' - entry.trace[1].function.source.should start_with 'function onClick' - @browser.source.split("\n")[entry.trace[1].line].should include 'onClick3()' - entry.trace[1].function.arguments.should == %w(some-arg arguments-arg here-arg) + expect(entry.trace[1].function.name).to eq('onClick') + expect(entry.trace[1].function.source).to start_with 'function onClick' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick3()' + expect(entry.trace[1].function.arguments).to eq(%w(some-arg arguments-arg here-arg)) - entry.trace[2].function.name.should == 'onsubmit' - entry.trace[2].function.source.should start_with 'function onsubmit' - @browser.source.split("\n")[entry.trace[2].line].should include 'onClick(' + expect(entry.trace[2].function.name).to eq('onsubmit') + expect(entry.trace[2].function.source).to start_with 'function onsubmit' + expect(@browser.source.split("\n")[entry.trace[2].line]).to include 'onClick(' event = entry.trace[2].function.arguments.first form = "<form id=\"my_form\" onsubmit=\"onClick('some-arg', 'arguments-arg', 'here-arg'); return false;\">\n </form>" - event['target'].should == form - event['srcElement'].should == form - event['type'].should == 'submit' + expect(event['target']).to eq(form) + expect(event['srcElement']).to eq(form) + expect(event['type']).to eq('submit') end it 'returns data-flow sink data' do @browser.javascript.taint = 'taint' @browser.load "#{@url}/lots_of_sinks?input=#{@browser.javascript.log_data_flow_sink_stub( @browser.javascript.taint, function: 'blah' )}" @browser.explore_and_flush pages = @browser.page_snapshots_with_sinks doms = pages.map(&:dom) - doms.size.should == 2 + expect(doms.size).to eq(2) - doms[0].data_flow_sinks.size.should == 2 + expect(doms[0].data_flow_sinks.size).to eq(2) entry = doms[0].data_flow_sinks[0] - entry.function.should == 'blah' - entry.trace.size.should == 3 + expect(entry.function).to eq('blah') + expect(entry.trace.size).to eq(3) - entry.trace[0].function.name.should == 'onClick' - entry.trace[0].function.source.should start_with 'function onClick' - @browser.source.split("\n")[entry.trace[0].line].should include 'log_data_flow_sink(' - entry.trace[0].function.arguments.should == [1, 2] + expect(entry.trace[0].function.name).to eq('onClick') + expect(entry.trace[0].function.source).to start_with 'function onClick' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_data_flow_sink(' + expect(entry.trace[0].function.arguments).to eq([1, 2]) - entry.trace[1].function.name.should == 'onClick2' - entry.trace[1].function.source.should start_with 'function onClick2' - @browser.source.split("\n")[entry.trace[1].line].should include 'onClick' - entry.trace[1].function.arguments.should == %w(blah1 blah2 blah3) + expect(entry.trace[1].function.name).to eq('onClick2') + expect(entry.trace[1].function.source).to start_with 'function onClick2' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick' + expect(entry.trace[1].function.arguments).to eq(%w(blah1 blah2 blah3)) - entry.trace[2].function.name.should == 'onmouseover' - entry.trace[2].function.source.should start_with 'function onmouseover' + expect(entry.trace[2].function.name).to eq('onmouseover') + expect(entry.trace[2].function.source).to start_with 'function onmouseover' event = entry.trace[2].function.arguments.first link = "<a href=\"#\" onmouseover=\"onClick2('blah1', 'blah2', 'blah3');\">Blah</a>" - event['target'].should == link - event['srcElement'].should == link - event['type'].should == 'mouseover' + expect(event['target']).to eq(link) + expect(event['srcElement']).to eq(link) + expect(event['type']).to eq('mouseover') entry = doms[0].data_flow_sinks[1] - entry.function.should == 'blah' - entry.trace.size.should == 4 + expect(entry.function).to eq('blah') + expect(entry.trace.size).to eq(4) - entry.trace[0].function.name.should == 'onClick3' - entry.trace[0].function.source.should start_with 'function onClick3' - @browser.source.split("\n")[entry.trace[0].line].should include 'log_data_flow_sink(' - entry.trace[0].function.arguments.should be_empty + expect(entry.trace[0].function.name).to eq('onClick3') + expect(entry.trace[0].function.source).to start_with 'function onClick3' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_data_flow_sink(' + expect(entry.trace[0].function.arguments).to be_empty - entry.trace[1].function.name.should == 'onClick' - entry.trace[1].function.source.should start_with 'function onClick' - @browser.source.split("\n")[entry.trace[1].line].should include 'onClick3' - entry.trace[1].function.arguments.should == [1, 2] + expect(entry.trace[1].function.name).to eq('onClick') + expect(entry.trace[1].function.source).to start_with 'function onClick' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick3' + expect(entry.trace[1].function.arguments).to eq([1, 2]) - entry.trace[2].function.name.should == 'onClick2' - entry.trace[2].function.source.should start_with 'function onClick2' - @browser.source.split("\n")[entry.trace[2].line].should include 'onClick' - entry.trace[2].function.arguments.should == %w(blah1 blah2 blah3) + expect(entry.trace[2].function.name).to eq('onClick2') + expect(entry.trace[2].function.source).to start_with 'function onClick2' + expect(@browser.source.split("\n")[entry.trace[2].line]).to include 'onClick' + expect(entry.trace[2].function.arguments).to eq(%w(blah1 blah2 blah3)) - entry.trace[3].function.name.should == 'onmouseover' - entry.trace[3].function.source.should start_with 'function onmouseover' + expect(entry.trace[3].function.name).to eq('onmouseover') + expect(entry.trace[3].function.source).to start_with 'function onmouseover' event = entry.trace[3].function.arguments.first link = "<a href=\"#\" onmouseover=\"onClick2('blah1', 'blah2', 'blah3');\">Blah</a>" - event['target'].should == link - event['srcElement'].should == link - event['type'].should == 'mouseover' + expect(event['target']).to eq(link) + expect(event['srcElement']).to eq(link) + expect(event['type']).to eq('mouseover') - doms[1].data_flow_sinks.size.should == 2 + expect(doms[1].data_flow_sinks.size).to eq(2) entry = doms[1].data_flow_sinks[0] - entry.function.should == 'blah' - entry.trace.size.should == 2 + expect(entry.function).to eq('blah') + expect(entry.trace.size).to eq(2) - entry.trace[0].function.name.should == 'onClick' - entry.trace[0].function.source.should start_with 'function onClick' - @browser.source.split("\n")[entry.trace[0].line].should include 'log_data_flow_sink(' - entry.trace[0].function.arguments.should == %w(some-arg arguments-arg here-arg) + expect(entry.trace[0].function.name).to eq('onClick') + expect(entry.trace[0].function.source).to start_with 'function onClick' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_data_flow_sink(' + expect(entry.trace[0].function.arguments).to eq(%w(some-arg arguments-arg here-arg)) - entry.trace[1].function.name.should == 'onsubmit' - entry.trace[1].function.source.should start_with 'function onsubmit' - @browser.source.split("\n")[entry.trace[1].line].should include 'onClick' + expect(entry.trace[1].function.name).to eq('onsubmit') + expect(entry.trace[1].function.source).to start_with 'function onsubmit' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick' event = entry.trace[1].function.arguments.first form = "<form id=\"my_form\" onsubmit=\"onClick('some-arg', 'arguments-arg', 'here-arg'); return false;\">\n </form>" - event['target'].should == form - event['srcElement'].should == form - event['type'].should == 'submit' + expect(event['target']).to eq(form) + expect(event['srcElement']).to eq(form) + expect(event['type']).to eq('submit') entry = doms[1].data_flow_sinks[1] - entry.function.should == 'blah' - entry.trace.size.should == 3 + expect(entry.function).to eq('blah') + expect(entry.trace.size).to eq(3) - entry.trace[0].function.name.should == 'onClick3' - entry.trace[0].function.source.should start_with 'function onClick3' - @browser.source.split("\n")[entry.trace[0].line].should include 'log_data_flow_sink(' - entry.trace[0].function.arguments.should be_empty + expect(entry.trace[0].function.name).to eq('onClick3') + expect(entry.trace[0].function.source).to start_with 'function onClick3' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_data_flow_sink(' + expect(entry.trace[0].function.arguments).to be_empty - entry.trace[1].function.name.should == 'onClick' - entry.trace[1].function.source.should start_with 'function onClick' - @browser.source.split("\n")[entry.trace[1].line].should include 'onClick3()' - entry.trace[1].function.arguments.should == %w(some-arg arguments-arg here-arg) + expect(entry.trace[1].function.name).to eq('onClick') + expect(entry.trace[1].function.source).to start_with 'function onClick' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick3()' + expect(entry.trace[1].function.arguments).to eq(%w(some-arg arguments-arg here-arg)) - entry.trace[2].function.name.should == 'onsubmit' - entry.trace[2].function.source.should start_with 'function onsubmit' - @browser.source.split("\n")[entry.trace[2].line].should include 'onClick(' + expect(entry.trace[2].function.name).to eq('onsubmit') + expect(entry.trace[2].function.source).to start_with 'function onsubmit' + expect(@browser.source.split("\n")[entry.trace[2].line]).to include 'onClick(' event = entry.trace[2].function.arguments.first form = "<form id=\"my_form\" onsubmit=\"onClick('some-arg', 'arguments-arg', 'here-arg'); return false;\">\n </form>" - event['target'].should == form - event['srcElement'].should == form - event['type'].should == 'submit' + expect(event['target']).to eq(form) + expect(event['srcElement']).to eq(form) + expect(event['type']).to eq('submit') end describe 'when store_pages: false' do it 'does not store pages' do @browser.shutdown @browser = @browser.class.new( store_pages: false ) @browser.load "#{@url}/lots_of_sinks?input=#{@browser.javascript.log_execution_flow_sink_stub(1)}" @browser.explore_and_flush - @browser.page_snapshots_with_sinks.should be_empty + expect(@browser.page_snapshots_with_sinks).to be_empty end end end describe '#response' do @@ -975,14 +978,14 @@ browser_response = @browser.response browser_request = browser_response.request raw_response = Arachni::HTTP::Client.get( @url, mode: :sync ) raw_request = raw_response.request - browser_response.url.should == raw_response.url + expect(browser_response.url).to eq(raw_response.url) [:url, :method].each do |attribute| - browser_request.send(attribute).should == raw_request.send(attribute) + expect(browser_request.send(attribute)).to eq(raw_request.send(attribute)) end end context "when the response takes more than #{Arachni::OptionGroups::HTTP}#request_timeout" do it 'returns nil' @@ -990,11 +993,11 @@ context 'when the resource is out-of-scope' do it 'returns nil' do Arachni::Options.url = @url @browser.load 'http://google.com/' - @browser.response.should be_nil + expect(@browser.response).to be_nil end end end describe '#to_page' do @@ -1002,43 +1005,44 @@ ua = Arachni::Options.http.user_agent @browser.load( @url ) page = @browser.to_page - page.should be_kind_of Arachni::Page + expect(page).to be_kind_of Arachni::Page - ua.should_not be_empty - page.response.body.should_not include( ua ) - page.body.should include( ua ) + expect(ua).not_to be_empty + expect(page.response.body).not_to include( ua ) + expect(page.body).to include( ua ) end it "assigns the proper #{Arachni::Page::DOM}#digest" do @browser.load( @url ) - @browser.to_page.dom.instance_variable_get(:@digest).should == + expect(@browser.to_page.dom.instance_variable_get(:@digest)).to eq( '<HTML><HEAD><SCRIPT src=http://javascript.browser.arachni/' << 'taint_tracer.js><SCRIPT src=http://javascript.' << 'browser.arachni/dom_monitor.js><SCRIPT><TITLE><BODY><' << 'DIV><SCRIPT type=text/javascript><SCRIPT type=text/javascript>' + ) end it "assigns the proper #{Arachni::Page::DOM}#transitions" do @browser.load( @url ) page = @browser.to_page - page.dom.transitions.should == transitions_from_array([ + expect(page.dom.transitions).to eq(transitions_from_array([ { page: :load }, { @url => :request } - ]) + ])) end it "assigns the proper #{Arachni::Page::DOM}#skip_states" do @browser.load( @url ) pages = @browser.load( @url + '/explore' ).trigger_events. page_snapshots page = pages.last - page.dom.skip_states.should be_subset @browser.skip_states + expect(page.dom.skip_states).to be_subset @browser.skip_states end it "assigns the proper #{Arachni::Page::DOM} sink data" do @browser.load "#{web_server_url_for( :taint_tracer )}/debug" << "?input=#{@browser.javascript.log_execution_flow_sink_stub(1)}" @@ -1046,141 +1050,269 @@ page = @browser.to_page sink_data = page.dom.execution_flow_sinks first_entry = sink_data.first - sink_data.should == [first_entry] + expect(sink_data).to eq([first_entry]) - first_entry.data.should == [1] - first_entry.trace.size.should == 2 + expect(first_entry.data).to eq([1]) + expect(first_entry.trace.size).to eq(2) - first_entry.trace[0].function.name.should == 'onClick' - first_entry.trace[0].function.source.should start_with 'function onClick' - @browser.source.split("\n")[first_entry.trace[0].line].should include 'log_execution_flow_sink(1)' - first_entry.trace[0].function.arguments.should == %w(some-arg arguments-arg here-arg) + expect(first_entry.trace[0].function.name).to eq('onClick') + expect(first_entry.trace[0].function.source).to start_with 'function onClick' + expect(@browser.source.split("\n")[first_entry.trace[0].line]).to include 'log_execution_flow_sink(1)' + expect(first_entry.trace[0].function.arguments).to eq(%w(some-arg arguments-arg here-arg)) - first_entry.trace[1].function.name.should == 'onsubmit' - first_entry.trace[1].function.source.should start_with 'function onsubmit' - @browser.source.split("\n")[first_entry.trace[1].line].should include 'onClick(' - first_entry.trace[1].function.arguments.size.should == 1 + expect(first_entry.trace[1].function.name).to eq('onsubmit') + expect(first_entry.trace[1].function.source).to start_with 'function onsubmit' + expect(@browser.source.split("\n")[first_entry.trace[1].line]).to include 'onClick(' + expect(first_entry.trace[1].function.arguments.size).to eq(1) event = first_entry.trace[1].function.arguments.first form = "<form id=\"my_form\" onsubmit=\"onClick('some-arg', 'arguments-arg', 'here-arg'); return false;\">\n </form>" - event['target'].should == form - event['srcElement'].should == form - event['type'].should == 'submit' + expect(event['target']).to eq(form) + expect(event['srcElement']).to eq(form) + expect(event['type']).to eq('submit') end - context "when the page has #{Arachni::Element::Form::DOM} elements" do - context "and #{Arachni::OptionGroups::Audit}#forms is" do - context true do - before do - Arachni::Options.audit.elements :forms - end + context 'when the page has' do + context "#{Arachni::Element::UIForm} elements" do + context "and #{Arachni::OptionGroups::Audit}#inputs is" do + context true do + before do + Arachni::Options.audit.elements :ui_forms + end - context 'a JavaScript action' do - it 'does not set #skip_dom' do - @browser.load "#{@url}/each_element_with_events/form/action/javascript" - @browser.to_page.forms.first.skip_dom.should be_nil + context '<input> button' do + context 'with DOM events' do + it 'parses it' do + @browser.load "#{@url}/to_page/input/button/with_events" + + input = @browser.to_page.ui_forms.first + + expect(input.action).to eq @browser.url + expect(input.source).to eq '<input type="button" id="insert">' + expect(input.method).to eq :click + end + end + + context 'without DOM events' do + it 'ignores it' do + @browser.load "#{@url}/to_page/input/button/without_events" + expect(@browser.to_page.ui_forms).to be_empty + end + end end - end - context 'with DOM events' do - it 'does not set #skip_dom' do - @browser.load "#{@url}/fire_event/form/onsubmit" - @browser.to_page.forms.first.skip_dom.should be_nil + context '<button>' do + context 'with DOM events' do + it 'parses it' do + @browser.load "#{@url}/to_page/button/with_events" + + input = @browser.to_page.ui_forms.first + + expect(input.action).to eq @browser.url + expect(input.source).to eq '<button id="insert">' + expect(input.method).to eq :click + end + end + + context 'without DOM events' do + it 'ignores it' do + @browser.load "#{@url}to_page/button/without_events" + expect(@browser.to_page.ui_forms).to be_empty + end + end end end - context 'without DOM events' do - it 'sets #skip_dom to true' do - @browser.load "#{@url}/each_element_with_events/form/action/regular" - @browser.to_page.forms.first.skip_dom.should be_true + context false do + before do + Arachni::Options.audit.skip_elements :ui_forms end - end - end - context false do - before do - Arachni::Options.audit.skip_elements :forms + it 'ignores them' do + @browser.load "#{@url}/to_page/button/with_events" + expect(@browser.to_page.ui_forms).to be_empty + end end - - it 'does not set #skip_dom' do - @browser.load "#{@url}/each_element_with_events/form/action/regular" - @browser.to_page.forms.first.skip_dom.should be_nil - end end end - end - context "when the page has #{Arachni::Element::Cookie::DOM} elements" do - let(:cookies) { @browser.to_page.cookies } + context "#{Arachni::Element::UIInput} elements" do + context "and #{Arachni::OptionGroups::Audit}#inputs is" do + context true do + before do + Arachni::Options.audit.elements :ui_inputs + end - context "and #{Arachni::OptionGroups::Audit}#cookies is" do - context true do - before do - Arachni::Options.audit.elements :cookies + context '<input>' do + context 'with DOM events' do + it 'parses it' do + @browser.load "#{@url}/to_page/input/with_events" - @browser.load "#{@url}/#{page}" - @browser.load "#{@url}/#{page}" - end + input = @browser.to_page.ui_inputs.first - context 'with DOM processing of cookie' do - context 'names' do - let(:page) { 'dom-cookies-names' } + expect(input.action).to eq @browser.url + expect(input.source).to eq '<input oninput="handleOnInput();" id="my-input" name="my-input" value="1">' + expect(input.method).to eq :oninput + end + end - it 'does not set #skip_dom' do - cookies.find { |c| c.name == 'my-cookie' }.skip_dom.should be_nil - cookies.find { |c| c.name == 'my-cookie2' }.skip_dom.should be_nil + context 'without DOM events' do + it 'ignores it' do + @browser.load "#{@url}/to_page/input/without_events" + expect(@browser.to_page.ui_inputs).to be_empty + end end end - context 'values' do - let(:page) { 'dom-cookies-values' } + context '<textarea>' do + context 'with DOM events' do + it 'parses it' do + @browser.load "#{@url}/to_page/textarea/with_events" - it 'does not set #skip_dom' do - cookies.find { |c| c.name == 'my-cookie' }.skip_dom.should be_nil - cookies.find { |c| c.name == 'my-cookie2' }.skip_dom.should be_nil + input = @browser.to_page.ui_inputs.first + + expect(input.action).to eq @browser.url + expect(input.source).to eq '<textarea oninput="handleOnInput();" id="my-input" name="my-input">' + expect(input.method).to eq :oninput + end end + + context 'without DOM events' do + it 'ignores it' do + @browser.load "#{@url}/to_page/textarea/without_events" + expect(@browser.to_page.ui_inputs).to be_empty + end + end end end - context 'without DOM processing of cookie' do - context 'names' do - let(:page) { 'dom-cookies-names' } + context false do + before do + Arachni::Options.audit.skip_elements :ui_inputs + end + it 'ignores them' do + @browser.load "#{@url}/to_page/input/with_events" + expect(@browser.to_page.ui_inputs).to be_empty + end + end + end + end + + context "#{Arachni::Element::Form::DOM} elements" do + context "and #{Arachni::OptionGroups::Audit}#forms is" do + context true do + before do + Arachni::Options.audit.elements :forms + end + + context 'and JavaScript action' do it 'does not set #skip_dom' do - cookies.find { |c| c.name == 'my-cookie3' }.skip_dom.should be_true + @browser.load "#{@url}/each_element_with_events/form/action/javascript" + expect(@browser.to_page.forms.first.skip_dom).to be_nil end end - context 'values' do - let(:page) { 'dom-cookies-values' } - + context 'with DOM events' do it 'does not set #skip_dom' do - cookies.find { |c| c.name == 'my-cookie3' }.skip_dom.should be_true + @browser.load "#{@url}/fire_event/form/onsubmit" + expect(@browser.to_page.forms.first.skip_dom).to be_nil end end + + context 'without DOM events' do + it 'sets #skip_dom to true' do + @browser.load "#{@url}/each_element_with_events/form/action/regular" + expect(@browser.to_page.forms.first.skip_dom).to be_truthy + end + end end + + context false do + before do + Arachni::Options.audit.skip_elements :forms + end + + it 'does not set #skip_dom' do + @browser.load "#{@url}/each_element_with_events/form/action/regular" + expect(@browser.to_page.forms.first.skip_dom).to be_nil + end + end end + end - context false do - before do - Arachni::Options.audit.skip_elements :cookies + context "#{Arachni::Element::Cookie::DOM} elements" do + let(:cookies) { @browser.to_page.cookies } - @browser.load "#{@url}/#{page}" - @browser.load "#{@url}/#{page}" + context "and #{Arachni::OptionGroups::Audit}#cookies is" do + context true do + before do + Arachni::Options.audit.elements :cookies + + @browser.load "#{@url}/#{page}" + @browser.load "#{@url}/#{page}" + end + + context 'with DOM processing of cookie' do + context 'names' do + let(:page) { 'dom-cookies-names' } + + it 'does not set #skip_dom' do + expect(cookies.find { |c| c.name == 'my-cookie' }.skip_dom).to be_nil + expect(cookies.find { |c| c.name == 'my-cookie2' }.skip_dom).to be_nil + end + end + + context 'values' do + let(:page) { 'dom-cookies-values' } + + it 'does not set #skip_dom' do + expect(cookies.find { |c| c.name == 'my-cookie' }.skip_dom).to be_nil + expect(cookies.find { |c| c.name == 'my-cookie2' }.skip_dom).to be_nil + end + end + end + + context 'without DOM processing of cookie' do + context 'names' do + let(:page) { 'dom-cookies-names' } + + it 'does not set #skip_dom' do + expect(cookies.find { |c| c.name == 'my-cookie3' }.skip_dom).to be_truthy + end + end + + context 'values' do + let(:page) { 'dom-cookies-values' } + + it 'does not set #skip_dom' do + expect(cookies.find { |c| c.name == 'my-cookie3' }.skip_dom).to be_truthy + end + end + end end - let(:page) { 'dom-cookies-names' } + context false do + before do + Arachni::Options.audit.skip_elements :cookies - it 'does not set #skip_dom' do - cookies.should be_any - cookies.each do |cookie| - cookie.skip_dom.should be_nil + @browser.load "#{@url}/#{page}" + @browser.load "#{@url}/#{page}" end + + let(:page) { 'dom-cookies-names' } + + it 'does not set #skip_dom' do + expect(cookies).to be_any + cookies.each do |cookie| + expect(cookie.skip_dom).to be_nil + end + end end end end end @@ -1188,14 +1320,14 @@ it 'returns an empty page' do Arachni::Options.url = @url subject.load 'http://google.com/' page = subject.to_page - page.code.should == 0 - page.url.should == subject.url - page.body.should be_empty - page.dom.url.should == subject.watir.url + expect(page.code).to eq(0) + expect(page.url).to eq(subject.url) + expect(page.body).to be_empty + expect(page.dom.url).to eq(subject.watir.url) end end end describe '#fire_event' do @@ -1232,13 +1364,13 @@ context 'when the element is not visible' do it 'returns nil' do element = @browser.watir.div( id: 'my-div' ) - element.stub(:visible?) { false } + allow(element).to receive(:visible?) { false } - @browser.fire_event( element, :click ).should be_nil + expect(@browser.fire_event( element, :click )).to be_nil end end context "when the element is an #{described_class::ElementLocator}" do context 'and could not be located' do @@ -1246,43 +1378,43 @@ element = described_class::ElementLocator.new( tag_name: 'body', attributes: { 'id' => 'blahblah' } ) - element.stub(:locate){ raise Selenium::WebDriver::Error::WebDriverError } - @browser.fire_event( element, :click ).should be_nil + allow(element).to receive(:locate){ raise Selenium::WebDriver::Error::WebDriverError } + expect(@browser.fire_event( element, :click )).to be_nil - element.stub(:locate){ raise Watir::Exception::Error } - @browser.fire_event( element, :click ).should be_nil + allow(element).to receive(:locate){ raise Watir::Exception::Error } + expect(@browser.fire_event( element, :click )).to be_nil end end end context 'when the element never appears' do it 'returns nil' do element = @browser.watir.div( id: 'my-div' ) - element.stub(:exists?) { false } + allow(element).to receive(:exists?) { false } - @browser.fire_event( element, :click ).should be_nil + expect(@browser.fire_event( element, :click )).to be_nil end end context 'when the trigger fails with' do let(:element) { @browser.watir.div( id: 'my-div' ) } context Selenium::WebDriver::Error::WebDriverError do it 'returns nil' do - element.stub(:fire_event){ raise Selenium::WebDriver::Error::WebDriverError } - @browser.fire_event( element, :click ).should be_nil + allow(element).to receive(:fire_event){ raise Selenium::WebDriver::Error::WebDriverError } + expect(@browser.fire_event( element, :click )).to be_nil end end context Watir::Exception::Error do it 'returns nil' do - element.stub(:fire_event){ raise Watir::Exception::Error } - @browser.fire_event( element, :click ).should be_nil + allow(element).to receive(:fire_event){ raise Watir::Exception::Error } + expect(@browser.fire_event( element, :click )).to be_nil end end end context 'form' do @@ -1302,32 +1434,36 @@ before(:each) do @browser.fire_event @browser.watir.form, :submit, inputs: inputs end it 'fills in its inputs with the given values' do - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( inputs[:name] - @browser.watir.div( id: 'container-email' ).text.should == + ) + expect(@browser.watir.div( id: 'container-email' ).text).to eq( inputs[:email] + ) end it 'returns a playable transition' do @browser.load url transition = @browser.fire_event @browser.watir.form, :submit, inputs: inputs @browser.load url - @browser.watir.div( id: 'container-name' ).text.should be_empty - @browser.watir.div( id: 'container-email' ).text.should be_empty + expect(@browser.watir.div( id: 'container-name' ).text).to be_empty + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty transition.play @browser - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( inputs[:name] - @browser.watir.div( id: 'container-email' ).text.should == + ) + expect(@browser.watir.div( id: 'container-email' ).text).to eq( inputs[:email] + ) end context 'when the inputs contains non-UTF8 data' do context 'is given' do let(:inputs) do @@ -1337,132 +1473,144 @@ } end end it 'recodes them' do - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( inputs[:name].recode - @browser.watir.div( id: 'container-email' ).text.should == + ) + expect(@browser.watir.div( id: 'container-email' ).text).to eq( inputs[:email].recode + ) end end context 'when one of those inputs is a' do context 'select' do let(:url) { "#{@url}/fire_event/form/select" } it 'selects it' do - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( inputs[:name] - @browser.watir.div( id: 'container-email' ).text.should == + ) + expect(@browser.watir.div( id: 'container-email' ).text).to eq( inputs[:email] + ) end end end context 'but has missing values' do let(:inputs) do { name: 'The Dude' } end it 'leaves those empty' do - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( inputs[:name] - @browser.watir.div( id: 'container-email' ).text.should be_empty + ) + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty end it 'returns a playable transition' do @browser.load url transition = @browser.fire_event @browser.watir.form, :submit, inputs: inputs @browser.load url - @browser.watir.div( id: 'container-name' ).text.should be_empty - @browser.watir.div( id: 'container-email' ).text.should be_empty + expect(@browser.watir.div( id: 'container-name' ).text).to be_empty + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty transition.play @browser - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( inputs[:name] - @browser.watir.div( id: 'container-email' ).text.should be_empty + ) + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty end end context 'and is empty' do let(:inputs) do {} end it 'fills in empty values' do - @browser.watir.div( id: 'container-name' ).text.should be_empty - @browser.watir.div( id: 'container-email' ).text.should be_empty + expect(@browser.watir.div( id: 'container-name' ).text).to be_empty + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty end it 'returns a playable transition' do @browser.load url transition = @browser.fire_event @browser.watir.form, :submit, inputs: inputs @browser.load url - @browser.watir.div( id: 'container-name' ).text.should be_empty - @browser.watir.div( id: 'container-email' ).text.should be_empty + expect(@browser.watir.div( id: 'container-name' ).text).to be_empty + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty transition.play @browser - @browser.watir.div( id: 'container-name' ).text.should be_empty - @browser.watir.div( id: 'container-email' ).text.should be_empty + expect(@browser.watir.div( id: 'container-name' ).text).to be_empty + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty end end context 'and has disabled inputs' do let(:url) { "#{@url}/fire_event/form/disabled_inputs" } it 'is skips those inputs' do - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( inputs[:name] - @browser.watir.div( id: 'container-email' ).text.should be_empty + ) + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty end end end context 'is not given' do it 'fills in its inputs with sample values' do @browser.load url @browser.fire_event @browser.watir.form, :submit - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( Arachni::Options.input.value_for_name( 'name' ) - @browser.watir.div( id: 'container-email' ).text.should == + ) + expect(@browser.watir.div( id: 'container-email' ).text).to eq( Arachni::Options.input.value_for_name( 'email' ) + ) end it 'returns a playable transition' do @browser.load url transition = @browser.fire_event @browser.watir.form, :submit @browser.load url - @browser.watir.div( id: 'container-name' ).text.should be_empty - @browser.watir.div( id: 'container-email' ).text.should be_empty + expect(@browser.watir.div( id: 'container-name' ).text).to be_empty + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty transition.play @browser - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( Arachni::Options.input.value_for_name( 'name' ) - @browser.watir.div( id: 'container-email' ).text.should == + ) + expect(@browser.watir.div( id: 'container-email' ).text).to eq( Arachni::Options.input.value_for_name( 'email' ) + ) end context 'and has disabled inputs' do let(:url) { "#{@url}/fire_event/form/disabled_inputs" } it 'is skips those inputs' do @browser.fire_event @browser.watir.form, :submit - @browser.watir.div( id: 'container-name' ).text.should == + expect(@browser.watir.div( id: 'container-name' ).text).to eq( Arachni::Options.input.value_for_name( 'name' ) - @browser.watir.div( id: 'container-email' ).text.should be_empty + ) + expect(@browser.watir.div( id: 'container-email' ).text).to be_empty end end end end end @@ -1490,11 +1638,11 @@ pages_should_have_form_with_input captured_pages, 'myImageButton.y' @browser.shutdown @browser = described_class.new.start_capture @browser.load( url ) - @browser.flush_pages.size.should == 1 + expect(@browser.flush_pages.size).to eq(1) transition.play @browser captured_pages = @browser.flush_pages pages_should_have_form_with_input captured_pages, 'myImageButton.x' pages_should_have_form_with_input captured_pages, 'myImageButton.y' @@ -1523,66 +1671,70 @@ before(:each) do @browser.fire_event @browser.watir.input, event, value: value end it 'fills in its inputs with the given values' do - @browser.watir.div( id: 'container' ).text.should == + expect(@browser.watir.div( id: 'container' ).text).to eq( calculate_expectation.call( value ) + ) end it 'returns a playable transition' do @browser.load url transition = @browser.fire_event @browser.watir.input, event, value: value @browser.load url - @browser.watir.div( id: 'container' ).text.should be_empty + expect(@browser.watir.div( id: 'container' ).text).to be_empty transition.play @browser - @browser.watir.div( id: 'container' ).text.should == + expect(@browser.watir.div( id: 'container' ).text).to eq( calculate_expectation.call( value ) + ) end context 'and is empty' do let(:value) do '' end it 'fills in empty values' do - @browser.watir.div( id: 'container' ).text.should be_empty + expect(@browser.watir.div( id: 'container' ).text).to be_empty end it 'returns a playable transition' do @browser.load url transition = @browser.fire_event @browser.watir.input, event, value: value @browser.load url - @browser.watir.div( id: 'container' ).text.should be_empty + expect(@browser.watir.div( id: 'container' ).text).to be_empty transition.play @browser - @browser.watir.div( id: 'container' ).text.should be_empty + expect(@browser.watir.div( id: 'container' ).text).to be_empty end end end context 'is not given' do it 'fills in a sample value' do @browser.fire_event @browser.watir.input, event - @browser.watir.div( id: 'container' ).text.should == + expect(@browser.watir.div( id: 'container' ).text).to eq( calculate_expectation.call( Arachni::Options.input.value_for_name( 'name' ) ) + ) end it 'returns a playable transition' do @browser.load url transition = @browser.fire_event @browser.watir.input, event @browser.load url - @browser.watir.div( id: 'container' ).text.should be_empty + expect(@browser.watir.div( id: 'container' ).text).to be_empty transition.play @browser - @browser.watir.div( id: 'container' ).text.should == + expect(@browser.watir.div( id: 'container' ).text).to eq( calculate_expectation.call( Arachni::Options.input.value_for_name( 'name' ) ) + ) end end end end end @@ -1602,11 +1754,11 @@ elements_with_events end let(:url) { @url + '/trigger_events' } it 'passes each element and event info to the block' do - elements_with_events.should == [ + expect(elements_with_events).to eq([ [ described_class::ElementLocator.new( tag_name: 'body', attributes: { 'onmouseover' => 'makePOST();' } ), @@ -1617,44 +1769,44 @@ tag_name: 'div', attributes: { 'id' => 'my-div', 'onclick' => 'addForm();' } ), [[:onclick, 'addForm();']] ] - ] + ]) end context :a do context 'and the href is not empty' do context 'and it starts with javascript:' do let(:url) { @url + '/each_element_with_events/a/href/javascript' } it 'includes the :click event' do - elements_with_events.should == [ + expect(elements_with_events).to eq([ [ described_class::ElementLocator.new( tag_name: 'a', attributes: { 'href' => 'javascript:doStuff()' } ), [[:click, 'javascript:doStuff()']] ] - ] + ]) end end context 'and it does not start with javascript:' do let(:url) { @url + '/each_element_with_events/a/href/regular' } it 'is ignored' do - elements_with_events.should be_empty + expect(elements_with_events).to be_empty end end context 'and is out of scope' do let(:url) { @url + '/each_element_with_events/a/href/out-of-scope' } it 'is ignored' do - elements_with_events.should be_empty + expect(elements_with_events).to be_empty end end end end @@ -1662,11 +1814,11 @@ context :input do context 'of type "image"' do let(:url) { @url + '/each_element_with_events/form/input/image' } it 'includes the :click event' do - elements_with_events.should == [ + expect(elements_with_events).to eq([ [ described_class::ElementLocator.new( tag_name: 'input', attributes: { 'type' => 'image', @@ -1674,47 +1826,47 @@ 'src' => '/__sinatra__/404.png' } ), [[:click, 'image']] ] - ] + ]) end end end context 'and the action is not empty' do context 'and it starts with javascript:' do let(:url) { @url + '/each_element_with_events/form/action/javascript' } it 'includes the :submit event' do - elements_with_events.should == [ + expect(elements_with_events).to eq([ [ described_class::ElementLocator.new( tag_name: 'form', attributes: { 'action' => 'javascript:doStuff()' } ), [[:submit, 'javascript:doStuff()']] ] - ] + ]) end end context 'and it does not start with javascript:' do let(:url) { @url + '/each_element_with_events/form/action/regular' } it 'is ignored'do - elements_with_events.should be_empty + expect(elements_with_events).to be_empty end end context 'and is out of scope' do let(:url) { @url + '/each_element_with_events/form/action/out-of-scope' } it 'is ignored'do - elements_with_events.should be_empty + expect(elements_with_events).to be_empty end end end end end @@ -1762,11 +1914,11 @@ pages_should_have_form_with_input @browser.captured_pages, 'post-name' end it 'assigns the proper page transitions' do pages = @browser.load( @url + '/explore' ).trigger_events.page_snapshots - pages.map(&:dom).map(&:transitions).should == [ + expect(pages.map(&:dom).map(&:transitions)).to eq([ [ { :page => :load }, { "#{@url}explore" => :request } ], [ @@ -1794,11 +1946,11 @@ } } => :click }, { "#{@url}href-ajax" => :request }, ] - ].map { |transitions| transitions_from_array( transitions ) } + ].map { |transitions| transitions_from_array( transitions ) }) end it 'follows all javascript links' do @browser.load( @url + '/explore' ).start_capture.trigger_events @@ -1823,84 +1975,84 @@ pages_should_have_form_with_input @browser.captured_pages, 'myImageButton.y' end end it 'returns self' do - @browser.load( @url + '/explore' ).trigger_events.should == @browser + expect(@browser.load( @url + '/explore' ).trigger_events).to eq(@browser) end end describe '#source' do it 'returns the evaluated HTML source' do @browser.load @url ua = Arachni::Options.http.user_agent - ua.should_not be_empty + expect(ua).not_to be_empty - @browser.source.should include( ua ) + expect(@browser.source).to include( ua ) end end describe '#watir' do it 'provides access to the Watir::Browser API' do - @browser.watir.should be_kind_of Watir::Browser + expect(@browser.watir).to be_kind_of Watir::Browser end end describe '#selenium' do it 'provides access to the Selenium::WebDriver::Driver API' do - @browser.selenium.should be_kind_of Selenium::WebDriver::Driver + expect(@browser.selenium).to be_kind_of Selenium::WebDriver::Driver end end describe '#goto' do it 'loads the given URL' do @browser.goto @url ua = Arachni::Options.http.user_agent - ua.should_not be_empty + expect(ua).not_to be_empty - @browser.source.should include( ua ) + expect(@browser.source).to include( ua ) end it 'returns a playable transition' do transition = @browser.goto( @url ) @browser.shutdown @browser = described_class.new transition.play( @browser ) ua = Arachni::Options.http.user_agent - ua.should_not be_empty + expect(ua).not_to be_empty - @browser.source.should include( ua ) + expect(@browser.source).to include( ua ) end it 'puts the domain in the asset domains list' do subject.goto @url - described_class.asset_domains.should include Arachni::URI( @url ).domain + expect(described_class.asset_domains).to include Arachni::URI( @url ).domain end context 'when requesting the page URL' do it 'does not send If-None-Match request headers' do subject.goto "#{@url}/If-None-Match" - subject.response.code.should == 200 - subject.response.request.headers.should_not include 'If-None-Match' + expect(subject.response.code).to eq(200) + expect(subject.response.request.headers).not_to include 'If-None-Match' subject.goto "#{@url}/If-None-Match" - subject.response.code.should == 200 - subject.response.request.headers.should_not include 'If-None-Match' + expect(subject.response.code).to eq(200) + expect(subject.response.request.headers).not_to include 'If-None-Match' end it 'does not send If-Modified-Since request headers' do subject.goto "#{@url}/If-Modified-Since" - subject.response.code.should == 200 - subject.response.request.headers.should_not include 'If-Modified-Since' + expect(subject.response.code).to eq(200) + expect(subject.response.request.headers).not_to include 'If-Modified-Since' subject.goto "#{@url}/If-Modified-Since" - subject.response.code.should == 200 - subject.response.request.headers.should_not include 'If-Modified-Since' + expect(subject.response.code).to eq(200) + expect(subject.response.request.headers).not_to include 'If-Modified-Since' end end context 'when requesting something other than the page URL' do it 'sends If-None-Match request headers' do @@ -1911,14 +2063,14 @@ next if r.url == url response = r end subject.goto url - response.request.headers.should_not include 'If-None-Match' + expect(response.request.headers).not_to include 'If-None-Match' subject.goto url - response.request.headers.should include 'If-None-Match' + expect(response.request.headers).to include 'If-None-Match' end it 'sends If-Modified-Since request headers' do url = "#{@url}If-Modified-Since" @@ -1927,14 +2079,14 @@ next if r.url == url response = r end subject.goto url - response.request.headers.should_not include 'If-Modified-Since' + expect(response.request.headers).not_to include 'If-Modified-Since' subject.goto url - response.request.headers.should include 'If-Modified-Since' + expect(response.request.headers).to include 'If-Modified-Since' end end context 'when the page requires an asset' do before do @@ -1947,11 +2099,11 @@ %w(link input script img).each do |type| context 'via link' do let(:url) { "#{super()}/#{type}" } it 'whitelists it' do - described_class.asset_domains.should include "#{type}.stuff" + expect(described_class.asset_domains).to include "#{type}.stuff" end end end context 'with an extension of' do @@ -1977,39 +2129,52 @@ it 'waits for them to complete' do time = Time.now subject.goto "#{@url}load_delay" waited = Time.now - time - waited.should >= subject.load_delay / 1000.0 + expect(waited).to be >= subject.load_delay / 1000.0 end end context 'when there are outstanding HTTP requests' do it 'waits for them to complete' do sleep_time = 5 time = Time.now subject.goto "#{@url}/ajax_sleep?sleep=#{sleep_time}" - (Time.now - time).should >= sleep_time + expect(Time.now - time).to be >= sleep_time end context "when requests takes more than #{Arachni::OptionGroups::HTTP}#request_timeout" do it 'returns false' do sleep_time = 5 Arachni::Options.http.request_timeout = 1_000 - Arachni::HTTP::ProxyServer.any_instance.stub(:has_connections?){ true } + allow_any_instance_of(Arachni::HTTP::ProxyServer).to receive(:has_connections?){ true } time = Time.now subject.goto "#{@url}/ajax_sleep?sleep=#{sleep_time}" - (Time.now - time).should < sleep_time + expect(Time.now - time).to be < sleep_time end end end + context "with #{Arachni::OptionGroups::BrowserCluster}#local_storage" do + before do + Arachni::Options.browser_cluster.local_storage = { + 'name' => 'value' + } + end + + it 'sets the data as local storage' do + subject.load @url + expect( subject.javascript.run( 'return localStorage.getItem( "name" )' ) ).to eq 'value' + end + end + context "with #{Arachni::OptionGroups::BrowserCluster}#wait_for_elements" do before do Arachni::Options.browser_cluster.wait_for_elements = { 'stuff' => '#matchThis' } @@ -2017,21 +2182,21 @@ context 'when the URL matches a pattern' do it 'waits for the element matching the CSS to appear' do t = Time.now @browser.goto( @url + '/wait_for_elements#stuff/here' ) - (Time.now - t).should > 5 + expect(Time.now - t).to be > 5 - @browser.watir.element( css: '#matchThis' ).tag_name.should == 'button' + expect(@browser.watir.element( css: '#matchThis' ).tag_name).to eq('button') end it "waits a maximum of #{Arachni::OptionGroups::BrowserCluster}#job_timeout" do Arachni::Options.browser_cluster.job_timeout = 4 t = Time.now @browser.goto( @url + '/wait_for_elements#stuff/here' ) - (Time.now - t).should < 5 + expect(Time.now - t).to be < 5 expect do @browser.watir.element( css: '#matchThis' ).tag_name end.to raise_error Watir::Exception::UnknownObjectException end @@ -2039,11 +2204,11 @@ context 'when the URL does not match any patterns' do it 'does not wait' do t = Time.now @browser.goto( @url + '/wait_for_elements' ) - (Time.now - t).should < 5 + expect(Time.now - t).to be < 5 expect do @browser.watir.element( css: '#matchThis' ).tag_name end.to raise_error Watir::Exception::UnknownObjectException end @@ -2057,11 +2222,11 @@ @browser.shutdown @browser = described_class.new( disk_cache: false ) @browser.load( "#{@url}form-with-image-button" ) - image_hit_count.should == 0 + expect(image_hit_count).to eq(0) end end context false do it 'loads images' do @@ -2069,11 +2234,11 @@ @browser.shutdown @browser = described_class.new( disk_cache: false ) @browser.load( "#{@url}form-with-image-button" ) - image_hit_count.should == 1 + expect(image_hit_count).to eq(1) end end end context "with #{Arachni::OptionGroups::Scope}#exclude_path_patterns" do @@ -2092,196 +2257,196 @@ end context "with #{Arachni::OptionGroups::Scope}#redundant_path_patterns" do it 'respects scope restrictions' do Arachni::Options.scope.redundant_path_patterns = { 'explore' => 0 } - @browser.load( @url + '/explore' ).response.code.should == 0 + expect(@browser.load( @url + '/explore' ).response.code).to eq(0) end end context "with #{Arachni::OptionGroups::Scope}#auto_redundant_paths has bee configured" do it 'respects scope restrictions' do Arachni::Options.scope.auto_redundant_paths = 0 - @browser.load( @url + '/explore?test=1&test2=2' ).response.code.should == 0 + expect(@browser.load( @url + '/explore?test=1&test2=2' ).response.code).to eq(0) end end describe :cookies do it 'loads the given cookies' do cookie = { 'myname' => 'myvalue' } @browser.goto @url, cookies: cookie - @browser.cookies.find { |c| c.name == cookie.keys.first }.inputs.should == cookie + expect(@browser.cookies.find { |c| c.name == cookie.keys.first }.inputs).to eq(cookie) end it 'includes them in the transition' do cookie = { 'myname' => 'myvalue' } transition = @browser.goto( @url, cookies: cookie ) - transition.options[:cookies].should == cookie + expect(transition.options[:cookies]).to eq(cookie) end context 'when auditing existing cookies' do it 'preserves the HttpOnly attribute' do @browser.goto( @url ) - @browser.cookies.size.should == 1 + expect(@browser.cookies.size).to eq(1) cookies = { @browser.cookies.first.name => 'updated' } @browser.goto( @url, cookies: cookies ) @browser.cookies.first.value == 'updated' - @browser.cookies.first.should be_http_only + expect(@browser.cookies.first).to be_http_only end end end describe :take_snapshot do describe true do it 'captures a snapshot of the loaded page' do @browser.goto @url, take_snapshot: true pages = @browser.page_snapshots - pages.size.should == 1 + expect(pages.size).to eq(1) - pages.first.dom.transitions.should == transitions_from_array([ + expect(pages.first.dom.transitions).to eq(transitions_from_array([ { page: :load }, { @url => :request } - ]) + ])) end end describe false do it 'does not capture a snapshot of the loaded page' do @browser.goto @url, take_snapshot: false - @browser.page_snapshots.should be_empty + expect(@browser.page_snapshots).to be_empty end end describe 'default' do it 'captures a snapshot of the loaded page' do @browser.goto @url pages = @browser.page_snapshots - pages.size.should == 1 + expect(pages.size).to eq(1) - pages.first.dom.transitions.should == transitions_from_array([ + expect(pages.first.dom.transitions).to eq(transitions_from_array([ { page: :load }, { @url => :request } - ]) + ])) end end end describe :update_transitions do describe true do it 'pushes the page load to the transitions' do t = @browser.goto( @url, update_transitions: true ) - @browser.to_page.dom.transitions.should include t + expect(@browser.to_page.dom.transitions).to include t end end describe false do it 'does not push the page load to the transitions' do t = @browser.goto( @url, update_transitions: false ) - @browser.to_page.dom.transitions.should be_empty + expect(@browser.to_page.dom.transitions).to be_empty end end describe 'default' do it 'pushes the page load to the transitions' do t = @browser.goto( @url ) - @browser.to_page.dom.transitions.should include t + expect(@browser.to_page.dom.transitions).to include t end end end end describe '#load' do it 'returns self' do - @browser.load( @url ).should == @browser + expect(@browser.load( @url )).to eq(@browser) end describe :cookies do it 'loads the given cookies' do cookie = { 'myname' => 'myvalue' } @browser.load @url, cookies: cookie - @browser.cookies.find { |c| c.name == cookie.keys.first }.inputs.should == cookie + expect(@browser.cookies.find { |c| c.name == cookie.keys.first }.inputs).to eq(cookie) end end describe :take_snapshot do describe true do it 'captures a snapshot of the loaded page' do @browser.load @url, take_snapshot: true pages = @browser.page_snapshots - pages.size.should == 1 + expect(pages.size).to eq(1) - pages.first.dom.transitions.should == transitions_from_array([ + expect(pages.first.dom.transitions).to eq(transitions_from_array([ { page: :load }, { @url => :request } - ]) + ])) end end describe false do it 'does not capture a snapshot of the loaded page' do @browser.load @url, take_snapshot: false - @browser.page_snapshots.should be_empty + expect(@browser.page_snapshots).to be_empty end end describe 'default' do it 'captures a snapshot of the loaded page' do @browser.load @url pages = @browser.page_snapshots - pages.size.should == 1 + expect(pages.size).to eq(1) - pages.first.dom.transitions.should == transitions_from_array([ + expect(pages.first.dom.transitions).to eq(transitions_from_array([ { page: :load }, { @url => :request } - ]) + ])) end end end context 'when given a' do describe String do it 'treats it as a URL' do - hit_count.should == 0 + expect(hit_count).to eq(0) @browser.load @url - @browser.source.should include( ua ) - @browser.preloads.should_not include( @url ) + expect(@browser.source).to include( ua ) + expect(@browser.preloads).not_to include( @url ) - hit_count.should == 1 + expect(hit_count).to eq(1) end end describe Arachni::HTTP::Response do it 'loads it' do - hit_count.should == 0 + expect(hit_count).to eq(0) @browser.load Arachni::HTTP::Client.get( @url, mode: :sync ) - @browser.source.should include( ua ) - @browser.preloads.should_not include( @url ) + expect(@browser.source).to include( ua ) + expect(@browser.preloads).not_to include( @url ) - hit_count.should == 1 + expect(hit_count).to eq(1) end end describe Arachni::Page do it 'loads it' do - hit_count.should == 0 + expect(hit_count).to eq(0) @browser.load Arachni::HTTP::Client.get( @url, mode: :sync ).to_page - @browser.source.should include( ua ) - @browser.preloads.should_not include( @url ) + expect(@browser.source).to include( ua ) + expect(@browser.preloads).not_to include( @url ) - hit_count.should == 1 + expect(hit_count).to eq(1) end it 'uses its #cookie_jar' do - @browser.cookies.should be_empty + expect(@browser.cookies).to be_empty page = Arachni::Page.from_data( url: @url, cookie_jar: [ Arachni::Cookie.new( @@ -2292,41 +2457,41 @@ ) ] ) @browser.load( page ) - @browser.cookies.should == page.cookie_jar + expect(@browser.cookies).to eq(page.cookie_jar) end it 'replays its DOM#transitions' do @browser.load "#{@url}play-transitions" page = @browser.explore_and_flush.last - page.body.should include ua + expect(page.body).to include ua @browser.load page - @browser.source.should include ua + expect(@browser.source).to include ua page.dom.transitions.clear @browser.load page - @browser.source.should_not include ua + expect(@browser.source).not_to include ua end it 'loads its DOM#skip_states' do @browser.load( @url ) pages = @browser.load( @url + '/explore' ).trigger_events. page_snapshots page = pages.last - page.dom.skip_states.should be_subset @browser.skip_states + expect(page.dom.skip_states).to be_subset @browser.skip_states token = @browser.generate_token dpage = page.dup dpage.dom.skip_states << token @browser.load dpage - @browser.skip_states.should include token + expect(@browser.skip_states).to include token end end describe 'other' do @@ -2340,64 +2505,64 @@ describe '#preload' do it 'removes entries after they are used' do @browser.preload Arachni::HTTP::Client.get( @url, mode: :sync ) clear_hit_count - hit_count.should == 0 + expect(hit_count).to eq(0) @browser.load @url - @browser.source.should include( ua ) - @browser.preloads.should_not include( @url ) + expect(@browser.source).to include( ua ) + expect(@browser.preloads).not_to include( @url ) - hit_count.should == 0 + expect(hit_count).to eq(0) 2.times do @browser.load @url - @browser.source.should include( ua ) + expect(@browser.source).to include( ua ) end - @browser.preloads.should_not include( @url ) + expect(@browser.preloads).not_to include( @url ) - hit_count.should == 2 + expect(hit_count).to eq(2) end it 'returns the URL of the resource' do response = Arachni::HTTP::Client.get( @url, mode: :sync ) - @browser.preload( response ).should == response.url + expect(@browser.preload( response )).to eq(response.url) @browser.load response.url - @browser.source.should include( ua ) + expect(@browser.source).to include( ua ) end context 'when given a' do describe Arachni::HTTP::Response do it 'preloads it' do @browser.preload Arachni::HTTP::Client.get( @url, mode: :sync ) clear_hit_count - hit_count.should == 0 + expect(hit_count).to eq(0) @browser.load @url - @browser.source.should include( ua ) - @browser.preloads.should_not include( @url ) + expect(@browser.source).to include( ua ) + expect(@browser.preloads).not_to include( @url ) - hit_count.should == 0 + expect(hit_count).to eq(0) end end describe Arachni::Page do it 'preloads it' do @browser.preload Arachni::Page.from_url( @url ) clear_hit_count - hit_count.should == 0 + expect(hit_count).to eq(0) @browser.load @url - @browser.source.should include( ua ) - @browser.preloads.should_not include( @url ) + expect(@browser.source).to include( ua ) + expect(@browser.preloads).not_to include( @url ) - hit_count.should == 0 + expect(hit_count).to eq(0) end end describe 'other' do it 'raises Arachni::Browser::Error::Load' do @@ -2410,65 +2575,65 @@ describe '#cache' do it 'keeps entries after they are used' do @browser.cache Arachni::HTTP::Client.get( @url, mode: :sync ) clear_hit_count - hit_count.should == 0 + expect(hit_count).to eq(0) @browser.load @url - @browser.source.should include( ua ) - @browser.cache.should include( @url ) + expect(@browser.source).to include( ua ) + expect(@browser.cache).to include( @url ) - hit_count.should == 0 + expect(hit_count).to eq(0) 2.times do @browser.load @url - @browser.source.should include( ua ) + expect(@browser.source).to include( ua ) end - @browser.cache.should include( @url ) + expect(@browser.cache).to include( @url ) - hit_count.should == 0 + expect(hit_count).to eq(0) end it 'returns the URL of the resource' do response = Arachni::HTTP::Client.get( @url, mode: :sync ) - @browser.cache( response ).should == response.url + expect(@browser.cache( response )).to eq(response.url) @browser.load response.url - @browser.source.should include( ua ) - @browser.cache.should include( response.url ) + expect(@browser.source).to include( ua ) + expect(@browser.cache).to include( response.url ) end context 'when given a' do describe Arachni::HTTP::Response do it 'caches it' do @browser.cache Arachni::HTTP::Client.get( @url, mode: :sync ) clear_hit_count - hit_count.should == 0 + expect(hit_count).to eq(0) @browser.load @url - @browser.source.should include( ua ) - @browser.cache.should include( @url ) + expect(@browser.source).to include( ua ) + expect(@browser.cache).to include( @url ) - hit_count.should == 0 + expect(hit_count).to eq(0) end end describe Arachni::Page do it 'caches it' do @browser.cache Arachni::Page.from_url( @url ) clear_hit_count - hit_count.should == 0 + expect(hit_count).to eq(0) @browser.load @url - @browser.source.should include( ua ) - @browser.cache.should include( @url ) + expect(@browser.source).to include( ua ) + expect(@browser.cache).to include( @url ) - hit_count.should == 0 + expect(hit_count).to eq(0) end end describe 'other' do it 'raises Arachni::Browser::Error::Load' do @@ -2484,25 +2649,25 @@ it 'parses requests into elements of pages' do @browser.load @url + '/with-ajax' pages = @browser.captured_pages - pages.size.should == 2 + expect(pages.size).to eq(2) page = pages.first - page.forms.find { |form| form.inputs.include? 'ajax-token' }.should be_true + expect(page.forms.find { |form| form.inputs.include? 'ajax-token' }).to be_truthy end context 'when an element has already been seen' do context 'by the browser' do it 'ignores it' do @browser.load @url + '/with-ajax' - @browser.captured_pages.size.should == 2 + expect(@browser.captured_pages.size).to eq(2) @browser.captured_pages.clear @browser.load @url + '/with-ajax' - @browser.captured_pages.should be_empty + expect(@browser.captured_pages).to be_empty end end context "by the #{Arachni::ElementFilter}" do it 'ignores it' do @@ -2510,82 +2675,82 @@ Arachni::ElementFilter.update_forms @browser.captured_pages.map(&:forms).flatten @browser.shutdown @browser = described_class.new @browser.load @url + '/with-ajax' - @browser.captured_pages.should be_empty + expect(@browser.captured_pages).to be_empty end end end context 'when a GET request is performed' do it "is added as an #{Arachni::Element::Form} to the page" do @browser.load @url + '/with-ajax' pages = @browser.captured_pages - pages.size.should == 2 + expect(pages.size).to eq(2) page = pages.first form = page.forms.find { |form| form.inputs.include? 'ajax-token' } - form.url.should == @url + 'with-ajax' - form.action.should == @url + 'get-ajax' - form.inputs.should == { 'ajax-token' => 'my-token' } - form.method.should == :get + expect(form.url).to eq(@url + 'with-ajax') + expect(form.action).to eq(@url + 'get-ajax') + expect(form.inputs).to eq({ 'ajax-token' => 'my-token' }) + expect(form.method).to eq(:get) end end context 'when a POST request is performed' do context 'with form data' do it "is added as an #{Arachni::Element::Form} to the page" do @browser.load @url + '/with-ajax' pages = @browser.captured_pages - pages.size.should == 2 + expect(pages.size).to eq(2) form = find_page_with_form_with_input( pages, 'post-name' ). forms.find { |form| form.inputs.include? 'post-name' } - form.url.should == @url + 'with-ajax' - form.action.should == @url + 'post-ajax' - form.inputs.should == { 'post-name' => 'post-value' } - form.method.should == :post + expect(form.url).to eq(@url + 'with-ajax') + expect(form.action).to eq(@url + 'post-ajax') + expect(form.inputs).to eq({ 'post-name' => 'post-value' }) + expect(form.method).to eq(:post) end end context 'with JSON data' do it "is added as an #{Arachni::Element::JSON} to the page" do @browser.load @url + '/with-ajax-json' pages = @browser.captured_pages - pages.size.should == 1 + expect(pages.size).to eq(1) form = find_page_with_json_with_input( pages, 'post-name' ). jsons.find { |json| json.inputs.include? 'post-name' } - form.url.should == @url + 'with-ajax-json' - form.action.should == @url + 'post-ajax' - form.inputs.should == { 'post-name' => 'post-value' } - form.method.should == :post + expect(form.url).to eq(@url + 'with-ajax-json') + expect(form.action).to eq(@url + 'post-ajax') + expect(form.inputs).to eq({ 'post-name' => 'post-value' }) + expect(form.method).to eq(:post) end end context 'with XML data' do it "is added as an #{Arachni::Element::XML} to the page" do @browser.load @url + '/with-ajax-xml' pages = @browser.captured_pages - pages.size.should == 1 + expect(pages.size).to eq(1) form = find_page_with_xml_with_input( pages, 'input > text()' ). xmls.find { |xml| xml.inputs.include? 'input > text()' } - form.url.should == @url + 'with-ajax-xml' - form.action.should == @url + 'post-ajax' - form.inputs.should == { 'input > text()' => 'stuff' } - form.method.should == :post + expect(form.url).to eq(@url + 'with-ajax-xml') + expect(form.action).to eq(@url + 'post-ajax') + expect(form.inputs).to eq({ 'input > text()' => 'stuff' }) + expect(form.method).to eq(:post) end end end end @@ -2593,74 +2758,74 @@ it 'flushes the captured pages' do @browser.start_capture @browser.load @url + '/with-ajax' pages = @browser.flush_pages - pages.size.should == 3 - @browser.flush_pages.should be_empty + expect(pages.size).to eq(3) + expect(@browser.flush_pages).to be_empty end end describe '#stop_capture' do it 'stops the page capture' do @browser.stop_capture - @browser.capture?.should be_false + expect(@browser.capture?).to be_falsey end end describe 'capture?' do it 'returns false' do @browser.start_capture @browser.stop_capture - @browser.capture?.should be_false + expect(@browser.capture?).to be_falsey end context 'when capturing pages' do it 'returns true' do @browser.start_capture - @browser.capture?.should be_true + expect(@browser.capture?).to be_truthy end end context 'when not capturing pages' do it 'returns false' do @browser.start_capture @browser.stop_capture - @browser.capture?.should be_false + expect(@browser.capture?).to be_falsey end end end describe '#cookies' do it 'returns the browser cookies' do @browser.load @url - @browser.cookies.size.should == 1 + expect(@browser.cookies.size).to eq(1) cookie = @browser.cookies.first - cookie.should be_kind_of Arachni::Cookie - cookie.name.should == 'This name should be updated; and properly escaped' - cookie.value.should == 'This value should be updated; and properly escaped' + expect(cookie).to be_kind_of Arachni::Cookie + expect(cookie.name).to eq('This name should be updated; and properly escaped') + expect(cookie.value).to eq('This value should be updated; and properly escaped') end it 'preserves the HttpOnly attribute' do @browser.load @url - @browser.cookies.first.should be_http_only + expect(@browser.cookies.first).to be_http_only end context 'when parsing v1 cookies' do it 'removes the quotes' do cookie = 'rsession="06142010_0%3Ae275d357943e9a2de0"' @browser.load @url @browser.javascript.run( "document.cookie = '#{cookie}';" ) - @browser.cookies.first.value.should == '06142010_0:e275d357943e9a2de0' + expect(@browser.cookies.first.value).to eq('06142010_0:e275d357943e9a2de0') end end context 'when no page is available' do it 'returns an empty Array' do - @browser.cookies.should be_empty + expect(@browser.cookies).to be_empty end end end describe '#snapshot_id' do @@ -2675,45 +2840,45 @@ end let(:url) { @url + '/trigger_events' } it 'returns a DOM digest' do - snapshot_id.should == @browser.load( url ).snapshot_id + expect(snapshot_id).to eq(@browser.load( url ).snapshot_id) end context :a do context 'and the href is not empty' do context 'and it starts with javascript:' do let(:url) { @url + '/each_element_with_events/a/href/javascript' } it 'takes it into account' do - snapshot_id.should_not == empty_snapshot_id + expect(snapshot_id).not_to eq(empty_snapshot_id) end end context 'and it does not start with javascript:' do let(:url) { @url + '/each_element_with_events/a/href/regular' } it 'takes it into account' do - snapshot_id.should_not == empty_snapshot_id + expect(snapshot_id).not_to eq(empty_snapshot_id) end end context 'and is out of scope' do let(:url) { @url + '/each_element_with_events/a/href/out-of-scope' } it 'is ignored' do - snapshot_id.should == empty_snapshot_id + expect(snapshot_id).to eq(empty_snapshot_id) end end end context 'and the href is empty' do let(:url) { @url + '/each_element_with_events/a/href/empty' } it 'takes it into account' do - snapshot_id.should_not == empty_snapshot_id + expect(snapshot_id).not_to eq(empty_snapshot_id) end end end context :form do @@ -2722,36 +2887,36 @@ context :input do context 'of type "image"' do let(:url) { @url + '/each_element_with_events/form/input/image' } it 'takes it into account' do - snapshot_id.should_not == empty_snapshot_id + expect(snapshot_id).not_to eq(empty_snapshot_id) end end end context 'and the action is not empty' do context 'and it starts with javascript:' do let(:url) { @url + '/each_element_with_events/form/action/javascript' } it 'takes it into account' do - snapshot_id.should_not == empty_snapshot_id + expect(snapshot_id).not_to eq(empty_snapshot_id) end end context 'and it does not start with javascript:' do let(:url) { @url + '/each_element_with_events/form/action/regular' } it 'takes it into account' do - snapshot_id.should_not == empty_snapshot_id + expect(snapshot_id).not_to eq(empty_snapshot_id) end end context 'and is out of scope' do let(:url) { @url + '/each_element_with_events/form/action/out-of-scope' } it 'is ignored' do - snapshot_id.should == empty_snapshot_id + expect(snapshot_id).to eq(empty_snapshot_id) end end end end end