| <!DOCTYPE html> | |
| <!-- | |
| Copyright 2010 WebDriver committers | |
| Copyright 2010 Google Inc. | |
| Licensed under the Apache License, Version 2.0 (the "License"); | |
| you may not use this file except in compliance with the License. | |
| You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| --> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>Unit Tests for bot.inject</title> | |
| <link rel="stylesheet" href="/filez/_main/third_party/js/qunit/qunit.css"> | |
| <script src="/filez/_main/third_party/js/qunit/qunit.js"></script> | |
| <script src="/filez/_main/third_party/js/qunit/qunit_test_runner.js"></script> | |
| <script src="test_bootstrap.js"></script> | |
| <script type="text/javascript"> | |
| goog.require('bot.Error'); | |
| goog.require('bot.ErrorCode'); | |
| goog.require('bot.inject'); | |
| goog.require('bot.inject.cache'); | |
| goog.require('bot.json'); | |
| goog.require('bot.userAgent'); | |
| goog.require('goog.Promise'); | |
| goog.require('goog.dom'); | |
| goog.require('goog.events'); | |
| goog.require('goog.userAgent'); | |
| goog.require('goog.userAgent.product'); | |
| </script> | |
| </head> | |
| <body> | |
| <div id="qunit"></div> | |
| <div id="qunit-fixture"></div> | |
| <div style="display:none"> | |
| <iframe id="test-frame" src="testdata/blank_page.html"></iframe> | |
| </div> | |
| <script type="text/javascript"> | |
| goog.global.MY_GLOBAL_CONSTANT = 123; | |
| var frame, frameWin, frameDoc; | |
| QUnit.testStart(function() { | |
| frame = goog.dom.$('test-frame'); | |
| frameWin = goog.dom.getFrameContentWindow(frame); | |
| frameDoc = goog.dom.getFrameContentDocument(frame); | |
| document[bot.inject.cache.CACHE_KEY_] = null; | |
| frameDoc[bot.inject.cache.CACHE_KEY_] = null; | |
| }); | |
| QUnit.test('AddWindowToCache', function(assert) { | |
| var id = bot.inject.cache.addElement(frameWin); | |
| assert.strictEqual(bot.inject.cache.getElement(id), frameWin); | |
| }); | |
| QUnit.test('AddWindowToCacheMultipleTimesReusesIds', function(assert) { | |
| var id1 = bot.inject.cache.addElement(frameWin); | |
| var id2 = bot.inject.cache.addElement(frameWin); | |
| assert.strictEqual(id2, id1); | |
| }); | |
| QUnit.test('GetElementThrowsIfWindowIsClosed', function(assert) { | |
| var win = {document: 1, closed: 1}; | |
| var id = bot.inject.cache.addElement(win); | |
| assert.throws(function() { bot.inject.cache.getElement(id); }); | |
| }); | |
| QUnit.test('ShouldWrapAndUnwrapWindow', function(assert) { | |
| var wrapped = bot.inject.wrapValue(frameWin); | |
| assert.ok(wrapped !== null); | |
| assert.ok(wrapped !== undefined); | |
| assert.ok(goog.isObject(wrapped)); | |
| assert.ok(goog.object.containsKey(wrapped, bot.inject.WINDOW_KEY)); | |
| var id = wrapped[bot.inject.WINDOW_KEY]; | |
| var res = bot.inject.cache.getElement(id); | |
| assert.strictEqual(res, frameWin); | |
| assert.strictEqual(bot.inject.unwrapValue(wrapped), frameWin); | |
| }); | |
| QUnit.test('ShouldBeAbleToCacheElements', function(assert) { | |
| var id = bot.inject.cache.addElement(document.body); | |
| var el = bot.inject.cache.getElement(id); | |
| assert.strictEqual(el, document.body); | |
| }); | |
| QUnit.test('ShouldReuseExistingIdIfElementAlreadyExistsInTheCache', function(assert) { | |
| var id1 = bot.inject.cache.addElement(document.body); | |
| var id2 = bot.inject.cache.addElement(document.body); | |
| assert.strictEqual(id2, id1); | |
| }); | |
| QUnit.test('ShouldThrowIfElementDoesNotExistInTheCache', function(assert) { | |
| assert.throws(function() { bot.inject.cache.getElement('not-there'); }); | |
| }); | |
| QUnit.test('ShouldDecodeIdsWhenRetrievingFromTheCache', function(assert) { | |
| var id = bot.inject.cache.addElement(document.body); | |
| id = encodeURIComponent(id); | |
| var el = bot.inject.cache.getElement(id); | |
| assert.strictEqual(el, document.body); | |
| }); | |
| QUnit.test('ShouldThrowIfCachedElementIsNoLongerAttachedToTheDom', function(assert) { | |
| if (goog.userAgent.IE) { | |
| assert.ok(true, 'Skipping: TODO fix for IE'); | |
| return; | |
| } | |
| var div = document.createElement('DIV'); | |
| document.body.appendChild(div); | |
| var id = bot.inject.cache.addElement(div); | |
| assert.strictEqual(bot.inject.cache.getElement(id), div); | |
| document.body.removeChild(div); | |
| assert.throws(function() { bot.inject.cache.getElement(id); }); | |
| }); | |
| QUnit.test('DoesNotWrapStringBooleansNumbersOrNull', function(assert) { | |
| assert.strictEqual(bot.inject.wrapValue('foo'), 'foo'); | |
| assert.strictEqual(bot.inject.wrapValue(123), 123); | |
| assert.ok(bot.inject.wrapValue(true)); | |
| assert.strictEqual(bot.inject.wrapValue(null), null); | |
| }); | |
| QUnit.test('ConvertsUndefinedValueToNullForWrapping', function(assert) { | |
| assert.strictEqual(bot.inject.wrapValue(undefined), null); | |
| }); | |
| QUnit.test('ShouldAddElementsToCacheWhenWrapping', function(assert) { | |
| var wrapped = bot.inject.wrapValue(document.body); | |
| assert.ok(wrapped !== null); | |
| assert.ok(wrapped !== undefined); | |
| assert.ok(goog.isObject(wrapped)); | |
| assert.ok(goog.object.containsKey(wrapped, bot.inject.ELEMENT_KEY)); | |
| var id = wrapped[bot.inject.ELEMENT_KEY]; | |
| var el = bot.inject.cache.getElement(id); | |
| assert.strictEqual(el, document.body); | |
| }); | |
| QUnit.test('ShouldRecursivelyWrapArrays', function(assert) { | |
| var unwrapped = [123, 'abc', null, document.body]; | |
| var wrapped = bot.inject.wrapValue(unwrapped); | |
| assert.strictEqual(wrapped.length, unwrapped.length); | |
| assert.strictEqual(wrapped[0], unwrapped[0]); | |
| assert.strictEqual(wrapped[1], unwrapped[1]); | |
| assert.strictEqual(wrapped[2], unwrapped[2]); | |
| assert.ok(goog.object.containsKey(wrapped[3], bot.inject.ELEMENT_KEY)); | |
| assert.strictEqual(bot.inject.cache.getElement( | |
| wrapped[3][bot.inject.ELEMENT_KEY]), unwrapped[3]); | |
| }); | |
| QUnit.test('ShouldBeAbleToWrapNodeListsAsArrays', function(assert) { | |
| var unwrapped = document.getElementsByTagName('body'); | |
| var wrapped = bot.inject.wrapValue(unwrapped); | |
| assert.ok(Array.isArray(wrapped), 'should return an array, but was ' + goog.typeOf(wrapped)); | |
| assert.strictEqual(wrapped.length, unwrapped.length); | |
| assert.ok(goog.object.containsKey(wrapped[0], bot.inject.ELEMENT_KEY)); | |
| assert.strictEqual(bot.inject.cache.getElement( | |
| wrapped[0][bot.inject.ELEMENT_KEY]), document.body); | |
| }); | |
| QUnit.test('ShouldThrowWhenWrappingRecursiveStructure', function(assert) { | |
| var obj1 = {}; | |
| var obj2 = {}; | |
| obj1['obj2'] = obj2; | |
| obj2['obj1'] = obj1; | |
| assert.throws(function() { bot.inject.wrapValue(obj1); }); | |
| }); | |
| QUnit.test('ShouldBeAbleToUnWrapWrappedValues', function(assert) { | |
| var unwrapped = [123, 'abc', null, document.body]; | |
| var wrapped = bot.inject.wrapValue(unwrapped); | |
| var roundTripped = bot.inject.unwrapValue(wrapped); | |
| assert.deepEqual(roundTripped, unwrapped); | |
| }); | |
| QUnit.test('ShouldBeAbleToUnWrapNestedArrays', function(assert) { | |
| var unwrapped = [123, 'abc', null, [document.body, null, | |
| [document.body]]]; | |
| var wrapped = bot.inject.wrapValue(unwrapped); | |
| var roundTripped = bot.inject.unwrapValue(wrapped); | |
| assert.deepEqual(roundTripped, unwrapped); | |
| }); | |
| QUnit.test('ShouldBeAbleToUnWrapNestedObjects', function(assert) { | |
| var unwrapped = {'foo': {'bar': document.body}}; | |
| var wrapped = bot.inject.wrapValue(unwrapped); | |
| var roundTripped = bot.inject.unwrapValue(wrapped); | |
| assert.ok(goog.object.containsKey(roundTripped, 'foo')); | |
| var foo = roundTripped['foo']; | |
| assert.ok(goog.object.containsKey(foo, 'bar')); | |
| assert.strictEqual(foo['bar'], document.body); | |
| }); | |
| QUnit.test('ShouldUnWrapElementsUsingTheGivenDocumentsCache', function(assert) { | |
| var wrapped = bot.inject.wrapValue(frameDoc.body); | |
| assert.ok(wrapped !== null); | |
| assert.ok(wrapped !== undefined); | |
| assert.ok(goog.isObject(wrapped)); | |
| assert.ok(goog.object.containsKey(wrapped, bot.inject.ELEMENT_KEY)); | |
| assert.throws(function() { bot.inject.unwrapValue(wrapped); }); | |
| var unwrapped = bot.inject.unwrapValue(wrapped, frameDoc); | |
| assert.strictEqual(unwrapped, frameDoc.body); | |
| }); | |
| QUnit.test('ShouldBeAbleToUnwrapArgumentsExecuteScriptAndWrapResult', function(assert) { | |
| var id = bot.inject.cache.addElement(document.body); | |
| var args = [{}]; | |
| args[0][bot.inject.ELEMENT_KEY] = id; | |
| var result = bot.inject.executeScript( | |
| function() { return arguments[0]; }, args); | |
| assert.ok(goog.object.containsKey(result, 'status')); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS); | |
| assert.ok(goog.object.containsKey(result, 'value')); | |
| assert.ok(goog.object.containsKey(result['value'], | |
| bot.inject.ELEMENT_KEY)); | |
| assert.strictEqual(bot.inject.cache.getElement( | |
| result['value'][bot.inject.ELEMENT_KEY]), document.body); | |
| }); | |
| QUnit.test('ShouldTrapAndReturnWrappedErrorsFromInjectedScripts', function(assert) { | |
| var result = bot.inject.executeScript( | |
| function() { throw Error('ouch'); }, []); | |
| assert.ok(goog.object.containsKey(result, 'status')); | |
| assert.ok(goog.object.containsKey(result, 'value')); | |
| assert.strictEqual(result['status'], bot.ErrorCode.UNKNOWN_ERROR); | |
| result = result['value']; | |
| assert.ok(goog.object.containsKey(result, 'message')); | |
| assert.strictEqual(result['message'], 'ouch'); | |
| }); | |
| QUnit.test('ShouldResetCacheWhenPageIsRefreshed', function(assert) { | |
| var done = assert.async(); | |
| var id = bot.inject.cache.addElement(frameDoc.body); | |
| assert.strictEqual(bot.inject.cache.getElement(id, frameDoc), frameDoc.body); | |
| goog.events.listenOnce(frame, 'load', function() { | |
| frameDoc = goog.dom.getFrameContentDocument(frame); | |
| assert.throws(function() { bot.inject.cache.getElement(id, frameDoc); }); | |
| done(); | |
| }); | |
| frameWin.location.reload(); | |
| }); | |
| QUnit.test('ShouldStringifyResultsWhenAskedToDoSo', function(assert) { | |
| var result = bot.inject.executeScript(function() { | |
| return arguments[0] + arguments[1]; | |
| }, ['abc', 123], true); | |
| assert.strictEqual(goog.typeOf(result), 'string'); | |
| var json = bot.json.parse(result); | |
| assert.ok('status' in json, 'No status: ' + result); | |
| assert.ok('value' in json, 'No value: ' + result); | |
| assert.strictEqual(json['status'], 0); | |
| assert.strictEqual(json['value'], 'abc123'); | |
| }); | |
| QUnit.test('ShouldStringifyErrorsWhenAskedForStringResults', function(assert) { | |
| var result = bot.inject.executeScript(function() { | |
| throw new bot.Error(bot.ErrorCode.NO_SUCH_ELEMENT, 'ouch'); | |
| }, [], true); | |
| assert.strictEqual(goog.typeOf(result), 'string'); | |
| var json = bot.json.parse(result); | |
| assert.ok('status' in json, 'No status: ' + result); | |
| assert.ok('value' in json, 'No value: ' + result); | |
| assert.strictEqual(json['status'], bot.ErrorCode.NO_SUCH_ELEMENT); | |
| assert.ok('message' in json['value'], 'No message: ' + result); | |
| assert.strictEqual(json['value']['message'], 'ouch'); | |
| }); | |
| QUnit.test('ShouldBeAbleToExecuteAsyncScript', function(assert) { | |
| var done = assert.async(); | |
| bot.inject.executeAsyncScript( | |
| 'window.setTimeout(goog.partial(arguments[0], 1), 10)', | |
| [], 250, function(result) { | |
| assert.ok(goog.object.containsKey(result, 'status')); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS); | |
| assert.ok(goog.object.containsKey(result, 'value')); | |
| assert.strictEqual(result['value'], 1); | |
| done(); | |
| }); | |
| }); | |
| QUnit.test('ShouldBeAbleToExecuteAsyncScriptThatCallsbackSynchronously', function(assert) { | |
| var done = assert.async(); | |
| bot.inject.executeAsyncScript('arguments[0](1)', [], 0, function(result) { | |
| assert.ok(goog.object.containsKey(result, 'status')); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS); | |
| assert.ok(goog.object.containsKey(result, 'value')); | |
| assert.strictEqual(result['value'], 1); | |
| done(); | |
| }); | |
| }); | |
| QUnit.test('ShouldBeAbleToExecuteAsyncFunc', function(assert) { | |
| var done = assert.async(); | |
| bot.inject.executeAsyncScript( | |
| function(callback) { callback(1) }, [], 0, function(result) { | |
| assert.ok(goog.object.containsKey(result, 'status')); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS); | |
| assert.ok(goog.object.containsKey(result, 'value')); | |
| assert.strictEqual(result['value'], 1); | |
| done(); | |
| }); | |
| }); | |
| QUnit.test('ShouldThrowOnExecuteAsyncException', function(assert) { | |
| var done = assert.async(); | |
| bot.inject.executeAsyncScript('nosuchfunc()', [], 0, function(result) { | |
| assert.ok(goog.object.containsKey(result, 'status')); | |
| assert.strictEqual(result['status'], bot.ErrorCode.UNKNOWN_ERROR); | |
| done(); | |
| }); | |
| }); | |
| QUnit.test('ShouldTimeoutInExecuteAsync', function(assert) { | |
| var done = assert.async(); | |
| bot.inject.executeAsyncScript('', [], 0, function(result) { | |
| assert.ok(goog.object.containsKey(result, 'status')); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SCRIPT_TIMEOUT); | |
| done(); | |
| }); | |
| }); | |
| QUnit.test('ShouldBeAbleToStringifyResult', function(assert) { | |
| var done = assert.async(); | |
| bot.inject.executeAsyncScript('', [], 0, function(jsonResult) { | |
| var result = bot.json.parse(jsonResult); | |
| assert.ok(goog.object.containsKey(result, 'status')); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SCRIPT_TIMEOUT); | |
| done(); | |
| }, true); | |
| }); | |
| QUnit.test('ShouldBeAbleToWrapAndUnwrapInExecuteAsyncScript', function(assert) { | |
| var done = assert.async(); | |
| var id = bot.inject.cache.addElement(document.body); | |
| var args = [{}]; | |
| args[0][bot.inject.ELEMENT_KEY] = id; | |
| bot.inject.executeAsyncScript( | |
| 'arguments[1](arguments[0])', args, 0, function(result) { | |
| assert.ok(goog.object.containsKey(result, 'status')); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS); | |
| assert.ok(goog.object.containsKey(result, 'value')); | |
| assert.ok(goog.object.containsKey(result['value'], | |
| bot.inject.ELEMENT_KEY)); | |
| assert.strictEqual(bot.inject.cache.getElement( | |
| result['value'][bot.inject.ELEMENT_KEY]), document.body); | |
| done(); | |
| }); | |
| }); | |
| QUnit.test('ShouldExecuteAsyncScriptsInTheContextOfTheSpecifiedWindow', function(assert) { | |
| if (goog.userAgent.IE || goog.userAgent.product.SAFARI || | |
| (goog.userAgent.product.ANDROID && | |
| !bot.userAgent.isProductVersion(4))) { | |
| assert.ok(true, 'Skipping: known issue on this browser'); | |
| return; | |
| } | |
| var done = assert.async(); | |
| bot.inject.executeAsyncScript(function(callback) { | |
| callback({ | |
| 'this == window': (this == window), | |
| 'this == top': (this == window.top), | |
| 'typeof window.MY_GLOBAL_CONSTANT': (typeof MY_GLOBAL_CONSTANT), | |
| 'typeof window.top.MY_GLOBAL_CONSTANT': | |
| (typeof window.top.MY_GLOBAL_CONSTANT) | |
| }); | |
| }, [], 0, function(result) { | |
| var jsonResult = bot.json.stringify(result); | |
| assert.ok(goog.object.containsKey(result, 'status'), jsonResult); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS, jsonResult); | |
| assert.ok(goog.object.containsKey(result, 'value'), jsonResult); | |
| var value = result['value']; | |
| assert.strictEqual(value['this == window'], true, jsonResult); | |
| assert.strictEqual(value['this == top'], false, jsonResult); | |
| assert.strictEqual(value['typeof window.MY_GLOBAL_CONSTANT'], 'undefined', jsonResult); | |
| assert.strictEqual(value['typeof window.top.MY_GLOBAL_CONSTANT'], 'number', jsonResult); | |
| done(); | |
| }, false, frameWin); | |
| }); | |
| QUnit.test('ShouldExecuteScriptsInTheContextOfTheSpecifiedWindow', function(assert) { | |
| if (goog.userAgent.IE || goog.userAgent.product.SAFARI || | |
| (goog.userAgent.product.ANDROID && | |
| !bot.userAgent.isProductVersion(4))) { | |
| assert.ok(true, 'Skipping: known issue on this browser'); | |
| return; | |
| } | |
| var result = bot.inject.executeScript(function() { | |
| return { | |
| 'this == window': (this == window), | |
| 'this == top': (this == window.top), | |
| 'typeof window.MY_GLOBAL_CONSTANT': (typeof MY_GLOBAL_CONSTANT), | |
| 'typeof window.top.MY_GLOBAL_CONSTANT': | |
| (typeof window.top.MY_GLOBAL_CONSTANT) | |
| }; | |
| }, [], false, frameWin); | |
| var jsonResult = bot.json.stringify(result); | |
| assert.ok(goog.object.containsKey(result, 'status'), jsonResult); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS, jsonResult); | |
| assert.ok(goog.object.containsKey(result, 'value'), jsonResult); | |
| var value = result['value']; | |
| assert.strictEqual(value['this == window'], true, jsonResult); | |
| assert.strictEqual(value['this == top'], false, jsonResult); | |
| assert.strictEqual(value['typeof window.MY_GLOBAL_CONSTANT'], 'undefined', jsonResult); | |
| assert.strictEqual(value['typeof window.top.MY_GLOBAL_CONSTANT'], 'number', jsonResult); | |
| }); | |
| QUnit.test('CorrectlyUnwrapsFunctionArgsForInjectedScripts', function(assert) { | |
| var result = bot.inject.executeScript(function() { | |
| return arguments[0](); | |
| }, [function() {return 1;}]); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS); | |
| assert.strictEqual(result['value'], 1); | |
| }); | |
| QUnit.test('CorrectlyUnwrapsFunctionArgsForInjectedAsyncScripts', function(assert) { | |
| var done = assert.async(); | |
| bot.inject.executeAsyncScript(function() { | |
| var callback = arguments[arguments.length - 1]; | |
| callback(arguments[0]()); | |
| }, [function() {return 1;}], 0, function(result) { | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS); | |
| assert.strictEqual(result['value'], 1); | |
| done(); | |
| }, false); | |
| }); | |
| QUnit.test('CorrectlyUnwrapsArgsForInjectedScripts', function(assert) { | |
| if (goog.userAgent.IE) { | |
| assert.ok(true, 'Skipping: TODO fix for IE'); | |
| return; | |
| } | |
| var wrapped = bot.inject.wrapValue(frameDoc.body); | |
| var result = bot.inject.executeScript(function() { | |
| return [arguments[0], arguments[0].tagName.toUpperCase()]; | |
| }, [wrapped], false, frameWin); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS); | |
| var value = result['value']; | |
| assert.ok(Array.isArray(value)); | |
| assert.strictEqual(value.length, 2); | |
| assert.ok(goog.isObject(value[0])); | |
| assert.ok(goog.object.containsKey(value[0], bot.inject.ELEMENT_KEY)); | |
| assert.strictEqual(value[0][bot.inject.ELEMENT_KEY], | |
| wrapped[bot.inject.ELEMENT_KEY]); | |
| assert.strictEqual(value[1], 'BODY'); | |
| }); | |
| QUnit.test('CorrectlyUnwrapsArgsForInjectedAsyncScripts', function(assert) { | |
| if (goog.userAgent.IE) { | |
| assert.ok(true, 'Skipping: TODO fix for IE'); | |
| return; | |
| } | |
| var wrapped = bot.inject.wrapValue(frameDoc.body); | |
| var done = assert.async(); | |
| bot.inject.executeAsyncScript(function(element, callback) { | |
| callback([element, element.tagName.toUpperCase()]); | |
| }, [wrapped], 0, function(result) { | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS); | |
| var value = result['value']; | |
| assert.ok(Array.isArray(value)); | |
| assert.strictEqual(value.length, 2); | |
| assert.ok(goog.isObject(value[0])); | |
| assert.ok(goog.object.containsKey(value[0], bot.inject.ELEMENT_KEY)); | |
| assert.strictEqual(value[0][bot.inject.ELEMENT_KEY], | |
| wrapped[bot.inject.ELEMENT_KEY]); | |
| assert.strictEqual(value[1], 'BODY'); | |
| done(); | |
| }, false, frameWin); | |
| }); | |
| QUnit.test('ExecuteScriptShouldBeAbleToRecurseOnItself', function(assert) { | |
| if (goog.userAgent.IE) { | |
| assert.ok(true, 'Skipping: TODO fix for IE'); | |
| return; | |
| } | |
| var json = bot.inject.executeScript(bot.inject.executeScript, | |
| ['return 1 +2;'], true); | |
| var result = bot.json.parse(json); | |
| assert.ok(goog.object.containsKey(result, 'status'), json); | |
| assert.strictEqual(result['status'], bot.ErrorCode.SUCCESS, json); | |
| assert.ok(goog.object.containsKey(result, 'value'), json); | |
| var innerResult = result['value']; | |
| assert.ok(goog.isObject(innerResult), json); | |
| assert.ok(goog.object.containsKey(innerResult, 'status'), json); | |
| assert.strictEqual(innerResult['status'], bot.ErrorCode.SUCCESS, json); | |
| assert.ok(goog.object.containsKey(innerResult, 'value'), json); | |
| assert.strictEqual(innerResult['value'], 3, json); | |
| }); | |
| </script> | |
| </body> | |
| </html> |