michael@0: /* michael@0: * Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ michael@0: */ michael@0: michael@0: // Check that variables view works as expected in the web console. michael@0: michael@0: const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-eval-in-stackframe.html"; michael@0: michael@0: let gWebConsole, gJSTerm, gVariablesView; michael@0: michael@0: function test() michael@0: { michael@0: addTab(TEST_URI); michael@0: browser.addEventListener("load", function onLoad() { michael@0: browser.removeEventListener("load", onLoad, true); michael@0: openConsole(null, consoleOpened); michael@0: }, true); michael@0: } michael@0: michael@0: function consoleOpened(hud) michael@0: { michael@0: gWebConsole = hud; michael@0: gJSTerm = hud.jsterm; michael@0: gJSTerm.execute("fooObj", onExecuteFooObj); michael@0: } michael@0: michael@0: function onExecuteFooObj(msg) michael@0: { michael@0: ok(msg, "output message found"); michael@0: ok(msg.textContent.contains('{ testProp: "testValue" }'), "message text check"); michael@0: michael@0: let anchor = msg.querySelector("a"); michael@0: ok(anchor, "object link found"); michael@0: michael@0: gJSTerm.once("variablesview-fetched", onFooObjFetch); michael@0: michael@0: executeSoon(() => michael@0: EventUtils.synthesizeMouse(anchor, 2, 2, {}, gWebConsole.iframeWindow) michael@0: ); michael@0: } michael@0: michael@0: function onFooObjFetch(aEvent, aVar) michael@0: { michael@0: gVariablesView = aVar._variablesView; michael@0: ok(gVariablesView, "variables view object"); michael@0: michael@0: findVariableViewProperties(aVar, [ michael@0: { name: "testProp", value: "testValue" }, michael@0: ], { webconsole: gWebConsole }).then(onTestPropFound); michael@0: } michael@0: michael@0: function onTestPropFound(aResults) michael@0: { michael@0: let prop = aResults[0].matchedProp; michael@0: ok(prop, "matched the |testProp| property in the variables view"); michael@0: michael@0: is(content.wrappedJSObject.fooObj.testProp, aResults[0].value, michael@0: "|fooObj.testProp| value is correct"); michael@0: michael@0: // Check that property value updates work and that jsterm functions can be michael@0: // used. michael@0: updateVariablesViewProperty({ michael@0: property: prop, michael@0: field: "value", michael@0: string: "document.title + window.location + $('p')", michael@0: webconsole: gWebConsole, michael@0: callback: onFooObjFetchAfterUpdate, michael@0: }); michael@0: } michael@0: michael@0: function onFooObjFetchAfterUpdate(aEvent, aVar) michael@0: { michael@0: info("onFooObjFetchAfterUpdate"); michael@0: let para = content.wrappedJSObject.document.querySelector("p"); michael@0: let expectedValue = content.document.title + content.location + para; michael@0: michael@0: findVariableViewProperties(aVar, [ michael@0: { name: "testProp", value: expectedValue }, michael@0: ], { webconsole: gWebConsole }).then(onUpdatedTestPropFound); michael@0: } michael@0: michael@0: function onUpdatedTestPropFound(aResults) michael@0: { michael@0: let prop = aResults[0].matchedProp; michael@0: ok(prop, "matched the updated |testProp| property value"); michael@0: michael@0: is(content.wrappedJSObject.fooObj.testProp, aResults[0].value, michael@0: "|fooObj.testProp| value has been updated"); michael@0: michael@0: // Check that property name updates work. michael@0: updateVariablesViewProperty({ michael@0: property: prop, michael@0: field: "name", michael@0: string: "testUpdatedProp", michael@0: webconsole: gWebConsole, michael@0: callback: onFooObjFetchAfterPropRename, michael@0: }); michael@0: } michael@0: michael@0: function onFooObjFetchAfterPropRename(aEvent, aVar) michael@0: { michael@0: info("onFooObjFetchAfterPropRename"); michael@0: michael@0: let para = content.wrappedJSObject.document.querySelector("p"); michael@0: let expectedValue = content.document.title + content.location + para; michael@0: michael@0: // Check that the new value is in the variables view. michael@0: findVariableViewProperties(aVar, [ michael@0: { name: "testUpdatedProp", value: expectedValue }, michael@0: ], { webconsole: gWebConsole }).then(onRenamedTestPropFound); michael@0: } michael@0: michael@0: function onRenamedTestPropFound(aResults) michael@0: { michael@0: let prop = aResults[0].matchedProp; michael@0: ok(prop, "matched the renamed |testProp| property"); michael@0: michael@0: ok(!content.wrappedJSObject.fooObj.testProp, michael@0: "|fooObj.testProp| has been deleted"); michael@0: is(content.wrappedJSObject.fooObj.testUpdatedProp, aResults[0].value, michael@0: "|fooObj.testUpdatedProp| is correct"); michael@0: michael@0: // Check that property value updates that cause exceptions are reported in michael@0: // the web console output. michael@0: updateVariablesViewProperty({ michael@0: property: prop, michael@0: field: "value", michael@0: string: "foobarzFailure()", michael@0: webconsole: gWebConsole, michael@0: callback: onPropUpdateError, michael@0: }); michael@0: } michael@0: michael@0: function onPropUpdateError(aEvent, aVar) michael@0: { michael@0: info("onPropUpdateError"); michael@0: michael@0: let para = content.wrappedJSObject.document.querySelector("p"); michael@0: let expectedValue = content.document.title + content.location + para; michael@0: michael@0: // Make sure the property did not change. michael@0: findVariableViewProperties(aVar, [ michael@0: { name: "testUpdatedProp", value: expectedValue }, michael@0: ], { webconsole: gWebConsole }).then(onRenamedTestPropFoundAgain); michael@0: } michael@0: michael@0: function onRenamedTestPropFoundAgain(aResults) michael@0: { michael@0: let prop = aResults[0].matchedProp; michael@0: ok(prop, "matched the renamed |testProp| property again"); michael@0: michael@0: let outputNode = gWebConsole.outputNode; michael@0: michael@0: waitForMessages({ michael@0: webconsole: gWebConsole, michael@0: messages: [{ michael@0: name: "exception in property update reported in the web console output", michael@0: text: "foobarzFailure", michael@0: category: CATEGORY_OUTPUT, michael@0: severity: SEVERITY_ERROR, michael@0: }], michael@0: }).then(testPropDelete.bind(null, prop)); michael@0: } michael@0: michael@0: function testPropDelete(aProp) michael@0: { michael@0: gVariablesView.window.focus(); michael@0: aProp.focus(); michael@0: michael@0: executeSoon(() => { michael@0: EventUtils.synthesizeKey("VK_DELETE", {}, gVariablesView.window); michael@0: gWebConsole = gJSTerm = gVariablesView = null; michael@0: }); michael@0: michael@0: waitForSuccess({ michael@0: name: "property deleted", michael@0: timeout: 60000, michael@0: validatorFn: () => !("testUpdatedProp" in content.wrappedJSObject.fooObj), michael@0: successFn: finishTest, michael@0: failureFn: finishTest, michael@0: }); michael@0: }