From ba205de6f851963f62313e034e6c4100b73a13fe Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 28 Sep 2015 14:44:26 -0700 Subject: [PATCH] make modal support work with multiple/nested modals --- lib/capybara/poltergeist/browser.rb | 4 +- .../poltergeist/client/browser.coffee | 14 +- .../poltergeist/client/compiled/agent.js | 102 ++++----- .../poltergeist/client/compiled/browser.js | 197 ++++++++++-------- .../poltergeist/client/compiled/connection.js | 4 +- .../poltergeist/client/compiled/main.js | 61 +++--- .../poltergeist/client/compiled/node.js | 19 +- .../poltergeist/client/compiled/web_page.js | 107 +++++----- lib/capybara/poltergeist/driver.rb | 9 +- spec/integration/session_spec.rb | 17 ++ spec/support/public/test.js | 9 + spec/support/views/with_js.erb | 4 + 12 files changed, 298 insertions(+), 249 deletions(-) diff --git a/lib/capybara/poltergeist/browser.rb b/lib/capybara/poltergeist/browser.rb index 5c1251c..d0bb265 100644 --- a/lib/capybara/poltergeist/browser.rb +++ b/lib/capybara/poltergeist/browser.rb @@ -371,8 +371,8 @@ module Capybara::Poltergeist command 'set_prompt_response', nil end - def modal_messages - command 'modal_messages' + def modal_message + command 'modal_message' end private diff --git a/lib/capybara/poltergeist/client/browser.coffee b/lib/capybara/poltergeist/client/browser.coffee index b4f3671..02e386c 100644 --- a/lib/capybara/poltergeist/client/browser.coffee +++ b/lib/capybara/poltergeist/client/browser.coffee @@ -37,13 +37,13 @@ class Poltergeist.Browser return @page.native().onConfirm = (msg) => - process = @confirm_processes.shift() + process = @confirm_processes.pop() process = true if process == undefined @setModalMessage msg return process @page.native().onPrompt = (msg, defaultVal) => - response = @prompt_responses.shift() + response = @prompt_responses.pop() response = defaultVal if (response == undefined || response == false) @setModalMessage msg @@ -89,6 +89,11 @@ class Poltergeist.Browser visit: (url) -> @currentPage.state = 'loading' + #reset modal processing state when changing page + @processed_modal_messages = [] + @confirm_processes = [] + @prompt_responses = [] + # Prevent firing `page.onInitialized` event twice. Calling currentUrl # method before page is actually opened fires this event for the first time. @@ -468,6 +473,5 @@ class Poltergeist.Browser @prompt_responses.push response @sendResponse(true) - modal_messages: -> - @sendResponse(@processed_modal_messages) - @processed_modal_messages = [] + modal_message: -> + @sendResponse(@processed_modal_messages.shift()) diff --git a/lib/capybara/poltergeist/client/compiled/agent.js b/lib/capybara/poltergeist/client/compiled/agent.js index d0834b4..bda2fc0 100644 --- a/lib/capybara/poltergeist/client/compiled/agent.js +++ b/lib/capybara/poltergeist/client/compiled/agent.js @@ -48,7 +48,7 @@ PoltergeistAgent = (function() { }; PoltergeistAgent.prototype.find = function(method, selector, within) { - var el, error, i, results, xpath, _i, _len, _results; + var el, error, i, j, len, results, results1, xpath; if (within == null) { within = document; } @@ -56,22 +56,22 @@ PoltergeistAgent = (function() { if (method === "xpath") { xpath = document.evaluate(selector, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); results = (function() { - var _i, _ref, _results; - _results = []; - for (i = _i = 0, _ref = xpath.snapshotLength; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { - _results.push(xpath.snapshotItem(i)); + var j, ref, results1; + results1 = []; + for (i = j = 0, ref = xpath.snapshotLength; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) { + results1.push(xpath.snapshotItem(i)); } - return _results; + return results1; })(); } else { results = within.querySelectorAll(selector); } - _results = []; - for (_i = 0, _len = results.length; _i < _len; _i++) { - el = results[_i]; - _results.push(this.register(el)); + results1 = []; + for (j = 0, len = results.length; j < len; j++) { + el = results[j]; + results1.push(this.register(el)); } - return _results; + return results1; } catch (_error) { error = _error; if (error.code === DOMException.SYNTAX_ERR || error.code === 51) { @@ -95,8 +95,8 @@ PoltergeistAgent = (function() { }; PoltergeistAgent.prototype.get = function(id) { - var _base; - return (_base = this.nodes)[id] || (_base[id] = new PoltergeistAgent.Node(this, this.elements[id])); + var base; + return (base = this.nodes)[id] || (base[id] = new PoltergeistAgent.Node(this, this.elements[id])); }; PoltergeistAgent.prototype.nodeCall = function(id, name, args) { @@ -153,9 +153,9 @@ PoltergeistAgent.Node = (function() { FORM: ['submit'] }; - function Node(agent, element) { + function Node(agent, element1) { this.agent = agent; - this.element = element; + this.element = element1; } Node.prototype.parentId = function() { @@ -178,19 +178,20 @@ PoltergeistAgent.Node = (function() { }; Node.prototype.isObsolete = function() { - var obsolete, - _this = this; - obsolete = function(element) { - if (element.parentNode != null) { - if (element.parentNode === document) { - return false; + var obsolete; + obsolete = (function(_this) { + return function(element) { + if (element.parentNode != null) { + if (element.parentNode === document) { + return false; + } else { + return obsolete(element.parentNode); + } } else { - return obsolete(element.parentNode); + return true; } - } else { - return true; - } - }; + }; + })(this); return obsolete(this.element); }; @@ -266,11 +267,11 @@ PoltergeistAgent.Node = (function() { }; Node.prototype.getAttributes = function() { - var attr, attrs, i, _i, _len, _ref; + var attr, attrs, i, j, len, ref; attrs = {}; - _ref = this.element.attributes; - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - attr = _ref[i]; + ref = this.element.attributes; + for (i = j = 0, len = ref.length; j < len; i = ++j) { + attr = ref[i]; attrs[attr.name] = attr.value.replace("\n", "\\n"); } return attrs; @@ -289,24 +290,24 @@ PoltergeistAgent.Node = (function() { }; Node.prototype.value = function() { - var option, _i, _len, _ref, _results; + var j, len, option, ref, results1; if (this.element.tagName === 'SELECT' && this.element.multiple) { - _ref = this.element.children; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - option = _ref[_i]; + ref = this.element.children; + results1 = []; + for (j = 0, len = ref.length; j < len; j++) { + option = ref[j]; if (option.selected) { - _results.push(option.value); + results1.push(option.value); } } - return _results; + return results1; } else { return this.element.value; } }; Node.prototype.set = function(value) { - var char, keyCode, _i, _len; + var char, j, keyCode, len; if (this.element.readOnly) { return; } @@ -318,8 +319,8 @@ PoltergeistAgent.Node = (function() { if (this.element.type === 'number') { this.element.value = value; } else { - for (_i = 0, _len = value.length; _i < _len; _i++) { - char = value[_i]; + for (j = 0, len = value.length; j < len; j++) { + char = value[j]; keyCode = this.characterToKeyCode(char); this.keyupdowned('keydown', keyCode); this.element.value += char; @@ -380,16 +381,17 @@ PoltergeistAgent.Node = (function() { }; Node.prototype.path = function() { - var elements, selectors, - _this = this; - elements = this.parentIds().reverse().map(function(id) { - return _this.agent.get(id); - }); + var elements, selectors; + elements = this.parentIds().reverse().map((function(_this) { + return function(id) { + return _this.agent.get(id); + }; + })(this)); elements.push(this); selectors = elements.map(function(el) { var prev_siblings; prev_siblings = el.find('xpath', "./preceding-sibling::" + (el.tagName())); - return "" + (el.tagName()) + "[" + (prev_siblings.length + 1) + "]"; + return (el.tagName()) + "[" + (prev_siblings.length + 1) + "]"; }); return "//" + selectors.join('/'); }; @@ -488,15 +490,15 @@ PoltergeistAgent.Node = (function() { }; Node.prototype.getSelector = function(el) { - var className, selector, _i, _len, _ref; + var className, j, len, ref, selector; selector = el.tagName !== 'HTML' ? this.getSelector(el.parentNode) + ' ' : ''; selector += el.tagName.toLowerCase(); if (el.id) { selector += "#" + el.id; } - _ref = el.classList; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - className = _ref[_i]; + ref = el.classList; + for (j = 0, len = ref.length; j < len; j++) { + className = ref[j]; selector += "." + className; } return selector; diff --git a/lib/capybara/poltergeist/client/compiled/browser.js b/lib/capybara/poltergeist/client/compiled/browser.js index 47657ea..bec18d4 100644 --- a/lib/capybara/poltergeist/client/compiled/browser.js +++ b/lib/capybara/poltergeist/client/compiled/browser.js @@ -1,4 +1,4 @@ -var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; +var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; Poltergeist.Browser = (function() { function Browser(owner, width, height) { @@ -16,9 +16,8 @@ Poltergeist.Browser = (function() { } Browser.prototype.resetPage = function() { - var _ref, - _this = this; - _ref = [0, []], this._counter = _ref[0], this.pages = _ref[1]; + var ref; + ref = [0, []], this._counter = ref[0], this.pages = ref[1]; if (this.page != null) { if (!this.page.closed) { if (this.page.currentUrl() !== 'about:blank') { @@ -38,33 +37,41 @@ Poltergeist.Browser = (function() { this.processed_modal_messages = []; this.confirm_processes = []; this.prompt_responses = []; - this.page["native"]().onAlert = function(msg) { - _this.setModalMessage(msg); - }; - this.page["native"]().onConfirm = function(msg) { - var process; - process = _this.confirm_processes.shift(); - if (process === void 0) { - process = true; - } - _this.setModalMessage(msg); - return process; - }; - this.page["native"]().onPrompt = function(msg, defaultVal) { - var response; - response = _this.prompt_responses.shift(); - if (response === void 0 || response === false) { - response = defaultVal; - } - _this.setModalMessage(msg); - return response; - }; - return this.page.onPageCreated = function(newPage) { - var page; - page = new Poltergeist.WebPage(newPage); - page.handle = "" + (_this._counter++); - return _this.pages.push(page); - }; + this.page["native"]().onAlert = (function(_this) { + return function(msg) { + _this.setModalMessage(msg); + }; + })(this); + this.page["native"]().onConfirm = (function(_this) { + return function(msg) { + var process; + process = _this.confirm_processes.pop(); + if (process === void 0) { + process = true; + } + _this.setModalMessage(msg); + return process; + }; + })(this); + this.page["native"]().onPrompt = (function(_this) { + return function(msg, defaultVal) { + var response; + response = _this.prompt_responses.pop(); + if (response === void 0 || response === false) { + response = defaultVal; + } + _this.setModalMessage(msg); + return response; + }; + })(this); + return this.page.onPageCreated = (function(_this) { + return function(newPage) { + var page; + page = new Poltergeist.WebPage(newPage); + page.handle = "" + (_this._counter++); + return _this.pages.push(page); + }; + })(this); }; Browser.prototype.getPageByHandle = function(handle) { @@ -113,9 +120,11 @@ Poltergeist.Browser = (function() { }; Browser.prototype.visit = function(url) { - var prevUrl, - _this = this; + var prevUrl; this.currentPage.state = 'loading'; + this.processed_modal_messages = []; + this.confirm_processes = []; + this.prompt_responses = []; prevUrl = this.currentPage.source === null ? 'about:blank' : this.currentPage.currentUrl(); this.currentPage.open(url); if (/#/.test(url) && prevUrl.split('#')[0] === url.split('#')[0]) { @@ -124,15 +133,17 @@ Poltergeist.Browser = (function() { status: 'success' }); } else { - return this.currentPage.waitState('default', function() { - if (_this.currentPage.statusCode === null && _this.currentPage.status === 'fail') { - return _this.owner.sendError(new Poltergeist.StatusFailError); - } else { - return _this.sendResponse({ - status: _this.currentPage.status - }); - } - }); + return this.currentPage.waitState('default', (function(_this) { + return function() { + if (_this.currentPage.statusCode === null && _this.currentPage.status === 'fail') { + return _this.owner.sendError(new Poltergeist.StatusFailError); + } else { + return _this.sendResponse({ + status: _this.currentPage.status + }); + } + }; + })(this)); } }; @@ -243,27 +254,30 @@ Poltergeist.Browser = (function() { }; Browser.prototype.push_frame = function(name, timeout) { - var _ref, - _this = this; + var ref; if (timeout == null) { timeout = new Date().getTime() + 2000; } - if (_ref = this.frameUrl(name), __indexOf.call(this.currentPage.blockedUrls(), _ref) >= 0) { + if (ref = this.frameUrl(name), indexOf.call(this.currentPage.blockedUrls(), ref) >= 0) { return this.sendResponse(true); } else if (this.currentPage.pushFrame(name)) { if (this.currentPage.currentUrl() === 'about:blank') { this.currentPage.state = 'awaiting_frame_load'; - return this.currentPage.waitState('default', function() { - return _this.sendResponse(true); - }); + return this.currentPage.waitState('default', (function(_this) { + return function() { + return _this.sendResponse(true); + }; + })(this)); } else { return this.sendResponse(true); } } else { if (new Date().getTime() < timeout) { - return setTimeout((function() { - return _this.push_frame(name, timeout); - }), 50); + return setTimeout(((function(_this) { + return function() { + return _this.push_frame(name, timeout); + }; + })(this)), 50); } else { return this.owner.sendError(new Poltergeist.FrameNotFound(name)); } @@ -296,15 +310,16 @@ Poltergeist.Browser = (function() { }; Browser.prototype.switch_to_window = function(handle) { - var page, - _this = this; + var page; page = this.getPageByHandle(handle); if (page) { if (page !== this.currentPage) { - return page.waitState('default', function() { - _this.currentPage = page; - return _this.sendResponse(true); - }); + return page.waitState('default', (function(_this) { + return function() { + _this.currentPage = page; + return _this.sendResponse(true); + }; + })(this)); } else { return this.sendResponse(true); } @@ -330,25 +345,26 @@ Poltergeist.Browser = (function() { }; Browser.prototype.mouse_event = function(page_id, id, name) { - var node, - _this = this; + var node; node = this.node(page_id, id); this.currentPage.state = 'mouse_event'; this.last_mouse_event = node.mouseEvent(name); - return setTimeout(function() { - if (_this.currentPage.state === 'mouse_event') { - _this.currentPage.state = 'default'; - return _this.sendResponse({ - position: _this.last_mouse_event - }); - } else { - return _this.currentPage.waitState('default', function() { + return setTimeout((function(_this) { + return function() { + if (_this.currentPage.state === 'mouse_event') { + _this.currentPage.state = 'default'; return _this.sendResponse({ position: _this.last_mouse_event }); - }); - } - }, 5); + } else { + return _this.currentPage.waitState('default', function() { + return _this.sendResponse({ + position: _this.last_mouse_event + }); + }); + } + }; + })(this), 5); }; Browser.prototype.click = function(page_id, id) { @@ -410,24 +426,24 @@ Poltergeist.Browser = (function() { }; Browser.prototype.send_keys = function(page_id, id, keys) { - var key, modifier_code, modifier_key, modifier_keys, sequence, target, _i, _j, _k, _len, _len1, _len2; + var i, j, k, key, len, len1, len2, modifier_code, modifier_key, modifier_keys, sequence, target; target = this.node(page_id, id); if (!target.containsSelection()) { target.mouseEvent('click'); } - for (_i = 0, _len = keys.length; _i < _len; _i++) { - sequence = keys[_i]; + for (i = 0, len = keys.length; i < len; i++) { + sequence = keys[i]; key = sequence.key != null ? this.currentPage.keyCode(sequence.key) : sequence; if (sequence.modifier != null) { modifier_keys = this.currentPage.keyModifierKeys(sequence.modifier); modifier_code = this.currentPage.keyModifierCode(sequence.modifier); - for (_j = 0, _len1 = modifier_keys.length; _j < _len1; _j++) { - modifier_key = modifier_keys[_j]; + for (j = 0, len1 = modifier_keys.length; j < len1; j++) { + modifier_key = modifier_keys[j]; this.currentPage.sendEvent('keydown', modifier_key); } this.currentPage.sendEvent('keypress', key, null, null, modifier_code); - for (_k = 0, _len2 = modifier_keys.length; _k < _len2; _k++) { - modifier_key = modifier_keys[_k]; + for (k = 0, len2 = modifier_keys.length; k < len2; k++) { + modifier_key = modifier_keys[k]; this.currentPage.sendEvent('keyup', modifier_key); } } else { @@ -466,9 +482,9 @@ Poltergeist.Browser = (function() { }; Browser.prototype.set_clip_rect = function(full, selector) { - var dimensions, document, rect, viewport, _ref; + var dimensions, document, rect, ref, viewport; dimensions = this.currentPage.validatedDimensions(); - _ref = [dimensions.document, dimensions.viewport], document = _ref[0], viewport = _ref[1]; + ref = [dimensions.document, dimensions.viewport], document = ref[0], viewport = ref[1]; rect = full ? { left: 0, top: 0, @@ -594,26 +610,28 @@ Poltergeist.Browser = (function() { }; Browser.prototype.go_back = function() { - var _this = this; if (this.currentPage.canGoBack) { this.currentPage.state = 'loading'; this.currentPage.goBack(); - return this.currentPage.waitState('default', function() { - return _this.sendResponse(true); - }); + return this.currentPage.waitState('default', (function(_this) { + return function() { + return _this.sendResponse(true); + }; + })(this)); } else { return this.sendResponse(false); } }; Browser.prototype.go_forward = function() { - var _this = this; if (this.currentPage.canGoForward) { this.currentPage.state = 'loading'; this.currentPage.goForward(); - return this.currentPage.waitState('default', function() { - return _this.sendResponse(true); - }); + return this.currentPage.waitState('default', (function(_this) { + return function() { + return _this.sendResponse(true); + }; + })(this)); } else { return this.sendResponse(false); } @@ -634,9 +652,8 @@ Poltergeist.Browser = (function() { return this.sendResponse(true); }; - Browser.prototype.modal_messages = function() { - this.sendResponse(this.processed_modal_messages); - return this.processed_modal_messages = []; + Browser.prototype.modal_message = function() { + return this.sendResponse(this.processed_modal_messages.shift()); }; return Browser; diff --git a/lib/capybara/poltergeist/client/compiled/connection.js b/lib/capybara/poltergeist/client/compiled/connection.js index 7513303..25a922a 100644 --- a/lib/capybara/poltergeist/client/compiled/connection.js +++ b/lib/capybara/poltergeist/client/compiled/connection.js @@ -1,10 +1,10 @@ -var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; +var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; Poltergeist.Connection = (function() { function Connection(owner, port) { this.owner = owner; this.port = port; - this.commandReceived = __bind(this.commandReceived, this); + this.commandReceived = bind(this.commandReceived, this); this.socket = new WebSocket("ws://127.0.0.1:" + this.port + "/"); this.socket.onmessage = this.commandReceived; this.socket.onclose = function() { diff --git a/lib/capybara/poltergeist/client/compiled/main.js b/lib/capybara/poltergeist/client/compiled/main.js index 005816f..b7dc09d 100644 --- a/lib/capybara/poltergeist/client/compiled/main.js +++ b/lib/capybara/poltergeist/client/compiled/main.js @@ -1,6 +1,6 @@ -var Poltergeist, system, _ref, _ref1, _ref2, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; +var Poltergeist, system, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; Poltergeist = (function() { function Poltergeist(port, width, height) { @@ -64,12 +64,11 @@ Poltergeist.Error = (function() { })(); -Poltergeist.ObsoleteNode = (function(_super) { - __extends(ObsoleteNode, _super); +Poltergeist.ObsoleteNode = (function(superClass) { + extend(ObsoleteNode, superClass); function ObsoleteNode() { - _ref = ObsoleteNode.__super__.constructor.apply(this, arguments); - return _ref; + return ObsoleteNode.__super__.constructor.apply(this, arguments); } ObsoleteNode.prototype.name = "Poltergeist.ObsoleteNode"; @@ -86,8 +85,8 @@ Poltergeist.ObsoleteNode = (function(_super) { })(Poltergeist.Error); -Poltergeist.InvalidSelector = (function(_super) { - __extends(InvalidSelector, _super); +Poltergeist.InvalidSelector = (function(superClass) { + extend(InvalidSelector, superClass); function InvalidSelector(method, selector) { this.method = method; @@ -104,8 +103,8 @@ Poltergeist.InvalidSelector = (function(_super) { })(Poltergeist.Error); -Poltergeist.FrameNotFound = (function(_super) { - __extends(FrameNotFound, _super); +Poltergeist.FrameNotFound = (function(superClass) { + extend(FrameNotFound, superClass); function FrameNotFound(frameName) { this.frameName = frameName; @@ -121,8 +120,8 @@ Poltergeist.FrameNotFound = (function(_super) { })(Poltergeist.Error); -Poltergeist.MouseEventFailed = (function(_super) { - __extends(MouseEventFailed, _super); +Poltergeist.MouseEventFailed = (function(superClass) { + extend(MouseEventFailed, superClass); function MouseEventFailed(eventName, selector, position) { this.eventName = eventName; @@ -140,8 +139,8 @@ Poltergeist.MouseEventFailed = (function(_super) { })(Poltergeist.Error); -Poltergeist.JavascriptError = (function(_super) { - __extends(JavascriptError, _super); +Poltergeist.JavascriptError = (function(superClass) { + extend(JavascriptError, superClass); function JavascriptError(errors) { this.errors = errors; @@ -157,12 +156,12 @@ Poltergeist.JavascriptError = (function(_super) { })(Poltergeist.Error); -Poltergeist.BrowserError = (function(_super) { - __extends(BrowserError, _super); +Poltergeist.BrowserError = (function(superClass) { + extend(BrowserError, superClass); - function BrowserError(message, stack) { - this.message = message; - this.stack = stack; + function BrowserError(message1, stack1) { + this.message = message1; + this.stack = stack1; } BrowserError.prototype.name = "Poltergeist.BrowserError"; @@ -175,12 +174,11 @@ Poltergeist.BrowserError = (function(_super) { })(Poltergeist.Error); -Poltergeist.StatusFailError = (function(_super) { - __extends(StatusFailError, _super); +Poltergeist.StatusFailError = (function(superClass) { + extend(StatusFailError, superClass); function StatusFailError() { - _ref1 = StatusFailError.__super__.constructor.apply(this, arguments); - return _ref1; + return StatusFailError.__super__.constructor.apply(this, arguments); } StatusFailError.prototype.name = "Poltergeist.StatusFailError"; @@ -193,12 +191,11 @@ Poltergeist.StatusFailError = (function(_super) { })(Poltergeist.Error); -Poltergeist.NoSuchWindowError = (function(_super) { - __extends(NoSuchWindowError, _super); +Poltergeist.NoSuchWindowError = (function(superClass) { + extend(NoSuchWindowError, superClass); function NoSuchWindowError() { - _ref2 = NoSuchWindowError.__super__.constructor.apply(this, arguments); - return _ref2; + return NoSuchWindowError.__super__.constructor.apply(this, arguments); } NoSuchWindowError.prototype.name = "Poltergeist.NoSuchWindowError"; @@ -211,13 +208,13 @@ Poltergeist.NoSuchWindowError = (function(_super) { })(Poltergeist.Error); -phantom.injectJs("" + phantom.libraryPath + "/web_page.js"); +phantom.injectJs(phantom.libraryPath + "/web_page.js"); -phantom.injectJs("" + phantom.libraryPath + "/node.js"); +phantom.injectJs(phantom.libraryPath + "/node.js"); -phantom.injectJs("" + phantom.libraryPath + "/connection.js"); +phantom.injectJs(phantom.libraryPath + "/connection.js"); -phantom.injectJs("" + phantom.libraryPath + "/browser.js"); +phantom.injectJs(phantom.libraryPath + "/browser.js"); system = require('system'); diff --git a/lib/capybara/poltergeist/client/compiled/node.js b/lib/capybara/poltergeist/client/compiled/node.js index 66841c6..19828c3 100644 --- a/lib/capybara/poltergeist/client/compiled/node.js +++ b/lib/capybara/poltergeist/client/compiled/node.js @@ -1,8 +1,7 @@ -var __slice = [].slice; +var slice = [].slice; Poltergeist.Node = (function() { - var name, _fn, _i, _len, _ref, - _this = this; + var fn, i, len, name, ref; Node.DELEGATES = ['allText', 'visibleText', 'getAttribute', 'value', 'set', 'setAttribute', 'isObsolete', 'removeAttribute', 'isMultiple', 'select', 'tagName', 'find', 'getAttributes', 'isVisible', 'position', 'trigger', 'parentId', 'parentIds', 'mouseEventTest', 'scrollIntoView', 'isDOMEqual', 'isDisabled', 'deleteText', 'containsSelection', 'path']; @@ -15,17 +14,17 @@ Poltergeist.Node = (function() { return new Poltergeist.Node(this.page, this.parentId()); }; - _ref = Node.DELEGATES; - _fn = function(name) { + ref = Node.DELEGATES; + fn = function(name) { return Node.prototype[name] = function() { var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; return this.page.nodeCall(this.id, name, args); }; }; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - name = _ref[_i]; - _fn(name); + for (i = 0, len = ref.length; i < len; i++) { + name = ref[i]; + fn(name); } Node.prototype.mouseEventPosition = function() { @@ -86,4 +85,4 @@ Poltergeist.Node = (function() { return Node; -}).call(this); +})(); diff --git a/lib/capybara/poltergeist/client/compiled/web_page.js b/lib/capybara/poltergeist/client/compiled/web_page.js index 1554049..b3b029c 100644 --- a/lib/capybara/poltergeist/client/compiled/web_page.js +++ b/lib/capybara/poltergeist/client/compiled/web_page.js @@ -1,9 +1,8 @@ -var __slice = [].slice, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; +var slice = [].slice, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; Poltergeist.WebPage = (function() { - var command, delegate, _fn, _fn1, _i, _j, _len, _len1, _ref, _ref1, - _this = this; + var command, delegate, fn1, fn2, i, j, len, len1, ref, ref1; WebPage.CALLBACKS = ['onConsoleMessage', 'onLoadFinished', 'onInitialized', 'onLoadStarted', 'onResourceRequested', 'onResourceReceived', 'onError', 'onNavigationRequested', 'onUrlChanged', 'onPageCreated', 'onClosing']; @@ -14,7 +13,7 @@ Poltergeist.WebPage = (function() { WebPage.EXTENSIONS = []; function WebPage(_native) { - var callback, _i, _len, _ref; + var callback, i, len, ref; this._native = _native; this._native || (this._native = require('webpage').create()); this.id = 0; @@ -27,35 +26,35 @@ Poltergeist.WebPage = (function() { this._networkTraffic = {}; this._tempHeaders = {}; this._blockedUrls = []; - _ref = WebPage.CALLBACKS; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - callback = _ref[_i]; + ref = WebPage.CALLBACKS; + for (i = 0, len = ref.length; i < len; i++) { + callback = ref[i]; this.bindCallback(callback); } } - _ref = WebPage.COMMANDS; - _fn = function(command) { + ref = WebPage.COMMANDS; + fn1 = function(command) { return WebPage.prototype[command] = function() { var args; - args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; return this.runCommand(command, args); }; }; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - command = _ref[_i]; - _fn(command); + for (i = 0, len = ref.length; i < len; i++) { + command = ref[i]; + fn1(command); } - _ref1 = WebPage.DELEGATES; - _fn1 = function(delegate) { + ref1 = WebPage.DELEGATES; + fn2 = function(delegate) { return WebPage.prototype[delegate] = function() { return this._native[delegate].apply(this._native, arguments); }; }; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - delegate = _ref1[_j]; - _fn1(delegate); + for (j = 0, len1 = ref1.length; j < len1; j++) { + delegate = ref1[j]; + fn2(delegate); } WebPage.prototype.onInitializedNative = function() { @@ -111,12 +110,12 @@ Poltergeist.WebPage = (function() { }; WebPage.prototype.onResourceRequestedNative = function(request, net) { - var abort, _ref2; + var abort, ref2; abort = this.urlBlacklist.some(function(blacklisted_url) { return request.url.indexOf(blacklisted_url) !== -1; }); if (abort) { - if (_ref2 = request.url, __indexOf.call(this._blockedUrls, _ref2) < 0) { + if (ref2 = request.url, indexOf.call(this._blockedUrls, ref2) < 0) { this._blockedUrls.push(request.url); } return net.abort(); @@ -134,9 +133,9 @@ Poltergeist.WebPage = (function() { }; WebPage.prototype.onResourceReceivedNative = function(response) { - var _ref2; - if ((_ref2 = this._networkTraffic[response.id]) != null) { - _ref2.responseParts.push(response); + var ref2; + if ((ref2 = this._networkTraffic[response.id]) != null) { + ref2.responseParts.push(response); } if (this.requestId === response.id) { if (response.redirectURL) { @@ -149,18 +148,18 @@ Poltergeist.WebPage = (function() { }; WebPage.prototype.injectAgent = function() { - var extension, _k, _len2, _ref2, _results; + var extension, k, len2, ref2, results; if (this["native"]().evaluate(function() { return typeof __poltergeist; }) === "undefined") { - this["native"]().injectJs("" + phantom.libraryPath + "/agent.js"); - _ref2 = WebPage.EXTENSIONS; - _results = []; - for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { - extension = _ref2[_k]; - _results.push(this["native"]().injectJs(extension)); + this["native"]().injectJs(phantom.libraryPath + "/agent.js"); + ref2 = WebPage.EXTENSIONS; + results = []; + for (k = 0, len2 = ref2.length; k < len2; k++) { + extension = ref2[k]; + results.push(this["native"]().injectJs(extension)); } - return _results; + return results; } }; @@ -195,20 +194,22 @@ Poltergeist.WebPage = (function() { }; WebPage.prototype.keyModifierKeys = function(names) { - var _this = this; - return names.split(',').map(function(name) { - return _this.keyCode(name.charAt(0).toUpperCase() + name.substring(1)); - }); + return names.split(',').map((function(_this) { + return function(name) { + return _this.keyCode(name.charAt(0).toUpperCase() + name.substring(1)); + }; + })(this)); }; WebPage.prototype.waitState = function(state, callback) { - var _this = this; if (this.state === state) { return callback.call(); } else { - return setTimeout((function() { - return _this.waitState(state, callback); - }), 100); + return setTimeout(((function(_this) { + return function() { + return _this.waitState(state, callback); + }; + })(this)), 100); } }; @@ -244,8 +245,8 @@ Poltergeist.WebPage = (function() { WebPage.prototype.frameUrl = function(frameName) { var query; query = function(frameName) { - var _ref2; - return (_ref2 = document.querySelector("iframe[name='" + frameName + "']")) != null ? _ref2.src : void 0; + var ref2; + return (ref2 = document.querySelector("iframe[name='" + frameName + "']")) != null ? ref2.src : void 0; }; return this.evaluate(query, frameName); }; @@ -322,21 +323,21 @@ Poltergeist.WebPage = (function() { }; WebPage.prototype.addTempHeader = function(header) { - var name, value, _results; - _results = []; + var name, results, value; + results = []; for (name in header) { value = header[name]; - _results.push(this._tempHeaders[name] = value); + results.push(this._tempHeaders[name] = value); } - return _results; + return results; }; WebPage.prototype.removeTempHeaders = function() { - var allHeaders, name, value, _ref2; + var allHeaders, name, ref2, value; allHeaders = this.getCustomHeaders(); - _ref2 = this._tempHeaders; - for (name in _ref2) { - value = _ref2[name]; + ref2 = this._tempHeaders; + for (name in ref2) { + value = ref2[name]; delete allHeaders[name]; } return this.setCustomHeaders(allHeaders); @@ -403,7 +404,7 @@ Poltergeist.WebPage = (function() { WebPage.prototype.evaluate = function() { var args, fn; - fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + fn = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; this.injectAgent(); return JSON.parse(this.sanitize(this["native"]().evaluate("function() { return PoltergeistAgent.stringify(" + (this.stringifyCall(fn, args)) + ") }"))); }; @@ -418,7 +419,7 @@ Poltergeist.WebPage = (function() { WebPage.prototype.execute = function() { var args, fn; - fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + fn = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; return this["native"]().evaluate("function() { " + (this.stringifyCall(fn, args)) + " }"); }; @@ -478,4 +479,4 @@ Poltergeist.WebPage = (function() { return WebPage; -}).call(this); +})(); diff --git a/lib/capybara/poltergeist/driver.rb b/lib/capybara/poltergeist/driver.rb index 3589cb7..f8a15d2 100644 --- a/lib/capybara/poltergeist/driver.rb +++ b/lib/capybara/poltergeist/driver.rb @@ -340,16 +340,15 @@ module Capybara::Poltergeist not_found_msg += " with #{expect_text}" if expect_text begin - modals = browser.modal_messages - raise Capybara::ModalNotFound if modals.empty? - raise Capybara::ModalNotFound if (expect_text && !modals.include?(expect_text)) + modal_text = browser.modal_message + raise Capybara::ModalNotFound if modal_text.nil? + raise Capybara::ModalNotFound if (expect_text && (modal_text != expect_text)) rescue Capybara::ModalNotFound => e raise e, not_found_msg if (Time.now - start_time) >= timeout_sec sleep(0.05) retry end - - modals.first + modal_text end end end diff --git a/spec/integration/session_spec.rb b/spec/integration/session_spec.rb index c8b3c8f..80cb985 100644 --- a/spec/integration/session_spec.rb +++ b/spec/integration/session_spec.rb @@ -669,5 +669,22 @@ describe Capybara::Session do expect(@session.find(:css, 'tspan').text).to eq 'svg foo' end end + + context 'modals' do + before do + @session.visit '/poltergeist/with_js' + end + + it 'works with nested modals' do + expect { + @session.dismiss_confirm 'Are you really sure?' do + @session.accept_confirm 'Are you sure?' do + @session.click_link('Open check twice') + end + end + }.not_to raise_error + expect(@session).to have_xpath("//a[@id='open-twice' and @confirmed='false']") + end + end end end diff --git a/spec/support/public/test.js b/spec/support/public/test.js index 356193d..3401b11 100644 --- a/spec/support/public/test.js +++ b/spec/support/public/test.js @@ -45,4 +45,13 @@ $(function() { .blur(function() { $('#changes_on_blur').text($(this).val()) }) + + $('#open-twice') + .click(function() { + if (confirm('Are you sure?')) { + if (!confirm('Are you really sure?')) { + $(this).attr('confirmed', 'false'); + } + } + }) }) diff --git a/spec/support/views/with_js.erb b/spec/support/views/with_js.erb index 7f1730d..6e9a0be 100644 --- a/spec/support/views/with_js.erb +++ b/spec/support/views/with_js.erb @@ -61,5 +61,9 @@ + +

+ Open check twice +