poltergeist 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +48 -2
- data/lib/capybara/poltergeist.rb +3 -0
- data/lib/capybara/poltergeist/browser.rb +48 -55
- data/lib/capybara/poltergeist/client.rb +42 -12
- data/lib/capybara/poltergeist/client/agent.coffee +48 -5
- data/lib/capybara/poltergeist/client/browser.coffee +64 -42
- data/lib/capybara/poltergeist/client/compiled/agent.js +71 -8
- data/lib/capybara/poltergeist/client/compiled/browser.js +68 -41
- data/lib/capybara/poltergeist/client/compiled/main.js +34 -5
- data/lib/capybara/poltergeist/client/compiled/node.js +34 -25
- data/lib/capybara/poltergeist/client/compiled/web_page.js +30 -7
- data/lib/capybara/poltergeist/client/main.coffee +26 -3
- data/lib/capybara/poltergeist/client/node.coffee +30 -23
- data/lib/capybara/poltergeist/client/web_page.coffee +31 -7
- data/lib/capybara/poltergeist/driver.rb +54 -19
- data/lib/capybara/poltergeist/errors.rb +63 -6
- data/lib/capybara/poltergeist/inspector.rb +35 -0
- data/lib/capybara/poltergeist/node.rb +15 -5
- data/lib/capybara/poltergeist/server.rb +7 -12
- data/lib/capybara/poltergeist/spawn.rb +17 -0
- data/lib/capybara/poltergeist/util.rb +12 -0
- data/lib/capybara/poltergeist/version.rb +1 -1
- data/lib/capybara/poltergeist/web_socket_server.rb +25 -6
- metadata +31 -25
| @@ -7,15 +7,28 @@ PoltergeistAgent = (function() { | |
| 7 7 | 
             
                this.windows = [];
         | 
| 8 8 | 
             
                this.pushWindow(window);
         | 
| 9 9 | 
             
              }
         | 
| 10 | 
            +
              PoltergeistAgent.prototype.externalCall = function(name, arguments) {
         | 
| 11 | 
            +
                try {
         | 
| 12 | 
            +
                  return {
         | 
| 13 | 
            +
                    value: this[name].apply(this, arguments)
         | 
| 14 | 
            +
                  };
         | 
| 15 | 
            +
                } catch (error) {
         | 
| 16 | 
            +
                  return {
         | 
| 17 | 
            +
                    error: error.toString()
         | 
| 18 | 
            +
                  };
         | 
| 19 | 
            +
                }
         | 
| 20 | 
            +
              };
         | 
| 10 21 | 
             
              PoltergeistAgent.prototype.pushWindow = function(new_window) {
         | 
| 11 22 | 
             
                this.windows.push(new_window);
         | 
| 12 23 | 
             
                this.window = new_window;
         | 
| 13 | 
            -
                 | 
| 24 | 
            +
                this.document = this.window.document;
         | 
| 25 | 
            +
                return null;
         | 
| 14 26 | 
             
              };
         | 
| 15 27 | 
             
              PoltergeistAgent.prototype.popWindow = function() {
         | 
| 16 28 | 
             
                this.windows.pop();
         | 
| 17 29 | 
             
                this.window = this.windows[this.windows.length - 1];
         | 
| 18 | 
            -
                 | 
| 30 | 
            +
                this.document = this.window.document;
         | 
| 31 | 
            +
                return null;
         | 
| 19 32 | 
             
              };
         | 
| 20 33 | 
             
              PoltergeistAgent.prototype.pushFrame = function(id) {
         | 
| 21 34 | 
             
                return this.pushWindow(this.document.getElementById(id).contentWindow);
         | 
| @@ -26,10 +39,12 @@ PoltergeistAgent = (function() { | |
| 26 39 | 
             
              PoltergeistAgent.prototype.currentUrl = function() {
         | 
| 27 40 | 
             
                return window.location.toString();
         | 
| 28 41 | 
             
              };
         | 
| 29 | 
            -
              PoltergeistAgent.prototype.find = function(selector,  | 
| 30 | 
            -
                var  | 
| 31 | 
            -
                 | 
| 32 | 
            -
             | 
| 42 | 
            +
              PoltergeistAgent.prototype.find = function(selector, within) {
         | 
| 43 | 
            +
                var i, ids, results, _ref;
         | 
| 44 | 
            +
                if (within == null) {
         | 
| 45 | 
            +
                  within = this.document;
         | 
| 46 | 
            +
                }
         | 
| 47 | 
            +
                results = this.document.evaluate(selector, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
         | 
| 33 48 | 
             
                ids = [];
         | 
| 34 49 | 
             
                for (i = 0, _ref = results.snapshotLength; 0 <= _ref ? i < _ref : i > _ref; 0 <= _ref ? i++ : i--) {
         | 
| 35 50 | 
             
                  ids.push(this.register(results.snapshotItem(i)));
         | 
| @@ -53,10 +68,20 @@ PoltergeistAgent = (function() { | |
| 53 68 | 
             
              PoltergeistAgent.prototype.nodeCall = function(id, name, arguments) {
         | 
| 54 69 | 
             
                var node;
         | 
| 55 70 | 
             
                node = this.get(id);
         | 
| 71 | 
            +
                if (node.isObsolete()) {
         | 
| 72 | 
            +
                  throw new PoltergeistAgent.ObsoleteNode;
         | 
| 73 | 
            +
                }
         | 
| 56 74 | 
             
                return node[name].apply(node, arguments);
         | 
| 57 75 | 
             
              };
         | 
| 58 76 | 
             
              return PoltergeistAgent;
         | 
| 59 77 | 
             
            })();
         | 
| 78 | 
            +
            PoltergeistAgent.ObsoleteNode = (function() {
         | 
| 79 | 
            +
              function ObsoleteNode() {}
         | 
| 80 | 
            +
              ObsoleteNode.prototype.toString = function() {
         | 
| 81 | 
            +
                return "PoltergeistAgent.ObsoleteNode";
         | 
| 82 | 
            +
              };
         | 
| 83 | 
            +
              return ObsoleteNode;
         | 
| 84 | 
            +
            })();
         | 
| 60 85 | 
             
            PoltergeistAgent.Node = (function() {
         | 
| 61 86 | 
             
              Node.EVENTS = {
         | 
| 62 87 | 
             
                FOCUS: ['blur', 'focus', 'focusin', 'focusout'],
         | 
| @@ -69,6 +94,9 @@ PoltergeistAgent.Node = (function() { | |
| 69 94 | 
             
              Node.prototype.parentId = function() {
         | 
| 70 95 | 
             
                return this.agent.register(this.element.parentNode);
         | 
| 71 96 | 
             
              };
         | 
| 97 | 
            +
              Node.prototype.find = function(selector) {
         | 
| 98 | 
            +
                return this.agent.find(selector, this.element);
         | 
| 99 | 
            +
              };
         | 
| 72 100 | 
             
              Node.prototype.isObsolete = function() {
         | 
| 73 101 | 
             
                var obsolete;
         | 
| 74 102 | 
             
                obsolete = __bind(function(element) {
         | 
| @@ -178,10 +206,14 @@ PoltergeistAgent.Node = (function() { | |
| 178 206 | 
             
              };
         | 
| 179 207 | 
             
              Node.prototype.position = function() {
         | 
| 180 208 | 
             
                var rect;
         | 
| 181 | 
            -
                rect = this.element. | 
| 209 | 
            +
                rect = this.element.getClientRects()[0];
         | 
| 182 210 | 
             
                return {
         | 
| 183 211 | 
             
                  top: rect.top,
         | 
| 184 | 
            -
                   | 
| 212 | 
            +
                  right: rect.right,
         | 
| 213 | 
            +
                  left: rect.left,
         | 
| 214 | 
            +
                  bottom: rect.bottom,
         | 
| 215 | 
            +
                  width: rect.width,
         | 
| 216 | 
            +
                  height: rect.height
         | 
| 185 217 | 
             
                };
         | 
| 186 218 | 
             
              };
         | 
| 187 219 | 
             
              Node.prototype.trigger = function(name) {
         | 
| @@ -197,6 +229,37 @@ PoltergeistAgent.Node = (function() { | |
| 197 229 | 
             
                }
         | 
| 198 230 | 
             
                return this.element.dispatchEvent(event);
         | 
| 199 231 | 
             
              };
         | 
| 232 | 
            +
              Node.prototype.clickTest = function(x, y) {
         | 
| 233 | 
            +
                var el, origEl;
         | 
| 234 | 
            +
                el = origEl = document.elementFromPoint(x, y);
         | 
| 235 | 
            +
                while (el) {
         | 
| 236 | 
            +
                  if (el === this.element) {
         | 
| 237 | 
            +
                    return {
         | 
| 238 | 
            +
                      status: 'success'
         | 
| 239 | 
            +
                    };
         | 
| 240 | 
            +
                  } else {
         | 
| 241 | 
            +
                    el = el.parentNode;
         | 
| 242 | 
            +
                  }
         | 
| 243 | 
            +
                }
         | 
| 244 | 
            +
                return {
         | 
| 245 | 
            +
                  status: 'failure',
         | 
| 246 | 
            +
                  selector: origEl && this.getSelector(origEl)
         | 
| 247 | 
            +
                };
         | 
| 248 | 
            +
              };
         | 
| 249 | 
            +
              Node.prototype.getSelector = function(el) {
         | 
| 250 | 
            +
                var className, selector, _i, _len, _ref;
         | 
| 251 | 
            +
                selector = el.tagName !== 'HTML' ? this.getSelector(el.parentNode) + ' ' : '';
         | 
| 252 | 
            +
                selector += el.tagName.toLowerCase();
         | 
| 253 | 
            +
                if (el.id) {
         | 
| 254 | 
            +
                  selector += "#" + el.id;
         | 
| 255 | 
            +
                }
         | 
| 256 | 
            +
                _ref = el.classList;
         | 
| 257 | 
            +
                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 258 | 
            +
                  className = _ref[_i];
         | 
| 259 | 
            +
                  selector += "." + className;
         | 
| 260 | 
            +
                }
         | 
| 261 | 
            +
                return selector;
         | 
| 262 | 
            +
              };
         | 
| 200 263 | 
             
              return Node;
         | 
| 201 264 | 
             
            })();
         | 
| 202 265 | 
             
            window.__poltergeist = new PoltergeistAgent;
         | 
| @@ -3,6 +3,7 @@ Poltergeist.Browser = (function() { | |
| 3 3 | 
             
              function Browser(owner) {
         | 
| 4 4 | 
             
                this.owner = owner;
         | 
| 5 5 | 
             
                this.state = 'default';
         | 
| 6 | 
            +
                this.page_id = 0;
         | 
| 6 7 | 
             
                this.resetPage();
         | 
| 7 8 | 
             
              }
         | 
| 8 9 | 
             
              Browser.prototype.resetPage = function() {
         | 
| @@ -15,45 +16,71 @@ Poltergeist.Browser = (function() { | |
| 15 16 | 
             
                    return this.state = 'loading';
         | 
| 16 17 | 
             
                  }
         | 
| 17 18 | 
             
                }, this);
         | 
| 18 | 
            -
                 | 
| 19 | 
            +
                this.page.onLoadFinished = __bind(function(status) {
         | 
| 19 20 | 
             
                  if (this.state === 'loading') {
         | 
| 20 | 
            -
                    this. | 
| 21 | 
            +
                    this.sendResponse(status);
         | 
| 21 22 | 
             
                    return this.state = 'default';
         | 
| 22 23 | 
             
                  }
         | 
| 23 24 | 
             
                }, this);
         | 
| 25 | 
            +
                return this.page.onInitialized = __bind(function() {
         | 
| 26 | 
            +
                  return this.page_id += 1;
         | 
| 27 | 
            +
                }, this);
         | 
| 28 | 
            +
              };
         | 
| 29 | 
            +
              Browser.prototype.sendResponse = function(response) {
         | 
| 30 | 
            +
                var errors;
         | 
| 31 | 
            +
                errors = this.page.errors();
         | 
| 32 | 
            +
                if (errors.length > 0) {
         | 
| 33 | 
            +
                  this.page.clearErrors();
         | 
| 34 | 
            +
                  return this.owner.sendError(new Poltergeist.JavascriptError(errors));
         | 
| 35 | 
            +
                } else {
         | 
| 36 | 
            +
                  return this.owner.sendResponse(response);
         | 
| 37 | 
            +
                }
         | 
| 38 | 
            +
              };
         | 
| 39 | 
            +
              Browser.prototype.node = function(page_id, id) {
         | 
| 40 | 
            +
                if (page_id === this.page_id) {
         | 
| 41 | 
            +
                  return this.page.get(id);
         | 
| 42 | 
            +
                } else {
         | 
| 43 | 
            +
                  throw new Poltergeist.ObsoleteNode;
         | 
| 44 | 
            +
                }
         | 
| 24 45 | 
             
              };
         | 
| 25 46 | 
             
              Browser.prototype.visit = function(url) {
         | 
| 26 47 | 
             
                this.state = 'loading';
         | 
| 27 48 | 
             
                return this.page.open(url);
         | 
| 28 49 | 
             
              };
         | 
| 29 50 | 
             
              Browser.prototype.current_url = function() {
         | 
| 30 | 
            -
                return this. | 
| 51 | 
            +
                return this.sendResponse(this.page.currentUrl());
         | 
| 31 52 | 
             
              };
         | 
| 32 53 | 
             
              Browser.prototype.body = function() {
         | 
| 33 | 
            -
                return this. | 
| 54 | 
            +
                return this.sendResponse(this.page.content());
         | 
| 34 55 | 
             
              };
         | 
| 35 56 | 
             
              Browser.prototype.source = function() {
         | 
| 36 | 
            -
                return this. | 
| 57 | 
            +
                return this.sendResponse(this.page.source());
         | 
| 58 | 
            +
              };
         | 
| 59 | 
            +
              Browser.prototype.find = function(selector) {
         | 
| 60 | 
            +
                return this.sendResponse({
         | 
| 61 | 
            +
                  page_id: this.page_id,
         | 
| 62 | 
            +
                  ids: this.page.find(selector)
         | 
| 63 | 
            +
                });
         | 
| 37 64 | 
             
              };
         | 
| 38 | 
            -
              Browser.prototype. | 
| 39 | 
            -
                return this. | 
| 65 | 
            +
              Browser.prototype.find_within = function(page_id, id, selector) {
         | 
| 66 | 
            +
                return this.sendResponse(this.node(page_id, id).find(selector));
         | 
| 40 67 | 
             
              };
         | 
| 41 | 
            -
              Browser.prototype.text = function(id) {
         | 
| 42 | 
            -
                return this. | 
| 68 | 
            +
              Browser.prototype.text = function(page_id, id) {
         | 
| 69 | 
            +
                return this.sendResponse(this.node(page_id, id).text());
         | 
| 43 70 | 
             
              };
         | 
| 44 | 
            -
              Browser.prototype.attribute = function(id, name) {
         | 
| 45 | 
            -
                return this. | 
| 71 | 
            +
              Browser.prototype.attribute = function(page_id, id, name) {
         | 
| 72 | 
            +
                return this.sendResponse(this.node(page_id, id).getAttribute(name));
         | 
| 46 73 | 
             
              };
         | 
| 47 | 
            -
              Browser.prototype.value = function(id) {
         | 
| 48 | 
            -
                return this. | 
| 74 | 
            +
              Browser.prototype.value = function(page_id, id) {
         | 
| 75 | 
            +
                return this.sendResponse(this.node(page_id, id).value());
         | 
| 49 76 | 
             
              };
         | 
| 50 | 
            -
              Browser.prototype.set = function(id, value) {
         | 
| 51 | 
            -
                this. | 
| 52 | 
            -
                return this. | 
| 77 | 
            +
              Browser.prototype.set = function(page_id, id, value) {
         | 
| 78 | 
            +
                this.node(page_id, id).set(value);
         | 
| 79 | 
            +
                return this.sendResponse(true);
         | 
| 53 80 | 
             
              };
         | 
| 54 | 
            -
              Browser.prototype.select_file = function(id, value) {
         | 
| 81 | 
            +
              Browser.prototype.select_file = function(page_id, id, value) {
         | 
| 55 82 | 
             
                var element, multiple;
         | 
| 56 | 
            -
                element = this. | 
| 83 | 
            +
                element = this.node(page_id, id);
         | 
| 57 84 | 
             
                multiple = element.isMultiple();
         | 
| 58 85 | 
             
                if (multiple) {
         | 
| 59 86 | 
             
                  element.removeAttribute('multiple');
         | 
| @@ -64,53 +91,53 @@ Poltergeist.Browser = (function() { | |
| 64 91 | 
             
                if (multiple) {
         | 
| 65 92 | 
             
                  element.setAttribute('multiple', 'multiple');
         | 
| 66 93 | 
             
                }
         | 
| 67 | 
            -
                return this. | 
| 94 | 
            +
                return this.sendResponse(true);
         | 
| 68 95 | 
             
              };
         | 
| 69 | 
            -
              Browser.prototype.select = function(id, value) {
         | 
| 70 | 
            -
                return this. | 
| 96 | 
            +
              Browser.prototype.select = function(page_id, id, value) {
         | 
| 97 | 
            +
                return this.sendResponse(this.node(page_id, id).select(value));
         | 
| 71 98 | 
             
              };
         | 
| 72 | 
            -
              Browser.prototype.tag_name = function(id) {
         | 
| 73 | 
            -
                return this. | 
| 99 | 
            +
              Browser.prototype.tag_name = function(page_id, id) {
         | 
| 100 | 
            +
                return this.sendResponse(this.node(page_id, id).tagName());
         | 
| 74 101 | 
             
              };
         | 
| 75 | 
            -
              Browser.prototype.visible = function(id) {
         | 
| 76 | 
            -
                return this. | 
| 102 | 
            +
              Browser.prototype.visible = function(page_id, id) {
         | 
| 103 | 
            +
                return this.sendResponse(this.node(page_id, id).isVisible());
         | 
| 77 104 | 
             
              };
         | 
| 78 105 | 
             
              Browser.prototype.evaluate = function(script) {
         | 
| 79 | 
            -
                return this. | 
| 106 | 
            +
                return this.sendResponse(JSON.parse(this.page.evaluate("function() { return JSON.stringify(" + script + ") }")));
         | 
| 80 107 | 
             
              };
         | 
| 81 108 | 
             
              Browser.prototype.execute = function(script) {
         | 
| 82 109 | 
             
                this.page.execute("function() { " + script + " }");
         | 
| 83 | 
            -
                return this. | 
| 110 | 
            +
                return this.sendResponse(true);
         | 
| 84 111 | 
             
              };
         | 
| 85 112 | 
             
              Browser.prototype.push_frame = function(id) {
         | 
| 86 113 | 
             
                this.page.pushFrame(id);
         | 
| 87 | 
            -
                return this. | 
| 114 | 
            +
                return this.sendResponse(true);
         | 
| 88 115 | 
             
              };
         | 
| 89 116 | 
             
              Browser.prototype.pop_frame = function() {
         | 
| 90 117 | 
             
                this.page.popFrame();
         | 
| 91 | 
            -
                return this. | 
| 118 | 
            +
                return this.sendResponse(true);
         | 
| 92 119 | 
             
              };
         | 
| 93 | 
            -
              Browser.prototype.click = function(id) {
         | 
| 120 | 
            +
              Browser.prototype.click = function(page_id, id) {
         | 
| 94 121 | 
             
                this.state = 'clicked';
         | 
| 95 | 
            -
                this. | 
| 122 | 
            +
                this.node(page_id, id).click();
         | 
| 96 123 | 
             
                return setTimeout(__bind(function() {
         | 
| 97 124 | 
             
                  if (this.state === 'clicked') {
         | 
| 98 125 | 
             
                    this.state = 'default';
         | 
| 99 | 
            -
                    return this. | 
| 126 | 
            +
                    return this.sendResponse(true);
         | 
| 100 127 | 
             
                  }
         | 
| 101 128 | 
             
                }, this), 10);
         | 
| 102 129 | 
             
              };
         | 
| 103 | 
            -
              Browser.prototype.drag = function(id, other_id) {
         | 
| 104 | 
            -
                this. | 
| 105 | 
            -
                return this. | 
| 130 | 
            +
              Browser.prototype.drag = function(page_id, id, other_id) {
         | 
| 131 | 
            +
                this.node(page_id, id).dragTo(this.page.get(other_id));
         | 
| 132 | 
            +
                return this.sendResponse(true);
         | 
| 106 133 | 
             
              };
         | 
| 107 | 
            -
              Browser.prototype.trigger = function(id, event) {
         | 
| 108 | 
            -
                this. | 
| 109 | 
            -
                return this. | 
| 134 | 
            +
              Browser.prototype.trigger = function(page_id, id, event) {
         | 
| 135 | 
            +
                this.node(page_id, id).trigger(event);
         | 
| 136 | 
            +
                return this.sendResponse(event);
         | 
| 110 137 | 
             
              };
         | 
| 111 138 | 
             
              Browser.prototype.reset = function() {
         | 
| 112 139 | 
             
                this.resetPage();
         | 
| 113 | 
            -
                return this. | 
| 140 | 
            +
                return this.sendResponse(true);
         | 
| 114 141 | 
             
              };
         | 
| 115 142 | 
             
              Browser.prototype.render = function(path, full) {
         | 
| 116 143 | 
             
                var dimensions, document, viewport;
         | 
| @@ -142,14 +169,14 @@ Poltergeist.Browser = (function() { | |
| 142 169 | 
             
                  });
         | 
| 143 170 | 
             
                  this.page.render(path);
         | 
| 144 171 | 
             
                }
         | 
| 145 | 
            -
                return this. | 
| 172 | 
            +
                return this.sendResponse(true);
         | 
| 146 173 | 
             
              };
         | 
| 147 174 | 
             
              Browser.prototype.resize = function(width, height) {
         | 
| 148 175 | 
             
                this.page.setViewportSize({
         | 
| 149 176 | 
             
                  width: width,
         | 
| 150 177 | 
             
                  height: height
         | 
| 151 178 | 
             
                });
         | 
| 152 | 
            -
                return this. | 
| 179 | 
            +
                return this.sendResponse(true);
         | 
| 153 180 | 
             
              };
         | 
| 154 181 | 
             
              Browser.prototype.exit = function() {
         | 
| 155 182 | 
             
                return phantom.exit();
         | 
| @@ -8,9 +8,7 @@ Poltergeist = (function() { | |
| 8 8 | 
             
                try {
         | 
| 9 9 | 
             
                  return this.browser[command.name].apply(this.browser, command.args);
         | 
| 10 10 | 
             
                } catch (error) {
         | 
| 11 | 
            -
                  return this. | 
| 12 | 
            -
                    error: error.toString()
         | 
| 13 | 
            -
                  });
         | 
| 11 | 
            +
                  return this.sendError(error);
         | 
| 14 12 | 
             
                }
         | 
| 15 13 | 
             
              };
         | 
| 16 14 | 
             
              Poltergeist.prototype.sendResponse = function(response) {
         | 
| @@ -18,15 +16,46 @@ Poltergeist = (function() { | |
| 18 16 | 
             
                  response: response
         | 
| 19 17 | 
             
                });
         | 
| 20 18 | 
             
              };
         | 
| 19 | 
            +
              Poltergeist.prototype.sendError = function(error) {
         | 
| 20 | 
            +
                return this.connection.send({
         | 
| 21 | 
            +
                  error: {
         | 
| 22 | 
            +
                    name: error.name || 'Generic',
         | 
| 23 | 
            +
                    args: error.args && error.args() || [error.toString()]
         | 
| 24 | 
            +
                  }
         | 
| 25 | 
            +
                });
         | 
| 26 | 
            +
              };
         | 
| 21 27 | 
             
              return Poltergeist;
         | 
| 22 28 | 
             
            })();
         | 
| 29 | 
            +
            window.Poltergeist = Poltergeist;
         | 
| 23 30 | 
             
            Poltergeist.ObsoleteNode = (function() {
         | 
| 24 31 | 
             
              function ObsoleteNode() {}
         | 
| 25 | 
            -
              ObsoleteNode.prototype. | 
| 26 | 
            -
             | 
| 32 | 
            +
              ObsoleteNode.prototype.name = "Poltergeist.ObsoleteNode";
         | 
| 33 | 
            +
              ObsoleteNode.prototype.args = function() {
         | 
| 34 | 
            +
                return [];
         | 
| 27 35 | 
             
              };
         | 
| 28 36 | 
             
              return ObsoleteNode;
         | 
| 29 37 | 
             
            })();
         | 
| 38 | 
            +
            Poltergeist.ClickFailed = (function() {
         | 
| 39 | 
            +
              function ClickFailed(selector, position) {
         | 
| 40 | 
            +
                this.selector = selector;
         | 
| 41 | 
            +
                this.position = position;
         | 
| 42 | 
            +
              }
         | 
| 43 | 
            +
              ClickFailed.prototype.name = "Poltergeist.ClickFailed";
         | 
| 44 | 
            +
              ClickFailed.prototype.args = function() {
         | 
| 45 | 
            +
                return [this.selector, this.position];
         | 
| 46 | 
            +
              };
         | 
| 47 | 
            +
              return ClickFailed;
         | 
| 48 | 
            +
            })();
         | 
| 49 | 
            +
            Poltergeist.JavascriptError = (function() {
         | 
| 50 | 
            +
              function JavascriptError(errors) {
         | 
| 51 | 
            +
                this.errors = errors;
         | 
| 52 | 
            +
              }
         | 
| 53 | 
            +
              JavascriptError.prototype.name = "Poltergeist.JavascriptError";
         | 
| 54 | 
            +
              JavascriptError.prototype.args = function() {
         | 
| 55 | 
            +
                return [this.errors];
         | 
| 56 | 
            +
              };
         | 
| 57 | 
            +
              return JavascriptError;
         | 
| 58 | 
            +
            })();
         | 
| 30 59 | 
             
            phantom.injectJs('web_page.js');
         | 
| 31 60 | 
             
            phantom.injectJs('node.js');
         | 
| 32 61 | 
             
            phantom.injectJs('connection.js');
         | 
| @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            var __slice = Array.prototype.slice, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
         | 
| 2 2 | 
             
            Poltergeist.Node = (function() {
         | 
| 3 3 | 
             
              var name, _fn, _i, _len, _ref;
         | 
| 4 | 
            -
              Node.DELEGATES = ['text', 'getAttribute', 'value', 'set', 'setAttribute', 'removeAttribute', 'isMultiple', 'select', 'tagName', 'isVisible', 'position', 'trigger', 'parentId'];
         | 
| 4 | 
            +
              Node.DELEGATES = ['text', 'getAttribute', 'value', 'set', 'setAttribute', 'removeAttribute', 'isMultiple', 'select', 'tagName', 'find', 'isVisible', 'position', 'trigger', 'parentId', 'clickTest'];
         | 
| 5 5 | 
             
              function Node(page, id) {
         | 
| 6 6 | 
             
                this.page = page;
         | 
| 7 7 | 
             
                this.id = id;
         | 
| @@ -9,27 +9,23 @@ Poltergeist.Node = (function() { | |
| 9 9 | 
             
              Node.prototype.parent = function() {
         | 
| 10 10 | 
             
                return new Poltergeist.Node(this.page, this.parentId());
         | 
| 11 11 | 
             
              };
         | 
| 12 | 
            -
              Node.prototype.isObsolete = function() {
         | 
| 13 | 
            -
                return this.page.nodeCall(this.id, 'isObsolete');
         | 
| 14 | 
            -
              };
         | 
| 15 12 | 
             
              _ref = Node.DELEGATES;
         | 
| 16 13 | 
             
              _fn = __bind(function(name) {
         | 
| 17 14 | 
             
                return this.prototype[name] = function() {
         | 
| 18 15 | 
             
                  var arguments, _ref2;
         | 
| 19 16 | 
             
                  _ref2 = arguments, arguments = 1 <= _ref2.length ? __slice.call(_ref2, 0) : [];
         | 
| 20 | 
            -
                   | 
| 21 | 
            -
                    throw new Poltergeist.ObsoleteNode;
         | 
| 22 | 
            -
                  } else {
         | 
| 23 | 
            -
                    return this.page.nodeCall(this.id, name, arguments);
         | 
| 24 | 
            -
                  }
         | 
| 17 | 
            +
                  return this.page.nodeCall(this.id, name, arguments);
         | 
| 25 18 | 
             
                };
         | 
| 26 19 | 
             
              }, Node);
         | 
| 27 20 | 
             
              for (_i = 0, _len = _ref.length; _i < _len; _i++) {
         | 
| 28 21 | 
             
                name = _ref[_i];
         | 
| 29 22 | 
             
                _fn(name);
         | 
| 30 23 | 
             
              }
         | 
| 31 | 
            -
              Node.prototype. | 
| 32 | 
            -
                var adjust, dimensions, document, pos, scroll, viewport;
         | 
| 24 | 
            +
              Node.prototype.clickPosition = function(scrollIntoView) {
         | 
| 25 | 
            +
                var adjust, dimensions, document, middle, pos, scroll, viewport;
         | 
| 26 | 
            +
                if (scrollIntoView == null) {
         | 
| 27 | 
            +
                  scrollIntoView = true;
         | 
| 28 | 
            +
                }
         | 
| 33 29 | 
             
                dimensions = this.page.validatedDimensions();
         | 
| 34 30 | 
             
                document = dimensions.document;
         | 
| 35 31 | 
             
                viewport = dimensions.viewport;
         | 
| @@ -45,26 +41,39 @@ Poltergeist.Node = (function() { | |
| 45 41 | 
             
                    return scroll[coord] = Math.min(document[measurement] - viewport[measurement], scroll[coord] + pos[coord] - viewport[measurement] + (viewport[measurement] / 2));
         | 
| 46 42 | 
             
                  }
         | 
| 47 43 | 
             
                };
         | 
| 48 | 
            -
                 | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
                   | 
| 52 | 
            -
             | 
| 44 | 
            +
                if (scrollIntoView) {
         | 
| 45 | 
            +
                  adjust('left', 'width');
         | 
| 46 | 
            +
                  adjust('top', 'height');
         | 
| 47 | 
            +
                  if (scroll.left !== dimensions.left || scroll.top !== dimensions.top) {
         | 
| 48 | 
            +
                    this.page.setScrollPosition(scroll);
         | 
| 49 | 
            +
                    pos = this.position();
         | 
| 50 | 
            +
                  }
         | 
| 53 51 | 
             
                }
         | 
| 54 | 
            -
                 | 
| 52 | 
            +
                middle = function(start, end, size) {
         | 
| 53 | 
            +
                  return start + ((Math.min(end, size) - start) / 2);
         | 
| 54 | 
            +
                };
         | 
| 55 | 
            +
                return {
         | 
| 56 | 
            +
                  x: middle(pos.left, pos.right, viewport.width),
         | 
| 57 | 
            +
                  y: middle(pos.top, pos.bottom, viewport.height)
         | 
| 58 | 
            +
                };
         | 
| 55 59 | 
             
              };
         | 
| 56 60 | 
             
              Node.prototype.click = function() {
         | 
| 57 | 
            -
                var  | 
| 58 | 
            -
                 | 
| 59 | 
            -
                 | 
| 61 | 
            +
                var pos, test;
         | 
| 62 | 
            +
                pos = this.clickPosition();
         | 
| 63 | 
            +
                test = this.clickTest(pos.x, pos.y);
         | 
| 64 | 
            +
                if (test.status === 'success') {
         | 
| 65 | 
            +
                  return this.page.sendEvent('click', pos.x, pos.y);
         | 
| 66 | 
            +
                } else {
         | 
| 67 | 
            +
                  throw new Poltergeist.ClickFailed(test.selector, pos);
         | 
| 68 | 
            +
                }
         | 
| 60 69 | 
             
              };
         | 
| 61 70 | 
             
              Node.prototype.dragTo = function(other) {
         | 
| 62 71 | 
             
                var otherPosition, position;
         | 
| 63 | 
            -
                position = this. | 
| 64 | 
            -
                otherPosition = other. | 
| 65 | 
            -
                this.page.sendEvent('mousedown', position. | 
| 66 | 
            -
                this.page.sendEvent('mousemove', otherPosition. | 
| 67 | 
            -
                return this.page.sendEvent('mouseup', otherPosition. | 
| 72 | 
            +
                position = this.clickPosition();
         | 
| 73 | 
            +
                otherPosition = other.clickPosition(false);
         | 
| 74 | 
            +
                this.page.sendEvent('mousedown', position.x, position.y);
         | 
| 75 | 
            +
                this.page.sendEvent('mousemove', otherPosition.x, otherPosition.y);
         | 
| 76 | 
            +
                return this.page.sendEvent('mouseup', otherPosition.x, otherPosition.y);
         | 
| 68 77 | 
             
              };
         | 
| 69 78 | 
             
              return Node;
         | 
| 70 79 | 
             
            }).call(this);
         |