diff --git a/.travis.yml b/.travis.yml
index b84c3a1dd..f0187e12e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -117,7 +117,7 @@ matrix:
addons:
homebrew:
taps: homebrew/cask-versions
- casks: microsoft-edge-canary
+ casks: microsoft-edge-dev
before_install:
- wget https://msedgewebdriverstorage.blob.core.windows.net/edgewebdriver/76.0.168.0/edgedriver_mac64.zip
- unzip edgedriver_mac64.zip -d /usr/local/bin
diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb
index f2d1fb4f3..9d1d5312a 100644
--- a/lib/capybara/driver/base.rb
+++ b/lib/capybara/driver/base.rb
@@ -35,6 +35,14 @@ def go_forward
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#go_forward'
end
+ def freeze_page
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#freeze_page'
+ end
+
+ def thaw_page
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#thaw_page'
+ end
+
def execute_script(script, *args)
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#execute_script'
end
diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb
index 02e229842..9b62a64b5 100644
--- a/lib/capybara/selenium/driver.rb
+++ b/lib/capybara/selenium/driver.rb
@@ -45,6 +45,7 @@ def browser
end
end
processed_options = options.reject { |key, _val| SPECIAL_OPTIONS.include?(key) }
+
@browser = Selenium::WebDriver.for(options[:browser], processed_options)
specialize_driver
diff --git a/lib/capybara/selenium/driver_specializations/chrome_driver.rb b/lib/capybara/selenium/driver_specializations/chrome_driver.rb
index 8343d08a4..d55596b7d 100644
--- a/lib/capybara/selenium/driver_specializations/chrome_driver.rb
+++ b/lib/capybara/selenium/driver_specializations/chrome_driver.rb
@@ -54,6 +54,15 @@ def reset!
execute_cdp('Storage.clearDataForOrigin', origin: '*', storageTypes: storage_types_to_clear)
end
+ def freeze_page
+ bridge.http.call(:post, "session/#{bridge.session_id}/goog/page/freeze", {})
+ end
+
+ def thaw_page
+ bridge.http.call(:post, "session/#{bridge.session_id}/goog/page/resume", {})
+ evaluate_script('1==1') # Ensure page has restarted
+ end
+
private
def storage_types_to_clear
diff --git a/lib/capybara/spec/public/test.js b/lib/capybara/spec/public/test.js
index bf5b9b907..f5c8c346b 100644
--- a/lib/capybara/spec/public/test.js
+++ b/lib/capybara/spec/public/test.js
@@ -48,11 +48,13 @@ $(function() {
});
$('#clickable').click(function(e) {
var link = $(this);
+ $(link).after('Processing');
setTimeout(function() {
$(link).after('Has been clicked');
$(link).after('');
$(link).after('');
$('#change').remove();
+ $('#clickable-processing').remove();
}, 1000);
return false;
});
diff --git a/lib/capybara/spec/session/driver_spec.rb b/lib/capybara/spec/session/driver_spec.rb
new file mode 100644
index 000000000..74b7240d1
--- /dev/null
+++ b/lib/capybara/spec/session/driver_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+Capybara::SpecHelper.spec 'Driver' do
+ context 'freeze_page', requires: %i[freeze js] do
+ it 'can pause a page' do
+ @session.visit('/with_js')
+ @session.find(:css, '#clickable').click
+ sleep 0.1
+ @session.driver.freeze_page
+
+ expect(@session).to have_css('#clickable-processing')
+ sleep 3 # Time needs to be longer than click action delay
+ expect(@session).not_to have_css('#has-been-clicked')
+ expect(@session).to have_css('#clickable-processing')
+
+ @session.driver.thaw_page
+ expect(@session).to have_css('#has-been-clicked').and(have_no_css('#clickable-processing'))
+ end
+
+ it "doesn't prevent driver JS" do
+ @session.visit('/with_js')
+ @session.find(:css, '#clickable')
+ @session.driver.freeze_page
+
+ expect(@session.evaluate_script('1==1')).to eq true
+
+ @session.driver.thaw_page
+ end
+ end
+end
diff --git a/spec/selenium_spec_firefox.rb b/spec/selenium_spec_firefox.rb
index 68b7d7037..6c3cc9fd2 100644
--- a/spec/selenium_spec_firefox.rb
+++ b/spec/selenium_spec_firefox.rb
@@ -42,7 +42,7 @@ module TestSessions
SeleniumFirefox = Capybara::Session.new(:selenium_firefox, TestApp)
end
-skipped_tests = %i[response_headers status_code trigger]
+skipped_tests = %i[response_headers status_code trigger freeze]
Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::Firefox) if ENV['CI']
diff --git a/spec/selenium_spec_firefox_remote.rb b/spec/selenium_spec_firefox_remote.rb
index 9a77fba73..e1077af17 100644
--- a/spec/selenium_spec_firefox_remote.rb
+++ b/spec/selenium_spec_firefox_remote.rb
@@ -56,7 +56,7 @@ module TestSessions
str if File.exist?(str)
end
-skipped_tests = %i[response_headers status_code trigger download]
+skipped_tests = %i[response_headers status_code trigger download freeze]
Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
case example.metadata[:full_description]
diff --git a/spec/selenium_spec_safari.rb b/spec/selenium_spec_safari.rb
index 1273a04b4..1d2eaf933 100644
--- a/spec/selenium_spec_safari.rb
+++ b/spec/selenium_spec_safari.rb
@@ -36,7 +36,7 @@ module TestSessions
Safari = Capybara::Session.new(SAFARI_DRIVER, TestApp)
end
-skipped_tests = %i[response_headers status_code trigger windows drag]
+skipped_tests = %i[response_headers status_code trigger windows drag freeze]
Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::Safari) if ENV['CI']