annotate vendor/jcalderonzumba/gastonjs/src/Client/browser.js @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents 5311817fb629
children
rev   line source
Chris@0 1 var __indexOf = [].indexOf || function (item) {
Chris@0 2 for (var i = 0, l = this.length; i < l; i++) {
Chris@0 3 if (i in this && this[i] === item) return i;
Chris@0 4 }
Chris@0 5 return -1;
Chris@0 6 };
Chris@0 7
Chris@0 8 var xpathStringLiteral = function (s) {
Chris@0 9 if (s.indexOf('"') === -1)
Chris@0 10 return '"' + s + '"';
Chris@0 11 if (s.indexOf("'") === -1)
Chris@0 12 return "'" + s + "'";
Chris@0 13 return 'concat("' + s.replace(/"/g, '",\'"\',"') + '")';
Chris@0 14 };
Chris@0 15
Chris@0 16 Poltergeist.Browser = (function () {
Chris@0 17 /**
Chris@0 18 * Creates the "browser" inside phantomjs
Chris@0 19 * @param owner
Chris@0 20 * @param width
Chris@0 21 * @param height
Chris@0 22 * @param jsErrors
Chris@0 23 * @constructor
Chris@0 24 */
Chris@0 25 function Browser(owner, width, height, jsErrors) {
Chris@0 26 this.owner = owner;
Chris@0 27 this.width = width || 1024;
Chris@0 28 this.height = height || 768;
Chris@0 29 this.pages = [];
Chris@0 30 this.js_errors = (typeof jsErrors === 'boolean') ? jsErrors : true;
Chris@2 31 this._resourceTimeout = false;
Chris@0 32 this._debug = false;
Chris@0 33 this._counter = 0;
Chris@0 34 this.resetPage();
Chris@0 35 }
Chris@0 36
Chris@0 37 /**
Chris@0 38 * Resets the browser to a clean slate
Chris@0 39 */
Chris@0 40 Browser.prototype.resetPage = function () {
Chris@0 41 var _ref;
Chris@0 42 var self = this;
Chris@0 43
Chris@0 44 _ref = [0, []];
Chris@0 45 this._counter = _ref[0];
Chris@0 46 this.pages = _ref[1];
Chris@0 47
Chris@0 48 if (this.page != null) {
Chris@0 49 if (!this.page.closed) {
Chris@0 50 if (this.page.currentUrl() !== 'about:blank') {
Chris@0 51 this.page.clearLocalStorage();
Chris@0 52 }
Chris@0 53 this.page.release();
Chris@0 54 }
Chris@0 55 phantom.clearCookies();
Chris@0 56 }
Chris@0 57
Chris@2 58 this.page = this.currentPage = new Poltergeist.WebPage(null, this);
Chris@0 59 this.page.setViewportSize({
Chris@0 60 width: this.width,
Chris@0 61 height: this.height
Chris@0 62 });
Chris@2 63 };
Chris@0 64
Chris@2 65 /**
Chris@2 66 * Adds given newly opened Poltergeist.WebPage to the list of available windows/frames
Chris@2 67 * consulted by methods getPageByHandle, window_handle, window_handles, switch_to_window and close_window.
Chris@2 68 *
Chris@2 69 * @param {WebPage} page
Chris@2 70 */
Chris@2 71 Browser.prototype.registerPage = function (page) {
Chris@2 72 if (!('handle' in page))
Chris@2 73 {
Chris@2 74 page.handle = "" + (this._counter++);
Chris@2 75 this.pages.push(page);
Chris@2 76 }
Chris@2 77 };
Chris@2 78
Chris@2 79 /**
Chris@2 80 * Removes given closed Poltergeist.WebPage from the list of available windows/frames
Chris@2 81 * consulted by methods getPageByHandle, window_handle, window_handles, switch_to_window and close_window.
Chris@2 82 *
Chris@2 83 * @param {Poltergeist.WebPage} page
Chris@2 84 */
Chris@2 85 Browser.prototype.unregisterPage = function (page) {
Chris@2 86 if (('handle' in page) && (page.handle !== null))
Chris@2 87 {
Chris@2 88 for (var i = this.pages.length; i--;) {
Chris@2 89 if (page === this.pages[i]) {
Chris@2 90 this.pages.splice(i,1);
Chris@2 91 break;
Chris@2 92 }
Chris@2 93 }
Chris@2 94 page.handle = null;
Chris@2 95 }
Chris@0 96 };
Chris@0 97
Chris@0 98 /**
Chris@0 99 * Given a page handle id, tries to get it from the browser page list
Chris@0 100 * @param handle
Chris@0 101 * @return {WebPage}
Chris@0 102 */
Chris@0 103 Browser.prototype.getPageByHandle = function (handle) {
Chris@0 104 var filteredPages;
Chris@0 105
Chris@0 106 //TODO: perhaps we should throw a PageNotFoundByHandle or something like that..
Chris@0 107 if (handle === null || typeof handle == "undefined") {
Chris@0 108 return null;
Chris@0 109 }
Chris@0 110
Chris@0 111 filteredPages = this.pages.filter(function (p) {
Chris@0 112 return !p.closed && p.handle === handle;
Chris@0 113 });
Chris@0 114
Chris@0 115 if (filteredPages.length === 1) {
Chris@0 116 return filteredPages[0];
Chris@0 117 }
Chris@0 118
Chris@0 119 return null;
Chris@0 120 };
Chris@0 121
Chris@0 122 /**
Chris@0 123 * Sends a debug message to the console
Chris@0 124 * @param message
Chris@0 125 * @return {*}
Chris@0 126 */
Chris@0 127 Browser.prototype.debug = function (message) {
Chris@0 128 if (this._debug) {
Chris@0 129 return console.log("poltergeist [" + (new Date().getTime()) + "] " + message);
Chris@0 130 }
Chris@0 131 };
Chris@0 132
Chris@0 133 /**
Chris@0 134 * Given a page_id and id, gets if possible the node in such page
Chris@0 135 * @param page_id
Chris@0 136 * @param id
Chris@0 137 * @return {Poltergeist.Node}
Chris@0 138 */
Chris@0 139 Browser.prototype.node = function (page_id, id) {
Chris@0 140 if (this.currentPage.id === page_id) {
Chris@0 141 return this.currentPage.get(id);
Chris@0 142 } else {
Chris@0 143 throw new Poltergeist.ObsoleteNode;
Chris@0 144 }
Chris@0 145 };
Chris@0 146
Chris@0 147 /**
Chris@0 148 * Returns the frameUrl related to the frame given by name
Chris@0 149 * @param frame_name
Chris@0 150 * @return {*}
Chris@0 151 */
Chris@0 152 Browser.prototype.frameUrl = function (frame_name) {
Chris@0 153 return this.currentPage.frameUrl(frame_name);
Chris@0 154 };
Chris@0 155
Chris@0 156 /**
Chris@0 157 * This method defines the rectangular area of the web page to be rasterized when render is invoked.
Chris@0 158 * If no clipping rectangle is set, render will process the entire web page.
Chris@0 159 * @param full
Chris@0 160 * @param selector
Chris@0 161 * @return {*}
Chris@0 162 */
Chris@0 163 Browser.prototype.set_clip_rect = function (full, selector) {
Chris@0 164 var dimensions, clipDocument, rect, clipViewport;
Chris@0 165
Chris@0 166 dimensions = this.currentPage.validatedDimensions();
Chris@0 167 clipDocument = dimensions.document;
Chris@0 168 clipViewport = dimensions.viewport;
Chris@0 169
Chris@0 170 if (full) {
Chris@0 171 rect = {
Chris@0 172 left: 0,
Chris@0 173 top: 0,
Chris@0 174 width: clipDocument.width,
Chris@0 175 height: clipDocument.height
Chris@0 176 };
Chris@0 177 } else {
Chris@0 178 if (selector != null) {
Chris@0 179 rect = this.currentPage.elementBounds(selector);
Chris@0 180 } else {
Chris@0 181 rect = {
Chris@0 182 left: 0,
Chris@0 183 top: 0,
Chris@0 184 width: clipViewport.width,
Chris@0 185 height: clipViewport.height
Chris@0 186 };
Chris@0 187 }
Chris@0 188 }
Chris@0 189
Chris@0 190 this.currentPage.setClipRect(rect);
Chris@0 191 return dimensions;
Chris@0 192 };
Chris@0 193
Chris@0 194 /**
Chris@0 195 * Kill the browser, i.e kill phantomjs current process
Chris@0 196 * @return {int}
Chris@0 197 */
Chris@0 198 Browser.prototype.exit = function () {
Chris@0 199 return phantom.exit(0);
Chris@0 200 };
Chris@0 201
Chris@0 202 /**
Chris@0 203 * Do nothing
Chris@0 204 */
Chris@0 205 Browser.prototype.noop = function () {
Chris@0 206 };
Chris@0 207
Chris@0 208 /**
Chris@0 209 * Throws a new Object error
Chris@0 210 */
Chris@0 211 Browser.prototype.browser_error = function () {
Chris@0 212 throw new Error('zomg');
Chris@0 213 };
Chris@0 214
Chris@0 215 /**
Chris@0 216 * Visits a page and load its content
Chris@0 217 * @param serverResponse
Chris@0 218 * @param url
Chris@0 219 * @return {*}
Chris@0 220 */
Chris@0 221 Browser.prototype.visit = function (serverResponse, url) {
Chris@0 222 var prevUrl;
Chris@0 223 var self = this;
Chris@0 224 this.currentPage.state = 'loading';
Chris@2 225
Chris@2 226 if (this._resourceTimeout) {
Chris@2 227 this.currentPage._native.settings.resourceTimeout = this._resourceTimeout;
Chris@2 228 this.currentPage._native.onResourceTimeout = function (request) {
Chris@2 229 console.log('Response (#' + request.id + '): ' + JSON.stringify(request));
Chris@2 230 };
Chris@2 231 }
Chris@2 232
Chris@0 233 prevUrl = this.currentPage.source === null ? 'about:blank' : this.currentPage.currentUrl();
Chris@0 234 this.currentPage.open(url);
Chris@0 235 if (/#/.test(url) && prevUrl.split('#')[0] === url.split('#')[0]) {
Chris@0 236 this.currentPage.state = 'default';
Chris@0 237 return this.serverSendResponse({
Chris@0 238 status: 'success'
Chris@0 239 }, serverResponse);
Chris@0 240 } else {
Chris@0 241 return this.currentPage.waitState('default', function () {
Chris@0 242 if (self.currentPage.statusCode === null && self.currentPage.status === 'fail') {
Chris@0 243 return self.owner.serverSendError(new Poltergeist.StatusFailError, serverResponse);
Chris@0 244 } else {
Chris@0 245 return self.serverSendResponse({
Chris@0 246 status: self.currentPage.status
Chris@0 247 }, serverResponse);
Chris@0 248 }
Chris@0 249 });
Chris@0 250 }
Chris@0 251 };
Chris@0 252
Chris@0 253 /**
Chris@0 254 * Puts the control of the browser inside the IFRAME given by name
Chris@0 255 * @param serverResponse
Chris@0 256 * @param name
Chris@0 257 * @param timeout
Chris@0 258 * @return {*}
Chris@0 259 */
Chris@0 260 Browser.prototype.push_frame = function (serverResponse, name, timeout) {
Chris@0 261 var _ref;
Chris@0 262 var self = this;
Chris@0 263
Chris@0 264 if (timeout == null) {
Chris@0 265 timeout = new Date().getTime() + 2000;
Chris@0 266 }
Chris@0 267
Chris@0 268 //TODO: WTF, else if after a if with return COMMON
Chris@0 269 if (_ref = this.frameUrl(name), __indexOf.call(this.currentPage.blockedUrls(), _ref) >= 0) {
Chris@0 270 return this.serverSendResponse(true, serverResponse);
Chris@0 271 } else if (this.currentPage.pushFrame(name)) {
Chris@0 272 if (this.currentPage.currentUrl() === 'about:blank') {
Chris@0 273 this.currentPage.state = 'awaiting_frame_load';
Chris@0 274 return this.currentPage.waitState('default', function () {
Chris@0 275 return self.serverSendResponse(true, serverResponse);
Chris@0 276 });
Chris@0 277 } else {
Chris@0 278 return this.serverSendResponse(true, serverResponse);
Chris@0 279 }
Chris@0 280 } else {
Chris@0 281 if (new Date().getTime() < timeout) {
Chris@0 282 return setTimeout((function () {
Chris@0 283 return self.push_frame(serverResponse, name, timeout);
Chris@0 284 }), 50);
Chris@0 285 } else {
Chris@0 286 return this.owner.serverSendError(new Poltergeist.FrameNotFound(name), serverResponse);
Chris@0 287 }
Chris@0 288 }
Chris@0 289 };
Chris@0 290
Chris@0 291 /**
Chris@0 292 * Injects a javascript into the current page
Chris@0 293 * @param serverResponse
Chris@0 294 * @param extension
Chris@0 295 * @return {*}
Chris@0 296 */
Chris@0 297 Browser.prototype.add_extension = function (serverResponse, extension) {
Chris@0 298 //TODO: error control when the injection was not possible
Chris@0 299 this.currentPage.injectExtension(extension);
Chris@0 300 return this.serverSendResponse('success', serverResponse);
Chris@0 301 };
Chris@0 302
Chris@0 303 /**
Chris@0 304 * Returns the url we are currently in
Chris@0 305 * @param serverResponse
Chris@0 306 * @return {*}
Chris@0 307 */
Chris@0 308 Browser.prototype.current_url = function (serverResponse) {
Chris@0 309 return this.serverSendResponse(this.currentPage.currentUrl(), serverResponse);
Chris@0 310 };
Chris@0 311
Chris@0 312 /**
Chris@0 313 * Returns the current page window name
Chris@0 314 * @param serverResponse
Chris@0 315 * @returns {*}
Chris@0 316 */
Chris@0 317 Browser.prototype.window_name = function (serverResponse) {
Chris@0 318 return this.serverSendResponse(this.currentPage.windowName(), serverResponse);
Chris@0 319 };
Chris@0 320
Chris@0 321 /**
Chris@0 322 * Returns the status code associated to the page
Chris@0 323 * @param serverResponse
Chris@0 324 * @return {*}
Chris@0 325 */
Chris@0 326 Browser.prototype.status_code = function (serverResponse) {
Chris@0 327 if (this.currentPage.statusCode === undefined || this.currentPage.statusCode === null) {
Chris@0 328 return this.owner.serverSendError(new Poltergeist.StatusFailError("status_code_error"), serverResponse);
Chris@0 329 }
Chris@0 330 return this.serverSendResponse(this.currentPage.statusCode, serverResponse);
Chris@0 331 };
Chris@0 332
Chris@0 333 /**
Chris@0 334 * Returns the source code of the active frame, useful for when inside an IFRAME
Chris@0 335 * @param serverResponse
Chris@0 336 * @return {*}
Chris@0 337 */
Chris@0 338 Browser.prototype.body = function (serverResponse) {
Chris@0 339 return this.serverSendResponse(this.currentPage.content(), serverResponse);
Chris@0 340 };
Chris@0 341
Chris@0 342 /**
Chris@0 343 * Returns the source code of the page all the html
Chris@0 344 * @param serverResponse
Chris@0 345 * @return {*}
Chris@0 346 */
Chris@0 347 Browser.prototype.source = function (serverResponse) {
Chris@0 348 return this.serverSendResponse(this.currentPage.source, serverResponse);
Chris@0 349 };
Chris@0 350
Chris@0 351 /**
Chris@0 352 * Returns the current page title
Chris@0 353 * @param serverResponse
Chris@0 354 * @return {*}
Chris@0 355 */
Chris@0 356 Browser.prototype.title = function (serverResponse) {
Chris@0 357 return this.serverSendResponse(this.currentPage.title(), serverResponse);
Chris@0 358 };
Chris@0 359
Chris@0 360 /**
Chris@0 361 * Finds the elements that match a method of selection and a selector
Chris@0 362 * @param serverResponse
Chris@0 363 * @param method
Chris@0 364 * @param selector
Chris@0 365 * @return {*}
Chris@0 366 */
Chris@0 367 Browser.prototype.find = function (serverResponse, method, selector) {
Chris@0 368 return this.serverSendResponse({
Chris@0 369 page_id: this.currentPage.id,
Chris@0 370 ids: this.currentPage.find(method, selector)
Chris@0 371 }, serverResponse);
Chris@0 372 };
Chris@0 373
Chris@0 374 /**
Chris@0 375 * Find elements within a given element
Chris@0 376 * @param serverResponse
Chris@0 377 * @param page_id
Chris@0 378 * @param id
Chris@0 379 * @param method
Chris@0 380 * @param selector
Chris@0 381 * @return {*}
Chris@0 382 */
Chris@0 383 Browser.prototype.find_within = function (serverResponse, page_id, id, method, selector) {
Chris@0 384 return this.serverSendResponse(this.node(page_id, id).find(method, selector), serverResponse);
Chris@0 385 };
Chris@0 386
Chris@0 387 /**
Chris@0 388 * Returns ALL the text, visible and not visible from the given element
Chris@0 389 * @param serverResponse
Chris@0 390 * @param page_id
Chris@0 391 * @param id
Chris@0 392 * @return {*}
Chris@0 393 */
Chris@0 394 Browser.prototype.all_text = function (serverResponse, page_id, id) {
Chris@0 395 return this.serverSendResponse(this.node(page_id, id).allText(), serverResponse);
Chris@0 396 };
Chris@0 397
Chris@0 398 /**
Chris@0 399 * Returns the inner or outer html of a given id
Chris@0 400 * @param serverResponse
Chris@0 401 * @param page_id
Chris@0 402 * @param id
Chris@0 403 * @param type
Chris@0 404 * @returns Object
Chris@0 405 */
Chris@0 406 Browser.prototype.all_html = function (serverResponse, page_id, id, type) {
Chris@0 407 return this.serverSendResponse(this.node(page_id, id).allHTML(type), serverResponse);
Chris@0 408 };
Chris@0 409
Chris@0 410 /**
Chris@0 411 * Returns only the visible text in a given element
Chris@0 412 * @param serverResponse
Chris@0 413 * @param page_id
Chris@0 414 * @param id
Chris@0 415 * @return {*}
Chris@0 416 */
Chris@0 417 Browser.prototype.visible_text = function (serverResponse, page_id, id) {
Chris@0 418 return this.serverSendResponse(this.node(page_id, id).visibleText(), serverResponse);
Chris@0 419 };
Chris@0 420
Chris@0 421 /**
Chris@0 422 * Deletes the text in a given element leaving it empty
Chris@0 423 * @param serverResponse
Chris@0 424 * @param page_id
Chris@0 425 * @param id
Chris@0 426 * @return {*}
Chris@0 427 */
Chris@0 428 Browser.prototype.delete_text = function (serverResponse, page_id, id) {
Chris@0 429 return this.serverSendResponse(this.node(page_id, id).deleteText(), serverResponse);
Chris@0 430 };
Chris@0 431
Chris@0 432 /**
Chris@0 433 * Gets the value of a given attribute in an element
Chris@0 434 * @param serverResponse
Chris@0 435 * @param page_id
Chris@0 436 * @param id
Chris@0 437 * @param name
Chris@0 438 * @return {*}
Chris@0 439 */
Chris@0 440 Browser.prototype.attribute = function (serverResponse, page_id, id, name) {
Chris@0 441 return this.serverSendResponse(this.node(page_id, id).getAttribute(name), serverResponse);
Chris@0 442 };
Chris@0 443
Chris@0 444 /**
Chris@0 445 * Allows the possibility to set an attribute on a given element
Chris@0 446 * @param serverResponse
Chris@0 447 * @param page_id
Chris@0 448 * @param id
Chris@0 449 * @param name
Chris@0 450 * @param value
Chris@0 451 * @returns {*}
Chris@0 452 */
Chris@0 453 Browser.prototype.set_attribute = function (serverResponse, page_id, id, name, value) {
Chris@0 454 return this.serverSendResponse(this.node(page_id, id).setAttribute(name, value), serverResponse);
Chris@0 455 };
Chris@0 456
Chris@0 457 /**
Chris@0 458 * Allows the possibility to remove an attribute on a given element
Chris@0 459 * @param serverResponse
Chris@0 460 * @param page_id
Chris@0 461 * @param id
Chris@0 462 * @param name
Chris@0 463 * @returns {*}
Chris@0 464 */
Chris@0 465 Browser.prototype.remove_attribute = function (serverResponse, page_id, id, name) {
Chris@0 466 return this.serverSendResponse(this.node(page_id, id).removeAttribute(name), serverResponse);
Chris@0 467 };
Chris@0 468
Chris@0 469 /**
Chris@0 470 * Returns all the attributes of a given element
Chris@0 471 * @param serverResponse
Chris@0 472 * @param page_id
Chris@0 473 * @param id
Chris@0 474 * @param name
Chris@0 475 * @return {*}
Chris@0 476 */
Chris@0 477 Browser.prototype.attributes = function (serverResponse, page_id, id, name) {
Chris@0 478 return this.serverSendResponse(this.node(page_id, id).getAttributes(), serverResponse);
Chris@0 479 };
Chris@0 480
Chris@0 481 /**
Chris@0 482 * Returns all the way to the document level the parents of a given element
Chris@0 483 * @param serverResponse
Chris@0 484 * @param page_id
Chris@0 485 * @param id
Chris@0 486 * @return {*}
Chris@0 487 */
Chris@0 488 Browser.prototype.parents = function (serverResponse, page_id, id) {
Chris@0 489 return this.serverSendResponse(this.node(page_id, id).parentIds(), serverResponse);
Chris@0 490 };
Chris@0 491
Chris@0 492 /**
Chris@0 493 * Returns the element.value of an element given by its page and id
Chris@0 494 * @param serverResponse
Chris@0 495 * @param page_id
Chris@0 496 * @param id
Chris@0 497 * @return {*}
Chris@0 498 */
Chris@0 499 Browser.prototype.value = function (serverResponse, page_id, id) {
Chris@0 500 return this.serverSendResponse(this.node(page_id, id).value(), serverResponse);
Chris@0 501 };
Chris@0 502
Chris@0 503 /**
Chris@0 504 * Sets the element.value of an element by the given value
Chris@0 505 * @param serverResponse
Chris@0 506 * @param page_id
Chris@0 507 * @param id
Chris@0 508 * @param value
Chris@0 509 * @return {*}
Chris@0 510 */
Chris@0 511 Browser.prototype.set = function (serverResponse, page_id, id, value) {
Chris@0 512 this.node(page_id, id).set(value);
Chris@0 513 return this.serverSendResponse(true, serverResponse);
Chris@0 514 };
Chris@0 515
Chris@0 516 /**
Chris@0 517 * Uploads a file to an input file element
Chris@0 518 * @param serverResponse
Chris@0 519 * @param page_id
Chris@0 520 * @param id
Chris@0 521 * @param file_path
Chris@0 522 * @return {*}
Chris@0 523 */
Chris@0 524 Browser.prototype.select_file = function (serverResponse, page_id, id, file_path) {
Chris@0 525 var node = this.node(page_id, id);
Chris@0 526
Chris@0 527 this.currentPage.beforeUpload(node.id);
Chris@0 528 this.currentPage.uploadFile('[_poltergeist_selected]', file_path);
Chris@0 529 this.currentPage.afterUpload(node.id);
Chris@0 530
Chris@0 531 return this.serverSendResponse(true, serverResponse);
Chris@0 532 };
Chris@0 533
Chris@0 534 /**
Chris@0 535 * Sets a value to the selected element (to be used in select elements)
Chris@0 536 * @param serverResponse
Chris@0 537 * @param page_id
Chris@0 538 * @param id
Chris@0 539 * @param value
Chris@0 540 * @return {*}
Chris@0 541 */
Chris@0 542 Browser.prototype.select = function (serverResponse, page_id, id, value) {
Chris@0 543 return this.serverSendResponse(this.node(page_id, id).select(value), serverResponse);
Chris@0 544 };
Chris@0 545
Chris@0 546 /**
Chris@0 547 * Selects an option with the given value
Chris@0 548 * @param serverResponse
Chris@0 549 * @param page_id
Chris@0 550 * @param id
Chris@0 551 * @param value
Chris@0 552 * @param multiple
Chris@0 553 * @return {*}
Chris@0 554 */
Chris@0 555 Browser.prototype.select_option = function (serverResponse, page_id, id, value, multiple) {
Chris@0 556 return this.serverSendResponse(this.node(page_id, id).select_option(value, multiple), serverResponse);
Chris@0 557 };
Chris@0 558
Chris@0 559 /**
Chris@0 560 *
Chris@0 561 * @param serverResponse
Chris@0 562 * @param page_id
Chris@0 563 * @param id
Chris@0 564 * @return {*}
Chris@0 565 */
Chris@0 566 Browser.prototype.tag_name = function (serverResponse, page_id, id) {
Chris@0 567 return this.serverSendResponse(this.node(page_id, id).tagName(), serverResponse);
Chris@0 568 };
Chris@0 569
Chris@0 570
Chris@0 571 /**
Chris@0 572 * Tells if an element is visible or not
Chris@0 573 * @param serverResponse
Chris@0 574 * @param page_id
Chris@0 575 * @param id
Chris@0 576 * @return {*}
Chris@0 577 */
Chris@0 578 Browser.prototype.visible = function (serverResponse, page_id, id) {
Chris@0 579 return this.serverSendResponse(this.node(page_id, id).isVisible(), serverResponse);
Chris@0 580 };
Chris@0 581
Chris@0 582 /**
Chris@0 583 * Tells if an element is disabled
Chris@0 584 * @param serverResponse
Chris@0 585 * @param page_id
Chris@0 586 * @param id
Chris@0 587 * @return {*}
Chris@0 588 */
Chris@0 589 Browser.prototype.disabled = function (serverResponse, page_id, id) {
Chris@0 590 return this.serverSendResponse(this.node(page_id, id).isDisabled(), serverResponse);
Chris@0 591 };
Chris@0 592
Chris@0 593 /**
Chris@0 594 * Evaluates a javascript and returns the outcome to the client
Chris@0 595 * This will be JSON response so your script better be returning objects that can be used
Chris@0 596 * in JSON.stringify
Chris@0 597 * @param serverResponse
Chris@0 598 * @param script
Chris@0 599 * @return {*}
Chris@0 600 */
Chris@0 601 Browser.prototype.evaluate = function (serverResponse, script) {
Chris@0 602 return this.serverSendResponse(this.currentPage.evaluate("function() { return " + script + " }"), serverResponse);
Chris@0 603 };
Chris@0 604
Chris@0 605 /**
Chris@0 606 * Executes a javascript and goes back to the client with true if there were no errors
Chris@0 607 * @param serverResponse
Chris@0 608 * @param script
Chris@0 609 * @return {*}
Chris@0 610 */
Chris@0 611 Browser.prototype.execute = function (serverResponse, script) {
Chris@0 612 this.currentPage.execute("function() { " + script + " }");
Chris@0 613 return this.serverSendResponse(true, serverResponse);
Chris@0 614 };
Chris@0 615
Chris@0 616 /**
Chris@0 617 * If inside a frame then we will go back to the parent
Chris@0 618 * Not defined behaviour if you pop and are not inside an iframe
Chris@0 619 * @param serverResponse
Chris@0 620 * @return {*}
Chris@0 621 */
Chris@0 622 Browser.prototype.pop_frame = function (serverResponse) {
Chris@0 623 return this.serverSendResponse(this.currentPage.popFrame(), serverResponse);
Chris@0 624 };
Chris@0 625
Chris@0 626 /**
Chris@0 627 * Gets the window handle id by a given window name
Chris@0 628 * @param serverResponse
Chris@0 629 * @param name
Chris@0 630 * @return {*}
Chris@0 631 */
Chris@0 632 Browser.prototype.window_handle = function (serverResponse, name) {
Chris@0 633 var handle, pageByWindowName;
Chris@0 634
Chris@0 635 if (name === null || typeof name == "undefined" || name.length === 0) {
Chris@0 636 return this.serverSendResponse(this.currentPage.handle, serverResponse);
Chris@0 637 }
Chris@0 638
Chris@0 639 handle = null;
Chris@0 640
Chris@0 641 //Lets search the handle by the given window name
Chris@0 642 var filteredPages = this.pages.filter(function (p) {
Chris@0 643 return !p.closed && p.windowName() === name;
Chris@0 644 });
Chris@0 645
Chris@0 646 //A bit of error control is always good
Chris@0 647 if (Array.isArray(filteredPages) && filteredPages.length >= 1) {
Chris@0 648 pageByWindowName = filteredPages[0];
Chris@0 649 } else {
Chris@0 650 pageByWindowName = null;
Chris@0 651 }
Chris@0 652
Chris@0 653 if (pageByWindowName !== null && typeof pageByWindowName != "undefined") {
Chris@0 654 handle = pageByWindowName.handle;
Chris@0 655 }
Chris@0 656
Chris@0 657 return this.serverSendResponse(handle, serverResponse);
Chris@0 658 };
Chris@0 659
Chris@0 660 /**
Chris@0 661 * Returns all the window handles of opened windows
Chris@0 662 * @param serverResponse
Chris@0 663 * @return {*}
Chris@0 664 */
Chris@0 665 Browser.prototype.window_handles = function (serverResponse) {
Chris@0 666 var handles, filteredPages;
Chris@0 667
Chris@0 668 filteredPages = this.pages.filter(function (p) {
Chris@0 669 return !p.closed;
Chris@0 670 });
Chris@0 671
Chris@0 672 if (filteredPages.length > 0) {
Chris@0 673 handles = filteredPages.map(function (p) {
Chris@0 674 return p.handle;
Chris@0 675 });
Chris@0 676 if (handles.length === 0) {
Chris@0 677 handles = null;
Chris@0 678 }
Chris@0 679 } else {
Chris@0 680 handles = null;
Chris@0 681 }
Chris@0 682
Chris@0 683 return this.serverSendResponse(handles, serverResponse);
Chris@0 684 };
Chris@0 685
Chris@0 686 /**
Chris@0 687 * Tries to switch to a window given by the handle id
Chris@0 688 * @param serverResponse
Chris@0 689 * @param handle
Chris@0 690 * @return {*}
Chris@0 691 */
Chris@0 692 Browser.prototype.switch_to_window = function (serverResponse, handle) {
Chris@0 693 var page;
Chris@0 694 var self = this;
Chris@0 695
Chris@0 696 page = this.getPageByHandle(handle);
Chris@0 697 if (page === null || typeof page == "undefined") {
Chris@0 698 throw new Poltergeist.NoSuchWindowError;
Chris@0 699 }
Chris@0 700
Chris@0 701 if (page !== this.currentPage) {
Chris@0 702 return page.waitState('default', function () {
Chris@0 703 self.currentPage = page;
Chris@0 704 return self.serverSendResponse(true, serverResponse);
Chris@0 705 });
Chris@0 706 }
Chris@0 707
Chris@0 708 return this.serverSendResponse(true, serverResponse);
Chris@0 709 };
Chris@0 710
Chris@0 711 /**
Chris@0 712 * Opens a new window where we can do stuff
Chris@0 713 * @param serverResponse
Chris@0 714 * @return {*}
Chris@0 715 */
Chris@0 716 Browser.prototype.open_new_window = function (serverResponse) {
Chris@0 717 return this.execute(serverResponse, 'window.open()');
Chris@0 718 };
Chris@0 719
Chris@0 720 /**
Chris@0 721 * Closes the window given by handle name if possible
Chris@2 722 * NOTE: Closing a page in PhantomJS also closes new windows/frames opened from that page (QWebPage behaviour)
Chris@0 723 * @param serverResponse
Chris@0 724 * @param handle
Chris@0 725 * @return {*}
Chris@0 726 */
Chris@0 727 Browser.prototype.close_window = function (serverResponse, handle) {
Chris@0 728 var page;
Chris@0 729
Chris@0 730 page = this.getPageByHandle(handle);
Chris@0 731 if (page === null || typeof page == "undefined") {
Chris@0 732 //TODO: should we throw error since we actually could not find the window?
Chris@0 733 return this.serverSendResponse(false, serverResponse);
Chris@0 734 }
Chris@0 735
Chris@0 736 //TODO: we have to add some control here to actually asses that the release has been done
Chris@0 737 page.release();
Chris@0 738 return this.serverSendResponse(true, serverResponse);
Chris@0 739 };
Chris@0 740
Chris@0 741 /**
Chris@0 742 * Generic mouse event on an element
Chris@0 743 * @param serverResponse
Chris@0 744 * @param page_id
Chris@0 745 * @param id
Chris@0 746 * @param name
Chris@0 747 * @return {number}
Chris@0 748 */
Chris@0 749 Browser.prototype.mouse_event = function (serverResponse, page_id, id, name) {
Chris@0 750 var node;
Chris@0 751 var self = this;
Chris@0 752 node = this.node(page_id, id);
Chris@0 753 this.currentPage.state = 'mouse_event';
Chris@0 754 this.last_mouse_event = node.mouseEvent(name);
Chris@0 755 return setTimeout(function () {
Chris@0 756 if (self.currentPage.state === 'mouse_event') {
Chris@0 757 self.currentPage.state = 'default';
Chris@0 758 return self.serverSendResponse({
Chris@0 759 position: self.last_mouse_event
Chris@0 760 }, serverResponse);
Chris@0 761 } else {
Chris@0 762 return self.currentPage.waitState('default', function () {
Chris@0 763 return self.serverSendResponse({
Chris@0 764 position: self.last_mouse_event
Chris@0 765 }, serverResponse);
Chris@0 766 });
Chris@0 767 }
Chris@0 768 }, 5);
Chris@0 769 };
Chris@0 770
Chris@0 771 /**
Chris@0 772 * Simple click on the element
Chris@0 773 * @param serverResponse
Chris@0 774 * @param page_id
Chris@0 775 * @param id
Chris@0 776 * @return {*}
Chris@0 777 */
Chris@0 778 Browser.prototype.click = function (serverResponse, page_id, id) {
Chris@0 779 return this.mouse_event(serverResponse, page_id, id, 'click');
Chris@0 780 };
Chris@0 781
Chris@0 782 /**
Chris@0 783 * Right click on the element
Chris@0 784 * @param serverResponse
Chris@0 785 * @param page_id
Chris@0 786 * @param id
Chris@0 787 * @return {*}
Chris@0 788 */
Chris@0 789 Browser.prototype.right_click = function (serverResponse, page_id, id) {
Chris@0 790 return this.mouse_event(serverResponse, page_id, id, 'rightclick');
Chris@0 791 };
Chris@0 792
Chris@0 793 /**
Chris@0 794 * Double click on the element given by page and id
Chris@0 795 * @param serverResponse
Chris@0 796 * @param page_id
Chris@0 797 * @param id
Chris@0 798 * @return {*}
Chris@0 799 */
Chris@0 800 Browser.prototype.double_click = function (serverResponse, page_id, id) {
Chris@0 801 return this.mouse_event(serverResponse, page_id, id, 'doubleclick');
Chris@0 802 };
Chris@0 803
Chris@0 804 /**
Chris@0 805 * Executes a mousemove event on the page and given element
Chris@0 806 * @param serverResponse
Chris@0 807 * @param page_id
Chris@0 808 * @param id
Chris@0 809 * @return {*}
Chris@0 810 */
Chris@0 811 Browser.prototype.hover = function (serverResponse, page_id, id) {
Chris@0 812 return this.mouse_event(serverResponse, page_id, id, 'mousemove');
Chris@0 813 };
Chris@0 814
Chris@0 815 /**
Chris@0 816 * Triggers a mouse click event on the given coordinates
Chris@0 817 * @param serverResponse
Chris@0 818 * @param x
Chris@0 819 * @param y
Chris@0 820 * @return {*}
Chris@0 821 */
Chris@0 822 Browser.prototype.click_coordinates = function (serverResponse, x, y) {
Chris@0 823 var response;
Chris@0 824
Chris@0 825 this.currentPage.sendEvent('click', x, y);
Chris@0 826 response = {
Chris@0 827 click: {
Chris@0 828 x: x,
Chris@0 829 y: y
Chris@0 830 }
Chris@0 831 };
Chris@0 832
Chris@0 833 return this.serverSendResponse(response, serverResponse);
Chris@0 834 };
Chris@0 835
Chris@0 836 /**
Chris@0 837 * Drags one element into another, useful for nice javascript thingies
Chris@0 838 * @param serverResponse
Chris@0 839 * @param page_id
Chris@0 840 * @param id
Chris@0 841 * @param other_id
Chris@0 842 * @return {*}
Chris@0 843 */
Chris@0 844 Browser.prototype.drag = function (serverResponse, page_id, id, other_id) {
Chris@0 845 this.node(page_id, id).dragTo(this.node(page_id, other_id));
Chris@0 846 return this.serverSendResponse(true, serverResponse);
Chris@0 847 };
Chris@0 848
Chris@0 849 /**
Chris@0 850 * Triggers an event on the given page and element
Chris@0 851 * @param serverResponse
Chris@0 852 * @param page_id
Chris@0 853 * @param id
Chris@0 854 * @param event
Chris@0 855 * @return {*}
Chris@0 856 */
Chris@0 857 Browser.prototype.trigger = function (serverResponse, page_id, id, event) {
Chris@0 858 this.node(page_id, id).trigger(event);
Chris@0 859 return this.serverSendResponse(event, serverResponse);
Chris@0 860 };
Chris@0 861
Chris@0 862 /**
Chris@0 863 * Checks if two elements are equal on a dom level
Chris@0 864 * @param serverResponse
Chris@0 865 * @param page_id
Chris@0 866 * @param id
Chris@0 867 * @param other_id
Chris@0 868 * @return {*}
Chris@0 869 */
Chris@0 870 Browser.prototype.equals = function (serverResponse, page_id, id, other_id) {
Chris@0 871 return this.serverSendResponse(this.node(page_id, id).isEqual(this.node(page_id, other_id)), serverResponse);
Chris@0 872 };
Chris@0 873
Chris@0 874 /**
Chris@0 875 * Resets the current page to a clean slate
Chris@0 876 * @param serverResponse
Chris@0 877 * @return {*}
Chris@0 878 */
Chris@0 879 Browser.prototype.reset = function (serverResponse) {
Chris@0 880 this.resetPage();
Chris@0 881 return this.serverSendResponse(true, serverResponse);
Chris@0 882 };
Chris@0 883
Chris@0 884 /**
Chris@0 885 * Scrolls to a position given by the left, top coordinates
Chris@0 886 * @param serverResponse
Chris@0 887 * @param left
Chris@0 888 * @param top
Chris@0 889 * @return {*}
Chris@0 890 */
Chris@0 891 Browser.prototype.scroll_to = function (serverResponse, left, top) {
Chris@0 892 this.currentPage.setScrollPosition({
Chris@0 893 left: left,
Chris@0 894 top: top
Chris@0 895 });
Chris@0 896 return this.serverSendResponse(true, serverResponse);
Chris@0 897 };
Chris@0 898
Chris@0 899 /**
Chris@0 900 * Sends keys to an element simulating as closest as possible what a user would do
Chris@0 901 * when typing
Chris@0 902 * @param serverResponse
Chris@0 903 * @param page_id
Chris@0 904 * @param id
Chris@0 905 * @param keys
Chris@0 906 * @return {*}
Chris@0 907 */
Chris@0 908 Browser.prototype.send_keys = function (serverResponse, page_id, id, keys) {
Chris@0 909 var key, sequence, target, _i, _len;
Chris@0 910 target = this.node(page_id, id);
Chris@0 911 if (!target.containsSelection()) {
Chris@0 912 target.mouseEvent('click');
Chris@0 913 }
Chris@0 914 for (_i = 0, _len = keys.length; _i < _len; _i++) {
Chris@0 915 sequence = keys[_i];
Chris@0 916 key = sequence.key != null ? this.currentPage.keyCode(sequence.key) : sequence;
Chris@0 917 this.currentPage.sendEvent('keypress', key);
Chris@0 918 }
Chris@0 919 return this.serverSendResponse(true, serverResponse);
Chris@0 920 };
Chris@0 921
Chris@0 922 /**
Chris@0 923 * Sends a native phantomjs key event to element
Chris@0 924 * @param serverResponse
Chris@0 925 * @param page_id
Chris@0 926 * @param id
Chris@0 927 * @param keyEvent
Chris@0 928 * @param key
Chris@0 929 * @param modifier
Chris@0 930 */
Chris@0 931 Browser.prototype.key_event = function (serverResponse, page_id, id, keyEvent, key, modifier) {
Chris@0 932 var keyEventModifierMap;
Chris@0 933 var keyEventModifier;
Chris@0 934 var target;
Chris@0 935
Chris@0 936 keyEventModifierMap = {
Chris@0 937 'none': 0x0,
Chris@0 938 'shift': 0x02000000,
Chris@0 939 'ctrl': 0x04000000,
Chris@0 940 'alt': 0x08000000,
Chris@0 941 'meta': 0x10000000
Chris@0 942 };
Chris@0 943 keyEventModifier = keyEventModifierMap[modifier];
Chris@0 944
Chris@0 945 target = this.node(page_id, id);
Chris@0 946 if (!target.containsSelection()) {
Chris@0 947 target.mouseEvent('click');
Chris@0 948 }
Chris@0 949 target.page.sendEvent(keyEvent, key, null, null, keyEventModifier);
Chris@0 950
Chris@0 951 return this.serverSendResponse(true, serverResponse);
Chris@0 952 };
Chris@0 953
Chris@0 954 /**
Chris@0 955 * Sends the rendered page in a base64 encoding
Chris@0 956 * @param serverResponse
Chris@0 957 * @param format
Chris@0 958 * @param full
Chris@0 959 * @param selector
Chris@0 960 * @return {*}
Chris@0 961 */
Chris@0 962 Browser.prototype.render_base64 = function (serverResponse, format, full, selector) {
Chris@0 963 var encoded_image;
Chris@0 964 if (selector == null) {
Chris@0 965 selector = null;
Chris@0 966 }
Chris@0 967 this.set_clip_rect(full, selector);
Chris@0 968 encoded_image = this.currentPage.renderBase64(format);
Chris@0 969 return this.serverSendResponse(encoded_image, serverResponse);
Chris@0 970 };
Chris@0 971
Chris@0 972 /**
Chris@0 973 * Renders the current page entirely or a given selection
Chris@0 974 * @param serverResponse
Chris@0 975 * @param path
Chris@0 976 * @param full
Chris@0 977 * @param selector
Chris@0 978 * @return {*}
Chris@0 979 */
Chris@0 980 Browser.prototype.render = function (serverResponse, path, full, selector) {
Chris@0 981 var dimensions;
Chris@0 982 if (selector == null) {
Chris@0 983 selector = null;
Chris@0 984 }
Chris@0 985 dimensions = this.set_clip_rect(full, selector);
Chris@0 986 this.currentPage.setScrollPosition({
Chris@0 987 left: 0,
Chris@0 988 top: 0
Chris@0 989 });
Chris@0 990 this.currentPage.render(path);
Chris@0 991 this.currentPage.setScrollPosition({
Chris@0 992 left: dimensions.left,
Chris@0 993 top: dimensions.top
Chris@0 994 });
Chris@0 995 return this.serverSendResponse(true, serverResponse);
Chris@0 996 };
Chris@0 997
Chris@0 998
Chris@0 999 /**
Chris@0 1000 * Sets the paper size, useful when printing to PDF
Chris@0 1001 * @param serverResponse
Chris@0 1002 * @param size
Chris@0 1003 * @return {*}
Chris@0 1004 */
Chris@0 1005 Browser.prototype.set_paper_size = function (serverResponse, size) {
Chris@0 1006 this.currentPage.setPaperSize(size);
Chris@0 1007 return this.serverSendResponse(true, serverResponse);
Chris@0 1008 };
Chris@0 1009
Chris@0 1010 /**
Chris@0 1011 * Sets the zoom factor on the current page
Chris@0 1012 * @param serverResponse
Chris@0 1013 * @param zoom_factor
Chris@0 1014 * @return {*}
Chris@0 1015 */
Chris@0 1016 Browser.prototype.set_zoom_factor = function (serverResponse, zoom_factor) {
Chris@0 1017 this.currentPage.setZoomFactor(zoom_factor);
Chris@0 1018 return this.serverSendResponse(true, serverResponse);
Chris@0 1019 };
Chris@0 1020
Chris@0 1021 /**
Chris@0 1022 * Resizes the browser viewport, useful when testing mobile stuff
Chris@0 1023 * @param serverResponse
Chris@0 1024 * @param width
Chris@0 1025 * @param height
Chris@0 1026 * @return {*}
Chris@0 1027 */
Chris@0 1028 Browser.prototype.resize = function (serverResponse, width, height) {
Chris@0 1029 this.currentPage.setViewportSize({
Chris@0 1030 width: width,
Chris@0 1031 height: height
Chris@0 1032 });
Chris@0 1033 return this.serverSendResponse(true, serverResponse);
Chris@0 1034 };
Chris@0 1035
Chris@0 1036 /**
Chris@0 1037 * Gets the browser viewport size
Chris@0 1038 * Because PhantomJS is headless (nothing is shown)
Chris@0 1039 * viewportSize effectively simulates the size of the window like in a traditional browser.
Chris@0 1040 * @param serverResponse
Chris@0 1041 * @param handle
Chris@0 1042 * @return {*}
Chris@0 1043 */
Chris@0 1044 Browser.prototype.window_size = function (serverResponse, handle) {
Chris@0 1045 //TODO: add support for window handles
Chris@0 1046 return this.serverSendResponse(this.currentPage.viewportSize(), serverResponse);
Chris@0 1047 };
Chris@0 1048
Chris@0 1049 /**
Chris@0 1050 * Returns the network traffic that the current page has generated
Chris@0 1051 * @param serverResponse
Chris@0 1052 * @return {*}
Chris@0 1053 */
Chris@0 1054 Browser.prototype.network_traffic = function (serverResponse) {
Chris@0 1055 return this.serverSendResponse(this.currentPage.networkTraffic(), serverResponse);
Chris@0 1056 };
Chris@0 1057
Chris@0 1058 /**
Chris@0 1059 * Clears the accumulated network_traffic in the current page
Chris@0 1060 * @param serverResponse
Chris@0 1061 * @return {*}
Chris@0 1062 */
Chris@0 1063 Browser.prototype.clear_network_traffic = function (serverResponse) {
Chris@0 1064 this.currentPage.clearNetworkTraffic();
Chris@0 1065 return this.serverSendResponse(true, serverResponse);
Chris@0 1066 };
Chris@0 1067
Chris@0 1068 /**
Chris@0 1069 * Gets the headers of the current page
Chris@0 1070 * @param serverResponse
Chris@0 1071 * @return {*}
Chris@0 1072 */
Chris@0 1073 Browser.prototype.get_headers = function (serverResponse) {
Chris@0 1074 return this.serverSendResponse(this.currentPage.getCustomHeaders(), serverResponse);
Chris@0 1075 };
Chris@0 1076
Chris@0 1077 /**
Chris@0 1078 * Set headers in the browser
Chris@0 1079 * @param serverResponse
Chris@0 1080 * @param headers
Chris@0 1081 * @return {*}
Chris@0 1082 */
Chris@0 1083 Browser.prototype.set_headers = function (serverResponse, headers) {
Chris@0 1084 if (headers['User-Agent']) {
Chris@0 1085 this.currentPage.setUserAgent(headers['User-Agent']);
Chris@0 1086 }
Chris@0 1087 this.currentPage.setCustomHeaders(headers);
Chris@0 1088 return this.serverSendResponse(true, serverResponse);
Chris@0 1089 };
Chris@0 1090
Chris@0 1091 /**
Chris@0 1092 * Given an array of headers, adds them to the page
Chris@0 1093 * @param serverResponse
Chris@0 1094 * @param headers
Chris@0 1095 * @return {*}
Chris@0 1096 */
Chris@0 1097 Browser.prototype.add_headers = function (serverResponse, headers) {
Chris@0 1098 var allHeaders, name, value;
Chris@0 1099 allHeaders = this.currentPage.getCustomHeaders();
Chris@0 1100 for (name in headers) {
Chris@0 1101 if (headers.hasOwnProperty(name)) {
Chris@0 1102 value = headers[name];
Chris@0 1103 allHeaders[name] = value;
Chris@0 1104 }
Chris@0 1105 }
Chris@0 1106 return this.set_headers(serverResponse, allHeaders);
Chris@0 1107 };
Chris@0 1108
Chris@0 1109 /**
Chris@0 1110 * Adds a header to the page temporary or permanently
Chris@0 1111 * @param serverResponse
Chris@0 1112 * @param header
Chris@0 1113 * @param permanent
Chris@0 1114 * @return {*}
Chris@0 1115 */
Chris@0 1116 Browser.prototype.add_header = function (serverResponse, header, permanent) {
Chris@0 1117 if (!permanent) {
Chris@0 1118 this.currentPage.addTempHeader(header);
Chris@0 1119 }
Chris@0 1120 return this.add_headers(serverResponse, header);
Chris@0 1121 };
Chris@0 1122
Chris@0 1123
Chris@0 1124 /**
Chris@0 1125 * Sends back the client the response headers sent from the browser when making
Chris@0 1126 * the page request
Chris@0 1127 * @param serverResponse
Chris@0 1128 * @return {*}
Chris@0 1129 */
Chris@0 1130 Browser.prototype.response_headers = function (serverResponse) {
Chris@0 1131 return this.serverSendResponse(this.currentPage.responseHeaders(), serverResponse);
Chris@0 1132 };
Chris@0 1133
Chris@0 1134 /**
Chris@0 1135 * Returns the cookies of the current page being browsed
Chris@0 1136 * @param serverResponse
Chris@0 1137 * @return {*}
Chris@0 1138 */
Chris@0 1139 Browser.prototype.cookies = function (serverResponse) {
Chris@0 1140 return this.serverSendResponse(this.currentPage.cookies(), serverResponse);
Chris@0 1141 };
Chris@0 1142
Chris@0 1143 /**
Chris@0 1144 * Sets a cookie in the browser, the format of the cookies has to be the format it says
Chris@0 1145 * on phantomjs documentation and as such you can set it in other domains, not on the
Chris@0 1146 * current page
Chris@0 1147 * @param serverResponse
Chris@0 1148 * @param cookie
Chris@0 1149 * @return {*}
Chris@0 1150 */
Chris@0 1151 Browser.prototype.set_cookie = function (serverResponse, cookie) {
Chris@0 1152 return this.serverSendResponse(phantom.addCookie(cookie), serverResponse);
Chris@0 1153 };
Chris@0 1154
Chris@0 1155 /**
Chris@0 1156 * Remove a cookie set on the current page
Chris@0 1157 * @param serverResponse
Chris@0 1158 * @param name
Chris@0 1159 * @return {*}
Chris@0 1160 */
Chris@0 1161 Browser.prototype.remove_cookie = function (serverResponse, name) {
Chris@0 1162 //TODO: add error control to check if the cookie was properly deleted
Chris@0 1163 this.currentPage.deleteCookie(name);
Chris@0 1164 phantom.deleteCookie(name);
Chris@0 1165 return this.serverSendResponse(true, serverResponse);
Chris@0 1166 };
Chris@0 1167
Chris@0 1168 /**
Chris@0 1169 * Clear the cookies in the browser
Chris@0 1170 * @param serverResponse
Chris@0 1171 * @return {*}
Chris@0 1172 */
Chris@0 1173 Browser.prototype.clear_cookies = function (serverResponse) {
Chris@0 1174 phantom.clearCookies();
Chris@0 1175 return this.serverSendResponse(true, serverResponse);
Chris@0 1176 };
Chris@0 1177
Chris@0 1178 /**
Chris@0 1179 * Enables / Disables the cookies on the browser
Chris@0 1180 * @param serverResponse
Chris@0 1181 * @param flag
Chris@0 1182 * @return {*}
Chris@0 1183 */
Chris@0 1184 Browser.prototype.cookies_enabled = function (serverResponse, flag) {
Chris@0 1185 phantom.cookiesEnabled = flag;
Chris@0 1186 return this.serverSendResponse(true, serverResponse);
Chris@0 1187 };
Chris@0 1188
Chris@0 1189 /**
Chris@2 1190 * Sets proxy or unsets web proxy
Chris@2 1191 * @param {Object} serverResponse Phantomjs response object associated to the client request
Chris@2 1192 * @param {String} ip IP or host name, or null/'' to unset
Chris@2 1193 * @param {Number} port port number
Chris@2 1194 * @param {String} proxyType socks5 or anything else for http(s)
Chris@2 1195 * @param {String} user optional username for proxy authentication
Chris@2 1196 * @param {String} password optional password for proxy authentication
Chris@2 1197 * @return {*}
Chris@2 1198 * @see {@link https://github.com/ariya/phantomjs/pull/11829/commits/84c31822a2e5eba21fe42298ec27ec4ccab95667}
Chris@2 1199 */
Chris@2 1200 Browser.prototype.set_proxy = function (serverResponse, ip, port, proxyType, user, password) {
Chris@2 1201 phantom.setProxy(ip, port, proxyType, user, password);
Chris@2 1202 return this.serverSendResponse(true, serverResponse);
Chris@2 1203 };
Chris@2 1204
Chris@2 1205 /**
Chris@0 1206 * US19: DONE
Chris@0 1207 * Sets a basic authentication credential to access a page
Chris@0 1208 * THIS SHOULD BE USED BEFORE accessing a page
Chris@0 1209 * @param serverResponse
Chris@0 1210 * @param user
Chris@0 1211 * @param password
Chris@0 1212 * @return {*}
Chris@0 1213 */
Chris@0 1214 Browser.prototype.set_http_auth = function (serverResponse, user, password) {
Chris@0 1215 this.currentPage.setHttpAuth(user, password);
Chris@0 1216 return this.serverSendResponse(true, serverResponse);
Chris@0 1217 };
Chris@0 1218
Chris@0 1219 /**
Chris@0 1220 * Sets the flag whether to fail on javascript errors or not.
Chris@0 1221 * @param serverResponse
Chris@0 1222 * @param value
Chris@0 1223 * @return {*}
Chris@0 1224 */
Chris@0 1225 Browser.prototype.set_js_errors = function (serverResponse, value) {
Chris@0 1226 this.js_errors = value;
Chris@0 1227 return this.serverSendResponse(true, serverResponse);
Chris@0 1228 };
Chris@0 1229
Chris@0 1230 /**
Chris@0 1231 * Sets the debug mode to boolean value
Chris@0 1232 * @param serverResponse
Chris@0 1233 * @param value
Chris@0 1234 * @return {*}
Chris@0 1235 */
Chris@0 1236 Browser.prototype.set_debug = function (serverResponse, value) {
Chris@0 1237 this._debug = value;
Chris@0 1238 return this.serverSendResponse(true, serverResponse);
Chris@0 1239 };
Chris@0 1240
Chris@0 1241 /**
Chris@0 1242 * Goes back in the history when possible
Chris@0 1243 * @param serverResponse
Chris@0 1244 * @return {*}
Chris@0 1245 */
Chris@0 1246 Browser.prototype.go_back = function (serverResponse) {
Chris@0 1247 var self = this;
Chris@0 1248 if (this.currentPage.canGoBack()) {
Chris@0 1249 this.currentPage.state = 'loading';
Chris@0 1250 this.currentPage.goBack();
Chris@0 1251 return this.currentPage.waitState('default', function () {
Chris@0 1252 return self.serverSendResponse(true, serverResponse);
Chris@0 1253 });
Chris@0 1254 } else {
Chris@0 1255 return this.serverSendResponse(false, serverResponse);
Chris@0 1256 }
Chris@0 1257 };
Chris@0 1258
Chris@0 1259 /**
Chris@0 1260 * Reloads the page if possible
Chris@0 1261 * @return {*}
Chris@0 1262 */
Chris@0 1263 Browser.prototype.reload = function (serverResponse) {
Chris@0 1264 var self = this;
Chris@0 1265 this.currentPage.state = 'loading';
Chris@0 1266 this.currentPage.reload();
Chris@0 1267 return this.currentPage.waitState('default', function () {
Chris@0 1268 return self.serverSendResponse(true, serverResponse);
Chris@0 1269 });
Chris@0 1270 };
Chris@0 1271
Chris@0 1272 /**
Chris@0 1273 * Goes forward in the browser history if possible
Chris@0 1274 * @param serverResponse
Chris@0 1275 * @return {*}
Chris@0 1276 */
Chris@0 1277 Browser.prototype.go_forward = function (serverResponse) {
Chris@0 1278 var self = this;
Chris@0 1279 if (this.currentPage.canGoForward()) {
Chris@0 1280 this.currentPage.state = 'loading';
Chris@0 1281 this.currentPage.goForward();
Chris@0 1282 return this.currentPage.waitState('default', function () {
Chris@0 1283 return self.serverSendResponse(true, serverResponse);
Chris@0 1284 });
Chris@0 1285 } else {
Chris@0 1286 return this.serverSendResponse(false, serverResponse);
Chris@0 1287 }
Chris@0 1288 };
Chris@0 1289
Chris@0 1290 /**
Chris@2 1291 * Sets the timeout in milliseconds, after which any resource requested will stop
Chris@2 1292 * trying and proceed with other parts of the page
Chris@2 1293 * @param serverResponse
Chris@2 1294 * @param value
Chris@2 1295 * @return {*}
Chris@2 1296 */
Chris@2 1297 Browser.prototype.set_resource_timeout = function (serverResponse, value) {
Chris@2 1298 this._resourceTimeout = value;
Chris@2 1299 return this.serverSendResponse(true, serverResponse);
Chris@2 1300 };
Chris@2 1301
Chris@2 1302 /**
Chris@0 1303 * Sets the urlBlacklist for the given urls as parameters
Chris@0 1304 * @return {boolean}
Chris@0 1305 */
Chris@0 1306 Browser.prototype.set_url_blacklist = function (serverResponse, blackList) {
Chris@0 1307 this.currentPage.urlBlacklist = Array.prototype.slice.call(blackList);
Chris@0 1308 return this.serverSendResponse(true, serverResponse);
Chris@0 1309 };
Chris@0 1310
Chris@0 1311 /**
Chris@0 1312 * Runs a browser command and returns the response back to the client
Chris@0 1313 * when the command has finished the execution
Chris@0 1314 * @param command
Chris@0 1315 * @param serverResponse
Chris@0 1316 * @return {*}
Chris@0 1317 */
Chris@0 1318 Browser.prototype.serverRunCommand = function (command, serverResponse) {
Chris@0 1319 var commandData;
Chris@0 1320 var commandArgs;
Chris@0 1321 var commandName;
Chris@0 1322
Chris@0 1323 commandName = command.name;
Chris@0 1324 commandArgs = command.args;
Chris@0 1325 this.currentPage.state = 'default';
Chris@0 1326 commandData = [serverResponse].concat(commandArgs);
Chris@0 1327
Chris@0 1328 if (typeof this[commandName] !== "function") {
Chris@0 1329 //We can not run such command
Chris@0 1330 throw new Poltergeist.Error();
Chris@0 1331 }
Chris@0 1332
Chris@0 1333 return this[commandName].apply(this, commandData);
Chris@0 1334 };
Chris@0 1335
Chris@0 1336 /**
Chris@0 1337 * Sends a response back to the client who made the request
Chris@0 1338 * @param response
Chris@0 1339 * @param serverResponse
Chris@0 1340 * @return {*}
Chris@0 1341 */
Chris@0 1342 Browser.prototype.serverSendResponse = function (response, serverResponse) {
Chris@0 1343 var errors;
Chris@0 1344 errors = this.currentPage.errors;
Chris@0 1345 this.currentPage.clearErrors();
Chris@0 1346 if (errors.length > 0 && this.js_errors) {
Chris@0 1347 return this.owner.serverSendError(new Poltergeist.JavascriptError(errors), serverResponse);
Chris@0 1348 } else {
Chris@0 1349 return this.owner.serverSendResponse(response, serverResponse);
Chris@0 1350 }
Chris@0 1351 };
Chris@0 1352
Chris@0 1353 return Browser;
Chris@0 1354
Chris@0 1355 })();