Commit 292e8ca6 authored by Tricia Crichton's avatar Tricia Crichton Committed by Commit Bot

[ChromeDriver] Use standard javascript objects

Some websites alter basic javascript objects (Promise, Array, Symbol)
in ways that break ChromeDriver. This cl saves the original javascript
objects, and then uses those when making javascript calls.

Unittests were reconfigured to support the 2 SendCommand calls needed in
ConnectIfNecessary.

Bug: chromedriver:3237
Change-Id: Id7375ec78d661c5400f44db4e2e0d4e443cbd8a0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1947385
Commit-Queue: Tricia Crichton <triciac@chromium.org>
Reviewed-by: default avatarJohn Chen <johnchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#723593}
parent 686aa0a9
...@@ -183,6 +183,28 @@ Status DevToolsClientImpl::ConnectIfNecessary() { ...@@ -183,6 +183,28 @@ Status DevToolsClientImpl::ConnectIfNecessary() {
if (!socket_->Connect(url_)) if (!socket_->Connect(url_))
return Status(kDisconnected, "unable to connect to renderer"); return Status(kDisconnected, "unable to connect to renderer");
} }
if (id_ != kBrowserwideDevToolsClientId) {
base::DictionaryValue params;
std::string script =
"(function () {"
"window.cdc_adoQpoasnfa76pfcZLmcfl_Array = window.Array;"
"window.cdc_adoQpoasnfa76pfcZLmcfl_Promise = window.Promise;"
"window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol = window.Symbol;"
"}) ();";
params.SetString("source", script);
Timeout small = Timeout(base::TimeDelta::FromSeconds(1));
Status status = SendCommandWithTimeout(
"Page.addScriptToEvaluateOnNewDocument", params, &small);
if (status.IsError())
return status;
params.Clear();
params.SetString("expression", script);
status = SendCommandWithTimeout("Runtime.evaluate", params, &small);
if (status.IsError())
return status;
}
} }
unnotified_connect_listeners_ = listeners_; unnotified_connect_listeners_ = listeners_;
......
...@@ -281,6 +281,7 @@ function isElement(value) { ...@@ -281,6 +281,7 @@ function isElement(value) {
* @return {boolean} True if value is an iterable collection. * @return {boolean} True if value is an iterable collection.
*/ */
function isCollection(value) { function isCollection(value) {
const Symbol = window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol || window.Symbol;
return (typeof value[Symbol.iterator] === 'function'); return (typeof value[Symbol.iterator] === 'function');
} }
...@@ -307,6 +308,7 @@ function cloneWithAlgorithm(item, seen, algo, opt_cache) { ...@@ -307,6 +308,7 @@ function cloneWithAlgorithm(item, seen, algo, opt_cache) {
} }
if (isCollection(item)) { if (isCollection(item)) {
const Array = window.cdc_adoQpoasnfa76pfcZLmcfl_Array || window.Array;
tmp = new Array(item.length); tmp = new Array(item.length);
for (let i = 0; i < item.length; ++i) for (let i = 0; i < item.length; ++i)
tmp[i] = maybeCopyProperty(i); tmp[i] = maybeCopyProperty(i);
...@@ -442,6 +444,7 @@ function callFunction(func, args, w3c, opt_unwrappedReturn) { ...@@ -442,6 +444,7 @@ function callFunction(func, args, w3c, opt_unwrappedReturn) {
let status = 0; let status = 0;
let returnValue; let returnValue;
const Promise = window.cdc_adoQpoasnfa76pfcZLmcfl_Promise || window.Promise;
try { try {
const unwrappedArgs = jsonDeserialize(args, [], cache); const unwrappedArgs = jsonDeserialize(args, [], cache);
const tmp = func.apply(null, unwrappedArgs); const tmp = func.apply(null, unwrappedArgs);
......
...@@ -49,6 +49,7 @@ function getAsyncScriptInfo() { ...@@ -49,6 +49,7 @@ function getAsyncScriptInfo() {
function executeAsyncScript(script, args, isUserSupplied) { function executeAsyncScript(script, args, isUserSupplied) {
let resolveHandle; let resolveHandle;
let rejectHandle; let rejectHandle;
const Promise = window.cdc_adoQpoasnfa76pfcZLmcfl_Promise || window.Promise;
var promise = new Promise((resolve, reject) => { var promise = new Promise((resolve, reject) => {
resolveHandle = resolve; resolveHandle = resolve;
rejectHandle = reject; rejectHandle = reject;
......
...@@ -14,6 +14,7 @@ function executeScript(script, args) { ...@@ -14,6 +14,7 @@ function executeScript(script, args) {
try { try {
// Convert script (as a string) into an async function. // Convert script (as a string) into an async function.
const f = (new Function('return async function(){' + script + '}'))(); const f = (new Function('return async function(){' + script + '}'))();
const Promise = window.cdc_adoQpoasnfa76pfcZLmcfl_Promise || window.Promise;
return Promise.resolve(f.apply(null, args)); return Promise.resolve(f.apply(null, args));
} catch (e) { } catch (e) {
return Promise.reject(e); return Promise.reject(e);
......
...@@ -81,3 +81,7 @@ function runTests() { ...@@ -81,3 +81,7 @@ function runTests() {
window.addEventListener('load', function() { window.addEventListener('load', function() {
runTests(); runTests();
}); });
window.cdc_adoQpoasnfa76pfcZLmcfl_Array = window.Array;
window.cdc_adoQpoasnfa76pfcZLmcfl_Promise = window.Promise;
window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol = window.Symbol;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment