12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Enum for WebDriver status codes. 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @enum {number} 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)var StatusCode = { 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OK: 0, 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UNKNOWN_ERROR: 13, 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) JAVASCRIPT_ERROR: 17, 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SCRIPT_TIMEOUT: 28, 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/** 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Dictionary key for asynchronous script info. 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @const 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)var ASYNC_INFO_KEY = '$chrome_asyncScriptInfo'; 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/** 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)* Return the information of asynchronous script execution. 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)* 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)* @return {Object.<string, ?>} Information of asynchronous script execution. 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)*/ 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function getAsyncScriptInfo() { 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!(ASYNC_INFO_KEY in document)) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) document[ASYNC_INFO_KEY] = {'id': 0}; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return document[ASYNC_INFO_KEY]; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)* Execute the given script and save its asynchronous result. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)* 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)* If script1 finishes after script2 is executed, then script1's result will be 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)* discarded while script2's will be saved. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)* 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* @param {string} script The asynchronous script to be executed. The script 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* should be a proper function body. It will be wrapped in a function and 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* invoked with the given arguments and, as the final argument, a callback 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* function to invoke to report the asynchronous result. 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* @param {!Array.<*>} args Arguments to be passed to the script. 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* @param {boolean} isUserSupplied Whether the script is supplied by the user. 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* If not, UnknownError will be used instead of JavaScriptError if an 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* exception occurs during the script, and an additional error callback will 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* be supplied to the script. 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* @param {?number} opt_timeoutMillis The timeout, in milliseconds, to use. 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* If the timeout is exceeded and the callback has not been invoked, a error 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* result will be saved and future invocation of the callback will be 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)* ignored. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)*/ 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)function executeAsyncScript(script, args, isUserSupplied, opt_timeoutMillis) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var info = getAsyncScriptInfo(); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.id++; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete info.result; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var id = info.id; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) function report(status, value) { 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (id != info.id) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info.id++; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info.result = {status: status, value: value}; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) function reportValue(value) { 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) report(StatusCode.OK, value); 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) function reportScriptError(error) { 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var code = isUserSupplied ? StatusCode.JAVASCRIPT_ERROR : 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (error.code || StatusCode.UNKNOWN_ERROR); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) report(code, error.message); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.push(reportValue); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!isUserSupplied) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) args.push(reportScriptError); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) try { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new Function(script).apply(null, args); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } catch (error) { 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reportScriptError(error); 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (typeof(opt_timeoutMillis) != 'undefined') { 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window.setTimeout(function() { 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var code = isUserSupplied ? StatusCode.SCRIPT_TIMEOUT : 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StatusCode.UNKNOWN_ERROR; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var errorMsg = 'result was not received in ' + opt_timeoutMillis / 1000 + 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' seconds'; 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) report(code, errorMsg); 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }, opt_timeoutMillis); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 94