spec/arachni/browser_spec.rb in arachni-1.5.1 vs spec/arachni/browser_spec.rb in arachni-1.6.0

- old
+ new

@@ -18,11 +18,11 @@ described_class.asset_domains.clear clear_hit_count end let(:subject) { @browser } - let(:ua) { described_class::USER_AGENT } + let(:ua) { Arachni::Options.http.user_agent } def transitions_from_array( transitions ) transitions.map do |t| element, event = t.first.to_a @@ -59,74 +59,10 @@ pages_should_have_form_with_input( pages, 'ajax-token' ) pages_should_have_form_with_input( pages, 'by-ajax' ) end - context 'when the browser dies' do - it 'kills the lifeline too' do - Arachni::Processes::Manager.kill subject.browser_pid - expect(Arachni::Processes::Manager.alive?(subject.lifeline_pid)).to be_falsey - end - end - - context 'when the lifeline dies' do - it 'kills the browser too' do - Arachni::Processes::Manager.kill subject.lifeline_pid - expect(Arachni::Processes::Manager.alive?(subject.browser_pid)).to be_falsey - end - end - - describe '#alive?' do - context 'when the lifeline is alive' do - it 'returns true' do - expect(Arachni::Processes::Manager.alive?(subject.lifeline_pid)).to be_truthy - expect(subject).to be_alive - end - end - - context 'when the browser is dead' do - it 'returns false' do - Arachni::Processes::Manager.kill subject.browser_pid - - expect(subject).to_not be_alive - end - end - - context 'when the lifeline is dead' do - it 'returns false' do - Arachni::Processes::Manager << subject.browser_pid - Arachni::Processes::Manager.kill subject.lifeline_pid - - expect(subject).to_not be_alive - end - end - end - - describe '.has_executable?' do - context 'when there is no executable browser' do - it 'returns false' do - 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 - 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__ - allow(Selenium::WebDriver::PhantomJS).to receive(:path){ stub } - expect(described_class.executable).to eq(stub) - end - end - describe '#initialize' do describe ':concurrency' do it 'sets the HTTP request concurrency' end @@ -253,17 +189,10 @@ @browser.start_capture 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 - 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 describe '#source_with_line_numbers' do it 'prefixes each source code line with a number' do subject.load @url @@ -777,16 +706,16 @@ entry = doms[0].execution_flow_sinks[0] expect(entry.data).to eq([1]) 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 - 1]).to include 'log_execution_flow_sink(1)' + 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]) 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 - 1]).to include 'onClick' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick' expect(entry.trace[1].function.arguments).to eq(%w(blah1 blah2 blah3)) expect(entry.trace[2].function.name).to eq('onmouseover') expect(entry.trace[2].function.source).to start_with 'function onmouseover' @@ -800,21 +729,21 @@ entry = doms[0].execution_flow_sinks[1] expect(entry.data).to eq([1]) 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 - 1]).to include 'log_execution_flow_sink(1)' + 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 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 - 1]).to include 'onClick3' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick3' expect(entry.trace[1].function.arguments).to eq([1, 2]) 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 - 1]).to include 'onClick' + expect(@browser.source.split("\n")[entry.trace[2].line]).to include 'onClick' expect(entry.trace[2].function.arguments).to eq(%w(blah1 blah2 blah3)) expect(entry.trace[3].function.name).to eq('onmouseover') expect(entry.trace[3].function.source).to start_with 'function onmouseover' @@ -844,16 +773,16 @@ entry = doms[1].execution_flow_sinks[0] expect(entry.data).to eq([1]) 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 - 1]).to include 'log_execution_flow_sink(1)' + 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)) 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 - 1]).to include 'onClick' + 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>" expect(event['target']).to eq(form) @@ -863,21 +792,21 @@ entry = doms[1].execution_flow_sinks[1] expect(entry.data).to eq([1]) 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 - 1]).to include 'log_execution_flow_sink(1)' + 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 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 - 1]).to include 'onClick3()' + 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)) 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 - 1]).to include 'onClick(' + 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>" expect(event['target']).to eq(form) @@ -900,16 +829,16 @@ entry = doms[0].data_flow_sinks[0] expect(entry.function).to eq('blah') 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 - 1]).to include 'log_data_flow_sink(' + 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]) 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 - 1]).to include 'onClick' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick' expect(entry.trace[1].function.arguments).to eq(%w(blah1 blah2 blah3)) expect(entry.trace[2].function.name).to eq('onmouseover') expect(entry.trace[2].function.source).to start_with 'function onmouseover' @@ -923,21 +852,21 @@ entry = doms[0].data_flow_sinks[1] expect(entry.function).to eq('blah') 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 - 1]).to include 'log_data_flow_sink(' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_data_flow_sink(' expect(entry.trace[0].function.arguments).to be_empty 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 - 1]).to include 'onClick3' + expect(@browser.source.split("\n")[entry.trace[1].line]).to include 'onClick3' expect(entry.trace[1].function.arguments).to eq([1, 2]) 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 - 1]).to include 'onClick' + expect(@browser.source.split("\n")[entry.trace[2].line]).to include 'onClick' expect(entry.trace[2].function.arguments).to eq(%w(blah1 blah2 blah3)) expect(entry.trace[3].function.name).to eq('onmouseover') expect(entry.trace[3].function.source).to start_with 'function onmouseover' @@ -953,16 +882,16 @@ entry = doms[1].data_flow_sinks[0] expect(entry.function).to eq('blah') 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 - 1]).to include 'log_data_flow_sink(' + 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)) 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 - 1]).to include 'onClick' + 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>" expect(event['target']).to eq(form) @@ -972,21 +901,21 @@ entry = doms[1].data_flow_sinks[1] expect(entry.function).to eq('blah') 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 - 1]).to include 'log_data_flow_sink(' + expect(@browser.source.split("\n")[entry.trace[0].line]).to include 'log_data_flow_sink(' expect(entry.trace[0].function.arguments).to be_empty 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 - 1]).to include 'onClick3()' + 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)) 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 - 1]).to include 'onClick(' + 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>" expect(event['target']).to eq(form) @@ -1094,15 +1023,15 @@ expect(page.body).to include( ua ) end it "assigns the proper #{Arachni::Page::DOM}#digest" do @browser.load( @url ) - expect(@browser.to_page.dom.digest).to eq(32000153) + expect(@browser.to_page.dom.digest).to eq(-2125129228) # expect(@browser.to_page.dom.instance_variable_get(:@digest)).to eq( - # '<HTML><HEAD><SCRIPT src=http://' << - # 'javascript.browser.arachni/polyfills.js><SCRIPT src=http://' << + # '<HTML><HEAD><SCRIPT src=https://' << + # 'javascript.browser.arachni/polyfills.js><SCRIPT src=https://' << # '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>' # ) @@ -1146,16 +1075,16 @@ expect(first_entry.data).to eq([1]) 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 - 1]).to include 'log_execution_flow_sink(1)' + 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)) 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 - 1]).to include 'onClick(' + 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>" @@ -1178,11 +1107,11 @@ @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.source).to eq '<input id="insert" type="button">' expect(input.method).to eq :click end end context 'without DOM events' do @@ -1241,11 +1170,11 @@ @browser.load "#{@url}/to_page/input/with_events" input = @browser.to_page.ui_inputs.first 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.source).to eq '<input id="my-input" name="my-input" oninput="handleOnInput();" value="1">' expect(input.method).to eq :input end end context 'without DOM events' do @@ -1262,11 +1191,11 @@ @browser.load "#{@url}/to_page/textarea/with_events" 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.source).to eq '<textarea id="my-input" name="my-input" oninput="handleOnInput();">' expect(input.method).to eq :input end end context 'without DOM events' do @@ -1442,19 +1371,19 @@ context 'when the resource is out-of-scope' do it 'returns an empty page' do Arachni::Options.url = @url subject.load @url - subject.javascript.run( 'window.location = "http://google.com/";' ) + subject.javascript.run( 'window.location = "http://www.google.com/";' ) sleep 1 page = subject.to_page expect(page.code).to eq(0) - expect(page.url).to eq('http://google.com/') + expect(page.url).to eq('http://www.google.com/') expect(page.body).to be_empty - expect(page.dom.url).to eq('http://google.com/') + expect(page.dom.url).to eq('http://www.google.com/') end end end describe '#fire_event' do @@ -1502,26 +1431,45 @@ end context 'when new timers are introduced' do let(:url) { "#{@url}/trigger_events/with_new_timers/3000" } - it 'waits for them' do - @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click - pages_should_have_form_with_input [@browser.to_page], 'by-ajax' - end + context "when #{Arachni::OptionGroups::BrowserCluster}#wait_for_timers is" do + context 'true' do + before do + Arachni::Options.browser_cluster.wait_for_timers = true + end - context 'when a new timer exceeds Options.http.request_timeout' do - let(:url) { "#{@url}/trigger_events/with_new_timers/#{Arachni::Options.http.request_timeout + 5000}" } + it 'waits for them' do + @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click + pages_should_have_form_with_input [@browser.to_page], 'by-ajax' + end - it 'waits for Options.http.request_timeout' do - t = Time.now + context 'when a new timer exceeds Options.http.request_timeout' do + let(:url) { "#{@url}/trigger_events/with_new_timers/#{Arachni::Options.http.request_timeout + 5000}" } - @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click - pages_should_not_have_form_with_input [@browser.to_page], 'by-ajax' + it 'waits for Options.http.request_timeout' do + t = Time.now - expect(Time.now - t).to be <= Arachni::Options.http.request_timeout + @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click + pages_should_not_have_form_with_input [@browser.to_page], 'by-ajax' + + expect(Time.now - t).to be <= Arachni::Options.http.request_timeout + end + end end + + context 'false' do + before do + Arachni::Options.browser_cluster.wait_for_timers = false + end + + it 'waits for them' do + @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click + pages_should_not_have_form_with_input [@browser.to_page], 'by-ajax' + end + end end end context 'when cookies are set' do let(:url) { @url + '/each_element_with_events/set-cookie' } @@ -2235,10 +2183,11 @@ 'id' => 'my-div', 'onclick' => 'addForm();' } } => :click }, + { "#{@url}post-ajax" => :request }, { "#{@url}get-ajax?ajax-token=my-token" => :request }, { "#{@url}post-ajax" => :request } ], [ { :page => :load }, @@ -2350,10 +2299,56 @@ subject.goto "#{@url}/Content-Security-Policy" expect(subject.response.code).to eq(200) expect(subject.response.headers).not_to include 'Content-Security-Policy' end + context 'when there is no page URL' do + it 'does not receive a Date header' do + subject.watir.goto "#{@url}/Date" + expect(subject.response.code).to eq(200) + expect(subject.response.headers).not_to include 'Date' + end + + it 'does not receive an Etag header' do + subject.watir.goto "#{@url}/Etag" + expect(subject.response.code).to eq(200) + expect(subject.response.headers).not_to include 'Etag' + end + + it 'does not receive a Cache-Control header' do + subject.watir.goto "#{@url}/Cache-Control" + expect(subject.response.code).to eq(200) + expect(subject.response.headers).not_to include 'Cache-Control' + end + + it 'does not receive a Last-Modified header' do + subject.watir.goto "#{@url}/Last-Modified" + expect(subject.response.code).to eq(200) + expect(subject.response.headers).not_to include 'Last-Modified' + end + + it 'does not send If-None-Match request headers' do + subject.watir.goto "#{@url}/If-None-Match" + expect(subject.response.code).to eq(200) + expect(subject.response.request.headers).not_to include 'If-None-Match' + + subject.watir.goto "#{@url}/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.watir.goto "#{@url}/If-Modified-Since" + expect(subject.response.code).to eq(200) + expect(subject.response.request.headers).not_to include 'If-Modified-Since' + + subject.watir.goto "#{@url}/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 the page URL' do it 'does not receive a Date header' do subject.goto "#{@url}/Date" expect(subject.response.code).to eq(200) expect(subject.response.headers).not_to include 'Date' @@ -2528,16 +2523,38 @@ end end end context 'when the page has JS timeouts' do - it 'waits for them to complete' do - time = Time.now - subject.goto "#{@url}load_delay" - waited = Time.now - time + context "when #{Arachni::OptionGroups::BrowserCluster}#wait_for_timers is" do + context 'true' do + before do + Arachni::Options.browser_cluster.wait_for_timers = true + end - expect(waited).to be >= subject.load_delay / 1000.0 + it 'waits for them to complete' do + time = Time.now + subject.goto "#{@url}load_delay" + waited = Time.now - time + + expect(waited).to be >= subject.load_delay / 1000.0 + end + end + + context 'false' do + before do + Arachni::Options.browser_cluster.wait_for_timers = false + end + + it 'does not waits for them to complete' do + time = Time.now + subject.goto "#{@url}load_delay" + waited = Time.now - time + + expect(waited).to be < subject.load_delay / 1000.0 + end + end end end context 'when there are outstanding HTTP requests' do it 'waits for them to complete' do @@ -2575,10 +2592,23 @@ subject.load @url expect( subject.javascript.run( 'return localStorage.getItem( "name" )' ) ).to eq 'value' end end + context "with #{Arachni::OptionGroups::BrowserCluster}#session_storage" do + before do + Arachni::Options.browser_cluster.session_storage = { + 'name' => 'value' + } + end + + it 'sets the data as session storage' do + subject.load @url + expect( subject.javascript.run( 'return sessionStorage.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' } @@ -2597,56 +2627,22 @@ Arachni::Options.browser_cluster.job_timeout = 2 t = Time.now @browser.goto( @url + '/wait_for_elements#stuff/here' ) expect(Time.now - t).to be < 5 - - expect do - @browser.watir.element( css: '#matchThis' ).tag_name - end.to raise_error Watir::Exception::UnknownObjectException end end context 'when the URL does not match any patterns' do it 'does not wait' do t = Time.now @browser.goto( @url + '/wait_for_elements' ) expect(Time.now - t).to be < 5 - - expect do - @browser.watir.element( css: '#matchThis' ).tag_name - end.to raise_error Watir::Exception::UnknownObjectException end end end - context "#{Arachni::OptionGroups::BrowserCluster}#ignore_images" do - context 'true' do - it 'does not load images' do - Arachni::Options.browser_cluster.ignore_images = true - @browser.shutdown - @browser = described_class.new( disk_cache: false ) - - @browser.load( "#{@url}form-with-image-button" ) - - expect(image_hit_count).to eq(0) - end - end - - context 'false' do - it 'loads images' do - Arachni::Options.browser_cluster.ignore_images = false - @browser.shutdown - @browser = described_class.new( disk_cache: false ) - - @browser.load( "#{@url}form-with-image-button" ) - - expect(image_hit_count).to eq(1) - end - end - end - context "with #{Arachni::OptionGroups::Scope}#exclude_path_patterns" do it 'respects scope restrictions' do pages = @browser.load( @url + '/explore' ).start_capture.trigger_events.page_snapshots pages_should_have_form_with_input pages, 'by-ajax' @@ -2667,12 +2663,14 @@ 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 - expect(@browser.load( @url + '/explore?test=1&test2=2' ).response).to be_nil + Arachni::Options.scope.auto_redundant_paths = 1 + Arachni::URI( @url + '/explore?test=2&test2=3' ).scope.auto_redundant?( true ) + + expect(@browser.load( @url + '/explore?test=4&test2=5' ).response.body).to be_empty end end describe ':cookies' do it 'loads the given cookies' do @@ -3219,14 +3217,18 @@ expect(cookie.name).to eq 'with_expiration' expect(cookie.value).to eq 'bar' expect(cookie.expires.to_s).to eq Time.parse( '2047-08-01 09:30:11 +0000' ).to_s end + # Need a better test, Chrome returns no cookies for '.localhost' + # (or is it a bug and it's all subdomains?) and Firefox just converts + # '.localhost' to 'localhost', is this only for localhost or general bug? it 'preserves the domain' do + skip @browser.load "#{@url}/cookies/domains" - cookies = @browser.cookies + ap cookies = @browser.cookies cookie = cookies.find { |c| c.name == 'include_subdomains' } expect(cookie.name).to eq 'include_subdomains' expect(cookie.value).to eq 'bar1' expect(cookie.domain).to eq ".#{Arachni::URI( @url ).host}" @@ -3243,19 +3245,19 @@ @browser.load "#{@url}/cookies/under/path" cookie = @browser.cookies.first expect(cookie.name).to eq 'cookie_under_path' expect(cookie.value).to eq 'value' - expect(cookie.path).to eq '/cookies/under/' + expect(cookie.path).to eq '/cookies/under' end it 'preserves httpOnly' do @browser.load "#{@url}/cookies/under/path" cookie = @browser.cookies.first expect(cookie.name).to eq 'cookie_under_path' expect(cookie.value).to eq 'value' - expect(cookie.path).to eq '/cookies/under/' + expect(cookie.path).to eq '/cookies/under' expect(cookie).to_not be_http_only @browser.load "#{@url}/cookies/httpOnly" cookie = @browser.cookies.first