Skip to content

Instantly share code, notes, and snippets.

@znz
Created February 20, 2013 06:29
Show Gist options
  • Save znz/4993414 to your computer and use it in GitHub Desktop.
Save znz/4993414 to your computer and use it in GitHub Desktop.
poltergeist gem (+ phantomjs 1.8.1) の onConfirm 対応に挑戦しているけど onAlert と同じように書いているのに onConfirm が呼ばれなくて困っている。
diff --git a/lib/capybara/poltergeist/browser.rb b/lib/capybara/poltergeist/browser.rb
index c4100c2..97d790f 100644
--- a/lib/capybara/poltergeist/browser.rb
+++ b/lib/capybara/poltergeist/browser.rb
@@ -170,6 +170,18 @@ module Capybara::Poltergeist
command 'remove_cookie', name
end
+ def js_alert_messages
+ command 'js_alert_messages'
+ end
+
+ def js_confirm_messages
+ command 'js_confirm_messages'
+ end
+
+ def js_confirm_responses=(responses)
+ command 'set_js_confirm_responses', responses
+ end
+
def js_errors=(val)
command 'set_js_errors', !!val
end
diff --git a/lib/capybara/poltergeist/client/browser.coffee b/lib/capybara/poltergeist/client/browser.coffee
index fdbf8d2..7b2c687 100644
--- a/lib/capybara/poltergeist/client/browser.coffee
+++ b/lib/capybara/poltergeist/client/browser.coffee
@@ -47,6 +47,30 @@ class Poltergeist.Browser
# window.
setTimeout((=> this.push_window(name)), 0)
+ @alert_messages = []
+ @page.onAlert = (msg) =>
+ @alert_messages.push(msg)
+
+ @confirm_messages = []
+ @confirm_responses = []
+ @page.onConfirm = (msg) =>
+ @confirm_messages.push(msg)
+ if @confirm_responses.shift() == false
+ return false
+ return true
+
+ js_alert_messages: ->
+ this.sendResponse(@alert_messages)
+ @alert_messages = []
+
+ js_confirm_messages: ->
+ this.sendResponse(@confirm_messages)
+ @confirm_messages = []
+
+ set_js_confirm_responses: (responses) ->
+ @confirm_responses = responses
+ this.sendResponse(true)
+
debug: (message) ->
if @_debug
console.log "poltergeist [#{new Date().getTime()}] #{message}"
diff --git a/lib/capybara/poltergeist/client/compiled/browser.js b/lib/capybara/poltergeist/client/compiled/browser.js
index 54743a9..30c91fb 100644
--- a/lib/capybara/poltergeist/client/compiled/browser.js
+++ b/lib/capybara/poltergeist/client/compiled/browser.js
@@ -49,7 +49,7 @@ Poltergeist.Browser = (function() {
this.page.onInitialized = function() {
return _this.page_id += 1;
};
- return this.page.onPageCreated = function(sub_page) {
+ this.page.onPageCreated = function(sub_page) {
var name;
if (_this.state === 'awaiting_sub_page') {
name = _this.page_name;
@@ -60,6 +60,34 @@ Poltergeist.Browser = (function() {
}), 0);
}
};
+ this.alert_messages = [];
+ this.page.onAlert = function(msg) {
+ return _this.alert_messages.push(msg);
+ };
+ this.confirm_messages = [];
+ this.confirm_responses = [];
+ return this.page.onConfirm = function(msg) {
+ _this.confirm_messages.push(msg);
+ if (_this.confirm_responses.shift() === false) {
+ return false;
+ }
+ return true;
+ };
+ };
+
+ Browser.prototype.js_alert_messages = function() {
+ this.sendResponse(this.alert_messages);
+ return this.alert_messages = [];
+ };
+
+ Browser.prototype.js_confirm_messages = function() {
+ this.sendResponse(this.confirm_messages);
+ return this.confirm_messages = [];
+ };
+
+ Browser.prototype.set_js_confirm_responses = function(responses) {
+ this.confirm_responses = responses;
+ return this.sendResponse(true);
};
Browser.prototype.debug = function(message) {
diff --git a/lib/capybara/poltergeist/driver.rb b/lib/capybara/poltergeist/driver.rb
index fbe8fd6..492dd62 100644
--- a/lib/capybara/poltergeist/driver.rb
+++ b/lib/capybara/poltergeist/driver.rb
@@ -179,6 +179,18 @@ module Capybara::Poltergeist
browser.remove_cookie(name)
end
+ def js_alert_messages
+ browser.js_alert_messages
+ end
+
+ def js_confirm_messages
+ browser.js_confirm_messages
+ end
+
+ def js_confirm_set_responses(*responses)
+ browser.js_confirm_responses = responses
+ end
+
def debug
if @options[:inspector]
inspector.open
diff --git a/spec/integration/driver_spec.rb b/spec/integration/driver_spec.rb
index 1317f16..78cf47a 100644
--- a/spec/integration/driver_spec.rb
+++ b/spec/integration/driver_spec.rb
@@ -291,6 +291,47 @@ module Capybara::Poltergeist
end
end
+ context "alert" do
+ it 'has js alert messages' do
+ @driver.js_alert_messages.should == []
+ @session.visit('/poltergeist/js_alert')
+ @driver.js_alert_messages.should == ["foo", "bar"]
+ @driver.js_alert_messages.should == []
+ end
+ end
+
+ context "confirm" do
+ it 'click OK' do
+ @session.visit('/poltergeist/js_confirm')
+ @driver.evaluate_script("result").should == true
+ @driver.js_confirm_messages.should == ["foo"]
+ end
+
+ it 'click Cancel' do
+ @driver.js_confirm_set_responses(false)
+ @session.visit('/poltergeist/js_confirm')
+ @driver.evaluate_script("result").should == false
+ end
+
+ it 'click Cancel and OK' do
+ @driver.js_confirm_set_responses(false)
+ @session.visit('/poltergeist/js_confirm')
+ @driver.evaluate_script("result").should == false
+ @session.visit('/poltergeist/js_confirm')
+ @driver.evaluate_script("result").should == true
+ @driver.js_confirm_messages.should == ["foo", "foo"]
+ end
+
+ it 'click Cancel twice' do
+ @driver.js_confirm_set_responses(false, false)
+ @session.visit('/poltergeist/js_confirm')
+ @driver.evaluate_script("result").should == false
+ @session.visit('/poltergeist/js_confirm')
+ @driver.evaluate_script("result").should == false
+ @driver.js_confirm_messages.should == ["foo", "foo"]
+ end
+ end
+
context "network traffic" do
before do
@driver.restart
diff --git a/spec/support/views/js_alert.erb b/spec/support/views/js_alert.erb
new file mode 100644
index 0000000..ad4fa0e
--- /dev/null
+++ b/spec/support/views/js_alert.erb
@@ -0,0 +1,4 @@
+<script type="text/javascript">
+ alert('foo');
+ alert('bar');
+</script>
diff --git a/spec/support/views/js_confirm.erb b/spec/support/views/js_confirm.erb
new file mode 100644
index 0000000..4c335b0
--- /dev/null
+++ b/spec/support/views/js_confirm.erb
@@ -0,0 +1,3 @@
+<script type="text/javascript">
+ result = confirm('foo');
+</script>
@znz
Copy link
Author

znz commented Feb 20, 2013

CONTRIBUTING.md の手順に従って bundle install して bundle exec rake で試していると、以下のような failures が出る。

Failures:

  1) Capybara::Poltergeist::Driver confirm click OK
     Failure/Error: @driver.js_confirm_messages.should == ["foo"]
       expected: ["foo"]
            got: [] (using ==)
     # ./spec/integration/driver_spec.rb:307:in `block (3 levels) in <module:Poltergeist>'
  2) Capybara::Poltergeist::Driver confirm click Cancel
     Failure/Error: @driver.evaluate_script("result").should == false
       expected: false
            got: true (using ==)
     # ./spec/integration/driver_spec.rb:313:in `block (3 levels) in <module:Poltergeist>'

  3) Capybara::Poltergeist::Driver confirm click Cancel and OK
     Failure/Error: @driver.evaluate_script("result").should == false
       expected: false
            got: true (using ==)
     # ./spec/integration/driver_spec.rb:319:in `block (3 levels) in <module:Poltergeist>'

  4) Capybara::Poltergeist::Driver confirm click Cancel twice
     Failure/Error: @driver.evaluate_script("result").should == false
       expected: false
            got: true (using ==)
     # ./spec/integration/driver_spec.rb:328:in `block (3 levels) in <module:Poltergeist>'

@gongo
Copy link

gongo commented Feb 27, 2013

上記パッチに加えて、下記を適用すると rake test で全 pass しました。
変更内容としては

  1. client/agent で confirm が必ず true を返すようになってたのでそれを削除
    • js_confirm_set_responses(false) しない限り true を返すので問題ないかな、と
  2. client/webpageonAlert だけ許可されていて onConfirm が許可 CALLBACK ではなかったので追加
diff --git a/lib/capybara/poltergeist/client/agent.coffee b/lib/capybara/poltergeist/client/agent.coffee
index ae58a1b..af28fd1 100644
--- a/lib/capybara/poltergeist/client/agent.coffee
+++ b/lib/capybara/poltergeist/client/agent.coffee
@@ -232,5 +232,4 @@ document.addEventListener(
   -> console.log('__DOMContentLoaded')
 )

-window.confirm = (message) -> true
 window.prompt  = (message, _default) -> _default or null
diff --git a/lib/capybara/poltergeist/client/compiled/agent.js b/lib/capybara/poltergeist/client/compiled/agent.js
index d41bf85..6a9e7b9 100644
--- a/lib/capybara/poltergeist/client/compiled/agent.js
+++ b/lib/capybara/poltergeist/client/compiled/agent.js
@@ -338,10 +338,6 @@ document.addEventListener('DOMContentLoaded', function() {
   return console.log('__DOMContentLoaded');
 });

-window.confirm = function(message) {
-  return true;
-};
-
 window.prompt = function(message, _default) {
   return _default || null;
 };
diff --git a/lib/capybara/poltergeist/client/compiled/web_page.js b/lib/capybara/poltergeist/client/compiled/web_page.js
index 4d59141..9d8b8e7 100644
--- a/lib/capybara/poltergeist/client/compiled/web_page.js
+++ b/lib/capybara/poltergeist/client/compiled/web_page.js
@@ -4,7 +4,7 @@ Poltergeist.WebPage = (function() {
   var command, delegate, _fn, _fn1, _i, _j, _len, _len1, _ref, _ref1,
     _this = this;

-  WebPage.CALLBACKS = ['onAlert', 'onConsoleMessage', 'onLoadFinished', 'onInitialized', 'onLoadStarted', 'onResourceRequested', 'onResourceReceived', 'onError', 'onNavigationRequested', 'onUrlChanged', 'onPageCreated'];
+  WebPage.CALLBACKS = ['onAlert', 'onConfirm', 'onConsoleMessage', 'onLoadFinished', 'onInitialized', 'onLoadStarted', 'onResourceRequested', 'onResourceReceived', 'onError', 'onNavigationRequested', 'onUrlChanged', 'onPageCreated'];

   WebPage.DELEGATES = ['open', 'sendEvent', 'uploadFile', 'release', 'render'];

diff --git a/lib/capybara/poltergeist/client/web_page.coffee b/lib/capybara/poltergeist/client/web_page.coffee
index 416b92d..998614c 100644
--- a/lib/capybara/poltergeist/client/web_page.coffee
+++ b/lib/capybara/poltergeist/client/web_page.coffee
@@ -1,5 +1,5 @@
 class Poltergeist.WebPage
-  @CALLBACKS = ['onAlert', 'onConsoleMessage', 'onLoadFinished', 'onInitialized',
+  @CALLBACKS = ['onAlert', 'onConfirm', 'onConsoleMessage', 'onLoadFinished', 'onInitialized',
                 'onLoadStarted', 'onResourceRequested', 'onResourceReceived',
                 'onError', 'onNavigationRequested', 'onUrlChanged', 'onPageCreated']

@znz
Copy link
Author

znz commented Feb 28, 2013

ありがとうございました。おかげさまで解決しました。

関連:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment