Commit 2f0d6985 authored by chrisgao@chromium.org's avatar chrisgao@chromium.org

[chromedriver] Fix issue of cache id in JS.

Also enable three passed java tests.

NOTRY=true

Review URL: https://chromiumcodereview.appspot.com/14230010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194743 0039d316-1c4b-4281-b951-d872f2087c98
parent 0f1320ae
......@@ -35,6 +35,7 @@ var ELEMENT_KEY = 'ELEMENT';
function Cache() {
this.cache_ = {};
this.nextId_ = 1;
this.idPrefix_ = Math.random().toString();
}
Cache.prototype = {
......@@ -45,12 +46,12 @@ Cache.prototype = {
* @param {!Object} item The item to store in the cache.
* @return {number} The ID for the cached item.
*/
storeItem_: function(item) {
storeItem: function(item) {
for (var i in this.cache_) {
if (item == this.cache_[i])
return i;
}
var id = this.nextId_.toString();
var id = this.idPrefix_ + ':' + this.nextId_;
this.cache_[id] = item;
this.nextId_++;
return id;
......@@ -62,7 +63,7 @@ Cache.prototype = {
* @param {number} id The ID for the cached item to retrieve.
* @return {!Object} The retrieved item.
*/
retrieveItem_: function(id) {
retrieveItem: function(id) {
var item = this.cache_[id];
if (item)
return item;
......@@ -86,63 +87,67 @@ Cache.prototype = {
if (!node)
delete this.cache_[id];
}
},
}
};
/**
/**
* Returns the global object cache for the page.
* @param {Document=} opt_doc The document whose cache to retrieve. Defaults to
* the current document.
* @return {!Cache} The page's object cache.
*/
function getPageCache(opt_doc) {
var doc = opt_doc || document;
// We use the same key as selenium's javascript/atoms/inject.js.
var key = '$wdc_';
if (!(key in doc))
doc[key] = new Cache();
return doc[key];
}
/**
* Wraps the given value to be transmitted remotely by converting
* appropriate objects to cached object IDs.
*
* @param {*} value The value to wrap.
* @return {*} The wrapped value.
*/
wrap: function(value) {
function wrap(value) {
if (typeof(value) == 'object' && value != null) {
var nodeType = value['nodeType'];
if (nodeType == NodeType.ELEMENT || nodeType == NodeType.DOCUMENT) {
var wrapped = {};
wrapped[ELEMENT_KEY] = this.storeItem_(value);
wrapped[ELEMENT_KEY] = getPageCache(value.ownerDocument).storeItem(value);
return wrapped;
}
var obj = (typeof(value.length) == 'number') ? [] : {};
for (var prop in value)
obj[prop] = this.wrap(value[prop]);
obj[prop] = wrap(value[prop]);
return obj;
}
return value;
},
}
/**
/**
* Unwraps the given value by converting from object IDs to the cached
* objects.
*
* @param {*} value The value to unwrap.
* @param {Cache} cache The cache to retrieve wrapped elements from.
* @return {*} The unwrapped value.
*/
unwrap: function(value) {
function unwrap(value, cache) {
if (typeof(value) == 'object' && value != null) {
if (ELEMENT_KEY in value)
return this.retrieveItem_(value[ELEMENT_KEY]);
return cache.retrieveItem(value[ELEMENT_KEY]);
var obj = (typeof(value.length) == 'number') ? [] : {};
for (var prop in value)
obj[prop] = this.unwrap(value[prop]);
obj[prop] = unwrap(value[prop], cache);
return obj;
}
return value;
}
};
/**
* Returns the global object cache for the page.
* @return {!Cache} The page's object cache.
*/
function getPageCache() {
// We use the same key as selenium's javascript/atoms/inject.js.
var key = '$wdc_';
if (!(key in document))
document[key] = new Cache();
return document[key];
}
/**
......@@ -168,11 +173,11 @@ function callFunction(func, args, opt_unwrappedReturn) {
cache.clearStale();
if (opt_unwrappedReturn)
return func.apply(null, cache.unwrap(args));
return func.apply(null, unwrap(args, cache));
var status = 0;
try {
var returnValue = cache.wrap(func.apply(null, cache.unwrap(args)));
var returnValue = wrap(func.apply(null, unwrap(args, cache)));
} catch (error) {
status = error.code || StatusCode.UNKNOWN_ERROR;
var returnValue = error.message;
......
......@@ -4,13 +4,21 @@
<script src='call_function.js'></script>
<script>
function clearCache() {
getPageCache().cache_ = {};
}
function testCallFunctionNoArgs() {
clearCache();
var result = callFunction(function() { return 1; }, []);
assertEquals(0, result.status);
assertEquals(1, result.value);
}
function testCallFunctionThrows() {
clearCache();
var result = callFunction(function() { throw new Error('fake error'); }, []);
assertEquals(StatusCode.UNKNOWN_ERROR, result.status);
assertEquals('fake error', result.value);
......@@ -26,120 +34,129 @@ function testCallFunctionThrows() {
}
function testCallFunctionArgs() {
clearCache();
function func(primitive, elem) {
return [primitive, elem.querySelector('div')];
}
var cache = getPageCache();
var result = callFunction(func, [1, cache.wrap(document)]);
var result = callFunction(func, [1, wrap(document)]);
assertEquals(0, result.status);
assertEquals(1, result.value[0]);
assertEquals(document.querySelector('div'), cache.unwrap(result.value[1]));
var cache = getPageCache();
assertEquals(document.querySelector('div'), unwrap(result.value[1], cache));
}
function testCallFunctionArgsUnwrappedReturn() {
clearCache();
function func(elem) {
return elem.querySelector('div');
}
var cache = getPageCache();
var result = callFunction(func, [cache.wrap(document)], true);
var result = callFunction(func, [wrap(document)], true);
assertEquals(document.querySelector('div'), result);
}
function testCacheWrap() {
var cache = new Cache();
assertEquals(1, cache.wrap(1));
assertEquals(1, cache.unwrap(1));
assertEquals("1", cache.wrap("1"));
assertEquals("1", cache.unwrap("1"));
assertEquals(false, cache.wrap(false));
assertEquals(false, cache.unwrap(false));
assertEquals(null, cache.wrap(null));
assertEquals(null, cache.unwrap(null));
assertEquals(undefined, cache.wrap(undefined));
assertEquals(undefined, cache.unwrap(undefined));
clearCache();
assertEquals(1, wrap(1));
assertEquals(1, unwrap(1));
assertEquals("1", wrap("1"));
assertEquals("1", unwrap("1"));
assertEquals(false, wrap(false));
assertEquals(false, unwrap(false));
assertEquals(null, wrap(null));
assertEquals(null, unwrap(null));
assertEquals(undefined, wrap(undefined));
assertEquals(undefined, unwrap(undefined));
function func() {}
assertEquals(func, cache.wrap(func));
assertEquals(func, cache.unwrap(func));
assertEquals(func, wrap(func));
assertEquals(func, unwrap(func));
var cache = getPageCache();
var arr = [1, new Array(1, new Object({a: 1, b: {a: 1, b: {}, c: 3}}), 3)];
var originalJson = JSON.stringify(arr);
arr[1][1].b.b[ELEMENT_KEY] = cache.nextId_.toString();
arr[1][1].b.b[ELEMENT_KEY] = cache.idPrefix_ + ':' + cache.nextId_;
var wrappedJson = JSON.stringify(arr);
arr[1][1].b.b = document;
assertEquals(wrappedJson, JSON.stringify(cache.wrap(arr)));
var unwrapped = cache.unwrap(JSON.parse(wrappedJson));
assertEquals(wrappedJson, JSON.stringify(wrap(arr)));
var unwrapped = unwrap(JSON.parse(wrappedJson), cache);
assertEquals(document, unwrapped[1][1].b.b);
unwrapped[1][1].b.b = {};
assertEquals(originalJson, JSON.stringify(unwrapped));
}
function testCacheDoubleWrap() {
var cache = new Cache();
assertEquals(cache.wrap(document)[ELEMENT_KEY],
cache.wrap(document)[ELEMENT_KEY]);
clearCache();
assertEquals(wrap(document)[ELEMENT_KEY], wrap(document)[ELEMENT_KEY]);
}
function testCacheUnwrapThrows() {
clearCache();
try {
var cache = new Cache();
var wrapped = {};
wrapped[ELEMENT_KEY] = '1';
cache.unwrap(wrapped);
unwrap(wrapped, getPageCache());
assert(false);
} catch (e) {
return;
}
assert(false);
}
function testClearStale() {
clearCache();
var doc = document;
var div = doc.querySelector('div');
var span = doc.querySelector('span');
var cache = new Cache();
var wrappedDoc = cache.wrap(doc);
var wrappedDiv = cache.wrap(div);
var wrappedSpan = cache.wrap(span);
var wrappedDoc = wrap(doc);
var wrappedDiv = wrap(div);
var wrappedSpan = wrap(span);
var cache = getPageCache();
cache.clearStale();
assertEquals(doc, cache.unwrap(wrappedDoc));
assertEquals(div, cache.unwrap(wrappedDiv));
assertEquals(span, cache.unwrap(wrappedSpan));
assertEquals(doc, unwrap(wrappedDoc, cache));
assertEquals(div, unwrap(wrappedDiv, cache));
assertEquals(span, unwrap(wrappedSpan, cache));
div.removeChild(span);
cache.clearStale();
assertEquals(doc, cache.unwrap(wrappedDoc));
assertEquals(div, cache.unwrap(wrappedDiv));
assertEquals(doc, unwrap(wrappedDoc, cache));
assertEquals(div, unwrap(wrappedDiv, cache));
try {
cache.unwrap(wrappedSpan);
unwrap(wrappedSpan, cache);
assert(false);
} catch (e) {
return;
}
assert(false);
}
function testCacheQuerySelector() {
var cache = new Cache();
clearCache();
var cache = getPageCache();
assertEquals(document.querySelector('div'),
cache.unwrap(cache.wrap(document.querySelector('div'))));
unwrap(wrap(document.querySelector('div')), cache));
assertEquals(document.querySelectorAll('div')[0],
cache.unwrap(cache.wrap(document.querySelectorAll('div')))[0]);
unwrap(wrap(document.querySelectorAll('div')), cache)[0]);
}
function testCacheStaleRef() {
var cache = new Cache();
clearCache();
var cache = getPageCache();
var img = document.createElement('img');
document.body.appendChild(img);
var wrappedImg = cache.wrap(img);
var wrappedImg = wrap(img);
document.body.removeChild(img);
cache.clearStale();
try {
cache.unwrap(wrappedImg);
unwrap(wrappedImg, cache);
assert(false);
} catch (e) {
assertEquals(StatusCode.STALE_ELEMENT_REFERENCE, e.code);
return;
}
assert(false);
}
</script>
......
......@@ -36,9 +36,6 @@ _REVISION_NEGATIVE_FILTER['HEAD'] = [
'CorrectEventFiringTest.testShouldFireEventsInTheRightOrder',
'CorrectEventFiringTest.testShouldFireFocusEventWhenClicking',
'DragAndDropTest.testDragTooFar',
'ElementEqualityTest.testAnElementFoundInADifferentFrameViaJsShouldHaveSameId',
'ElementFindingTest.testAnElementFoundInADifferentFrameIsStale',
'ElementFindingTest.testAnElementFoundInADifferentFrameViaJsCanBeUsed',
'ExecutingAsyncJavascriptTest.includesAlertTextInUnhandledAlertException',
'ExecutingAsyncJavascriptTest.throwsIfAlertHappensDuringScript',
'ExecutingAsyncJavascriptTest.throwsIfAlertHappensDuringScriptWhichTimesOut',
......
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