diff --git a/lib/capybara/poltergeist/browser.rb b/lib/capybara/poltergeist/browser.rb index 6744fe9..b6f0d5a 100644 --- a/lib/capybara/poltergeist/browser.rb +++ b/lib/capybara/poltergeist/browser.rb @@ -10,7 +10,8 @@ module Capybara::Poltergeist 'Poltergeist.FrameNotFound' => FrameNotFound, 'Poltergeist.InvalidSelector' => InvalidSelector, 'Poltergeist.StatusFailError' => StatusFailError, - 'Poltergeist.NoSuchWindowError' => NoSuchWindowError + 'Poltergeist.NoSuchWindowError' => NoSuchWindowError, + 'Poltergeist.UnsupportedFeature' => UnsupportedFeature } attr_reader :server, :client, :logger @@ -344,6 +345,10 @@ module Capybara::Poltergeist command 'set_debug', !!val end + def clear_memory_cache + command 'clear_memory_cache' + end + def command(name, *args) cmd = Command.new(name, *args) log cmd.message diff --git a/lib/capybara/poltergeist/client/browser.coffee b/lib/capybara/poltergeist/client/browser.coffee index b22859f..11b5ab9 100644 --- a/lib/capybara/poltergeist/client/browser.coffee +++ b/lib/capybara/poltergeist/client/browser.coffee @@ -508,3 +508,7 @@ class Poltergeist.Browser modal_message: -> @current_command.sendResponse(@processed_modal_messages.shift()) + + clear_memory_cache: -> + @currentPage.clearMemoryCache() + @current_command.sendResponse(true) diff --git a/lib/capybara/poltergeist/client/compiled/browser.js b/lib/capybara/poltergeist/client/compiled/browser.js index 761cfb2..c2ab872 100644 --- a/lib/capybara/poltergeist/client/compiled/browser.js +++ b/lib/capybara/poltergeist/client/compiled/browser.js @@ -693,6 +693,11 @@ Poltergeist.Browser = (function() { return this.current_command.sendResponse(this.processed_modal_messages.shift()); }; + Browser.prototype.clear_memory_cache = function() { + this.currentPage.clearMemoryCache(); + return this.current_command.sendResponse(true); + }; + return Browser; })(); diff --git a/lib/capybara/poltergeist/client/compiled/main.js b/lib/capybara/poltergeist/client/compiled/main.js index ca4cc06..6c1a091 100644 --- a/lib/capybara/poltergeist/client/compiled/main.js +++ b/lib/capybara/poltergeist/client/compiled/main.js @@ -214,6 +214,23 @@ Poltergeist.NoSuchWindowError = (function(superClass) { })(Poltergeist.Error); +Poltergeist.UnsupportedFeature = (function(superClass) { + extend(UnsupportedFeature, superClass); + + function UnsupportedFeature(message1) { + this.message = message1; + } + + UnsupportedFeature.prototype.name = "Poltergeist.UnsupportedFeature"; + + UnsupportedFeature.prototype.args = function() { + return [this.message, phantom.version]; + }; + + return UnsupportedFeature; + +})(Poltergeist.Error); + phantom.injectJs(phantom.libraryPath + "/web_page.js"); phantom.injectJs(phantom.libraryPath + "/node.js"); diff --git a/lib/capybara/poltergeist/client/compiled/web_page.js b/lib/capybara/poltergeist/client/compiled/web_page.js index e39c246..b1c65e5 100644 --- a/lib/capybara/poltergeist/client/compiled/web_page.js +++ b/lib/capybara/poltergeist/client/compiled/web_page.js @@ -584,6 +584,16 @@ Poltergeist.WebPage = (function() { return parser.href; }; + WebPage.prototype.clearMemoryCache = function() { + var clearMemoryCache; + clearMemoryCache = this["native"]().clearMemoryCache; + if (typeof clearMemoryCache === "function") { + return clearMemoryCache(); + } else { + throw new Poltergeist.UnsupportedFeature("clearMemoryCache is supported since PhantomJS 2.0.0"); + } + }; + return WebPage; })(); diff --git a/lib/capybara/poltergeist/client/main.coffee b/lib/capybara/poltergeist/client/main.coffee index f5a49c4..6385f22 100644 --- a/lib/capybara/poltergeist/client/main.coffee +++ b/lib/capybara/poltergeist/client/main.coffee @@ -87,6 +87,11 @@ class Poltergeist.NoSuchWindowError extends Poltergeist.Error name: "Poltergeist.NoSuchWindowError" args: -> [] +class Poltergeist.UnsupportedFeature extends Poltergeist.Error + constructor: (@message) -> + name: "Poltergeist.UnsupportedFeature" + args: -> [@message, phantom.version] + # We're using phantom.libraryPath so that any stack traces # report the full path. phantom.injectJs("#{phantom.libraryPath}/web_page.js") diff --git a/lib/capybara/poltergeist/client/web_page.coffee b/lib/capybara/poltergeist/client/web_page.coffee index d8e0d41..53b4055 100644 --- a/lib/capybara/poltergeist/client/web_page.coffee +++ b/lib/capybara/poltergeist/client/web_page.coffee @@ -409,3 +409,10 @@ class Poltergeist.WebPage parser = document.createElement('a') parser.href = url return parser.href + + clearMemoryCache: -> + clearMemoryCache = this.native().clearMemoryCache + if typeof clearMemoryCache == "function" + clearMemoryCache() + else + throw new Poltergeist.UnsupportedFeature("clearMemoryCache is supported since PhantomJS 2.0.0") diff --git a/lib/capybara/poltergeist/driver.rb b/lib/capybara/poltergeist/driver.rb index 83a65f0..4461669 100644 --- a/lib/capybara/poltergeist/driver.rb +++ b/lib/capybara/poltergeist/driver.rb @@ -279,6 +279,10 @@ module Capybara::Poltergeist browser.cookies_enabled = flag end + def clear_memory_cache + browser.clear_memory_cache + end + # * PhantomJS with set settings doesn't send `Authorize` on POST request # * With manually set header PhantomJS makes next request with # `Authorization: Basic Og==` header when settings are empty and the diff --git a/lib/capybara/poltergeist/errors.rb b/lib/capybara/poltergeist/errors.rb index c98543a..6b6f7ae 100644 --- a/lib/capybara/poltergeist/errors.rb +++ b/lib/capybara/poltergeist/errors.rb @@ -115,6 +115,24 @@ module Capybara end end + class UnsupportedFeature < ClientError + def name + response['name'] + end + + def unsupported_message + response['args'][0] + end + + def version + response['args'][1].values_at(*%w(major minor patch)).join '.' + end + + def message + "Running version of PhantomJS #{version} does not support some feature: #{unsupported_message}" + end + end + class MouseEventFailed < NodeError def name response['args'][0] diff --git a/spec/integration/driver_spec.rb b/spec/integration/driver_spec.rb index 4869684..7fbfb5d 100644 --- a/spec/integration/driver_spec.rb +++ b/spec/integration/driver_spec.rb @@ -16,6 +16,12 @@ module Capybara::Poltergeist "http://#{server.host}:#{server.port}#{path}" end + def phantom_version_is?(version_to_match) + (@phantom_version_matches ||= Hash.new { |hash, ver_spec| + hash[ver_spec] = Cliver.detect(@driver.options[:phantomjs] || Client::PHANTOMJS_NAME, ver_spec) } + )[version_to_match] + end + it 'supports a custom phantomjs path' do begin file = POLTERGEIST_ROOT + '/spec/support/custom_phantomjs_called' @@ -577,6 +583,48 @@ module Capybara::Poltergeist end end + context "memory cache clearing" do + + before do + @driver.restart + end + + it "can clear memory cache when supported (phantomjs >=2.0.0)" do + skip "clear_memory_cache is not supported by tested PhantomJS" unless phantom_version_is? ">= 2.0.0" + + @driver.clear_memory_cache + + @session.visit('/poltergeist/cacheable') + first_request = @driver.network_traffic.last + expect(@driver.network_traffic.length).to eq(1) + expect(first_request.response_parts.last.status).to eq(200) + + @session.visit('/poltergeist/cacheable') + expect(@driver.network_traffic.length).to eq(1) + + @driver.clear_memory_cache + + @session.visit('/poltergeist/cacheable') + another_request = @driver.network_traffic.last + expect(@driver.network_traffic.length).to eq(2) + expect(another_request.response_parts.last.status).to eq(200) + end + + it "raises error when it is unsupported (phantomjs <2.0.0)" do + skip "clear_memory_cache is supported by tested PhantomJS" if phantom_version_is? ">= 2.0.0" + + @session.visit('/poltergeist/cacheable') + first_request = @driver.network_traffic.last + expect(@driver.network_traffic.length).to eq(1) + expect(first_request.response_parts.last.status).to eq(200) + + expect{@driver.clear_memory_cache}.to raise_error(Capybara::Poltergeist::UnsupportedFeature) + + @session.visit('/poltergeist/cacheable') + expect(@driver.network_traffic.length).to eq(2) + end + end + context 'status code support' do it 'determines status from the simple response' do @session.visit('/poltergeist/status/500') diff --git a/spec/support/test_app.rb b/spec/support/test_app.rb index ed5fdc7..a71cdda 100644 --- a/spec/support/test_app.rb +++ b/spec/support/test_app.rb @@ -69,6 +69,12 @@ class TestApp 'Authorized POST request' end + get '/poltergeist/cacheable' do + cache_control :public, max_age: 60 + etag "deadbeef" + 'Cacheable request' + end + get '/poltergeist/:view' do |view| render_view view end