Diff
Modified: trunk/LayoutTests/ChangeLog (242807 => 242808)
--- trunk/LayoutTests/ChangeLog 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/LayoutTests/ChangeLog 2019-03-12 18:56:28 UTC (rev 242808)
@@ -1,3 +1,18 @@
+2019-03-12 Devin Rousso <[email protected]>
+
+ Web Inspector: Audit: there should be a centralized place for reusable code
+ https://bugs.webkit.org/show_bug.cgi?id=195265
+ <rdar://problem/47040673>
+
+ Reviewed by Joseph Pecoraro.
+
+ * inspector/audit/manager-start-setup.html: Added.
+ * inspector/audit/manager-start-setup-expected.txt: Added.
+ * inspector/model/auditTestCase.html:
+ * inspector/model/auditTestCase-expected.txt:
+ * inspector/model/auditTestGroup.html:
+ * inspector/model/auditTestGroup-expected.txt:
+
2019-03-12 Daniel Bates <[email protected]>
[iOS] Add test to ensure that a web page can prevent the default for Command + A
Added: trunk/LayoutTests/inspector/audit/manager-start-setup-expected.txt (0 => 242808)
--- trunk/LayoutTests/inspector/audit/manager-start-setup-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/audit/manager-start-setup-expected.txt 2019-03-12 18:56:28 UTC (rev 242808)
@@ -0,0 +1,20 @@
+Tests for the AuditManager.prototype.start functionality.
+
+
+== Running test suite: AuditManager.prototype.start
+-- Running test case: AuditManager.prototype.start.SyncSetup
+PASS: The setup function should have set __test to 42.
+
+-- Running test case: AuditManager.prototype.start.AsyncSetup
+PASS: The setup function should have set __test to 42.
+
+-- Running test case: AuditManager.prototype.start.SubLevelSetup
+PASS: The setup function should have set __test to undefined.
+
+-- Running test case: AuditManager.prototype.start.OverriddenSetup
+PASS: The setup function should have set __test to B.
+
+-- Running test case: AuditManager.prototype.start.MultipleTopLevel
+PASS: The setup function should have set __test to A.
+PASS: The setup function should have set __test to B.
+
Added: trunk/LayoutTests/inspector/audit/manager-start-setup.html (0 => 242808)
--- trunk/LayoutTests/inspector/audit/manager-start-setup.html (rev 0)
+++ trunk/LayoutTests/inspector/audit/manager-start-setup.html 2019-03-12 18:56:28 UTC (rev 242808)
@@ -0,0 +1,145 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+
+function test()
+{
+ const auditTestString = (function() {
+ return {
+ level: "pass",
+ __test: WebInspectorAudit.__test,
+ };
+ }).toString();
+
+ async function wrapTest(audit, expected, {getResultCallback} = {}) {
+ WI.auditManager._addTest(audit);
+
+ let [result] = await WI.auditManager.start([audit]);
+ if (getResultCallback)
+ result = getResultCallback(result);
+
+ InspectorTest.assert(result.didPass, "The test should pass.");
+ InspectorTest.assert(!result.data.errors, "There should be no errors.");
+ InspectorTest.expectEqual(result.data.__test.value, expected, `The setup function should have set __test to ${expected}.`);
+
+ WI.auditManager.removeTest(audit);
+ }
+
+ let suite = InspectorTest.createAsyncSuite("AuditManager.prototype.start");
+
+ suite.addTestCase({
+ name: "AuditManager.prototype.start.SyncSetup",
+ description: "Check that the setup of an audit is actually run.",
+ async test() {
+ const setup = (function() {
+ WebInspectorAudit.__test = 42;
+ }).toString();
+
+ let audit = new WI.AuditTestCase("AuditManager.prototype.start.SyncSetup", auditTestString, {setup});
+
+ await wrapTest(audit, 42);
+ },
+ });
+
+ suite.addTestCase({
+ name: "AuditManager.prototype.start.AsyncSetup",
+ description: "Check that the setup of an audit can be asynchronous.",
+ async test() {
+ const setup = (async function() {
+ await new Promise((resolve, reject) => {
+ setTimeout(resolve, 10);
+ });
+
+ WebInspectorAudit.__test = 42;
+ }).toString();
+
+ let audit = new WI.AuditTestCase("AuditManager.prototype.start.AsyncSetup", auditTestString, {setup});
+
+ await wrapTest(audit, 42);
+ },
+ });
+
+ suite.addTestCase({
+ name: "AuditManager.prototype.start.SubLevelSetup",
+ description: "Check that the setup of a non-top-level audit is not run.",
+ async test() {
+ const setup = (function() {
+ WebInspectorAudit.__test = 42;
+ }).toString();
+
+ let audit = new WI.AuditTestGroup("AuditManager.prototype.start.SubLevelSetup.Group", [
+ new WI.AuditTestCase("AuditManager.prototype.start.SubLevelSetup.Test", auditTestString, {setup}),
+ ]);
+
+ await wrapTest(audit, undefined, {
+ getResultCallback(result) {
+ return result.results[0];
+ },
+ });
+ },
+ });
+
+ suite.addTestCase({
+ name: "AuditManager.prototype.start.OverriddenSetup",
+ description: "Check that only the setup of top-level audits is run.",
+ async test() {
+ const setupA = (function() {
+ if (!WebInspectorAudit.__test)
+ WebInspectorAudit.__test = "";
+ WebInspectorAudit.__test += "A";
+ }).toString();
+
+ const setupB = (function() {
+ if (!WebInspectorAudit.__test)
+ WebInspectorAudit.__test = "";
+ WebInspectorAudit.__test += "B";
+ }).toString();
+
+ let audit = new WI.AuditTestGroup("AuditManager.prototype.start.OverriddenLevelSetup.Group", [
+ new WI.AuditTestCase("AuditManager.prototype.start.OverriddenLevelSetup.Test", auditTestString, {setup: setupA}),
+ ], {setup: setupB});
+
+ await wrapTest(audit, "B", {
+ getResultCallback(result) {
+ return result.results[0];
+ },
+ });
+ },
+ });
+
+ suite.addTestCase({
+ name: "AuditManager.prototype.start.MultipleTopLevel",
+ description: "Test that a new WebInspectorAudit object is created for each setup call.",
+ async test() {
+ const setupA = (function() {
+ if (!WebInspectorAudit.__test)
+ WebInspectorAudit.__test = "";
+ WebInspectorAudit.__test += "A";
+ }).toString();
+
+ let auditA = new WI.AuditTestCase("AuditManager.prototype.start.MultipleTopLevel.A", auditTestString, {setup: setupA});
+
+ await wrapTest(auditA, "A");
+
+ const setupB = (function() {
+ if (!WebInspectorAudit.__test)
+ WebInspectorAudit.__test = "";
+ WebInspectorAudit.__test += "B";
+ }).toString();
+
+ let auditB = new WI.AuditTestCase("AuditManager.prototype.start.MultipleTopLevel.B", auditTestString, {setup: setupB});
+
+ await wrapTest(auditB, "B");
+ },
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>Tests for the AuditManager.prototype.start functionality.</p>
+</body>
+</html>
Modified: trunk/LayoutTests/inspector/model/auditTestCase-expected.txt (242807 => 242808)
--- trunk/LayoutTests/inspector/model/auditTestCase-expected.txt 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/LayoutTests/inspector/model/auditTestCase-expected.txt 2019-03-12 18:56:28 UTC (rev 242808)
@@ -23,11 +23,12 @@
-- Running test case: AuditTestCase.fromPayload.validWithInvalidOptionals
WARN: Audit Warning: "validWithInvalidOptionals test name" has a non-string "description" value
+WARN: Audit Warning: "validWithInvalidOptionals test name" has a non-string "setup" value
WARN: Audit Warning: "validWithInvalidOptionals test name" is too new to run in this Web Inspector
{
"type": "test-case",
"name": "validWithInvalidOptionals test name",
- "supports": 2,
+ "supports": 3,
"test": "validWithInvalidOptionals test function"
}
@@ -36,7 +37,8 @@
"type": "test-case",
"name": "validWithValidOptionals test name",
"description": "validWithValidOptionals test description",
- "supports": 0,
+ "supports": 1,
+ "setup": "validWithValidOptionals test setup",
"test": "validWithValidOptionals test function"
}
Modified: trunk/LayoutTests/inspector/model/auditTestCase.html (242807 => 242808)
--- trunk/LayoutTests/inspector/model/auditTestCase.html 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/LayoutTests/inspector/model/auditTestCase.html 2019-03-12 18:56:28 UTC (rev 242808)
@@ -53,6 +53,7 @@
name: "validWithInvalidOptionals test name",
description: null,
supports: WI.AuditTestBase.Version + 1,
+ setup: null,
test: "validWithInvalidOptionals test function",
},
},
@@ -63,6 +64,7 @@
name: "validWithValidOptionals test name",
description: "validWithValidOptionals test description",
supports: WI.AuditTestBase.Version - 1,
+ setup: "validWithValidOptionals test setup",
test: "validWithValidOptionals test function",
},
},
Modified: trunk/LayoutTests/inspector/model/auditTestGroup-expected.txt (242807 => 242808)
--- trunk/LayoutTests/inspector/model/auditTestGroup-expected.txt 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/LayoutTests/inspector/model/auditTestGroup-expected.txt 2019-03-12 18:56:28 UTC (rev 242808)
@@ -35,18 +35,20 @@
-- Running test case: AuditTestGroup.fromPayload.validWithInvalidOptionals
WARN: Audit Warning: "validWithInvalidOptionals test name" has a non-string "description" value
+WARN: Audit Warning: "validWithInvalidOptionals test name" has a non-string "setup" value
WARN: Audit Warning: "validWithInvalidOptionals test name" is too new to run in this Web Inspector
WARN: Audit Warning: "validWithInvalidOptionals group name" has a non-string "description" value
+WARN: Audit Warning: "validWithInvalidOptionals group name" has a non-string "setup" value
WARN: Audit Warning: "validWithInvalidOptionals group name" is too new to run in this Web Inspector
{
"type": "test-group",
"name": "validWithInvalidOptionals group name",
- "supports": 2,
+ "supports": 3,
"tests": [
{
"type": "test-case",
"name": "validWithInvalidOptionals test name",
- "supports": 3,
+ "supports": 4,
"test": "validWithInvalidOptionals test function"
}
]
@@ -57,13 +59,15 @@
"type": "test-group",
"name": "validWithValidOptionals group name",
"description": "validWithValidOptionals group description",
- "supports": 0,
+ "supports": 1,
+ "setup": "validWithValidOptionals group setup",
"tests": [
{
"type": "test-case",
"name": "validWithValidOptionals test name",
"description": "validWithValidOptionals test description",
- "supports": -1,
+ "supports": 0,
+ "setup": "validWithValidOptionals test setup",
"test": "validWithValidOptionals test function"
}
]
@@ -74,19 +78,22 @@
"type": "test-group",
"name": "validNested group name",
"description": "validNested group description",
- "supports": 0,
+ "supports": 1,
+ "setup": "validNested group setup",
"tests": [
{
"type": "test-group",
"name": "validNested nested group name",
"description": "validNested nested group description",
- "supports": -1,
+ "supports": 0,
+ "setup": "validNested nested group setup",
"tests": [
{
"type": "test-case",
"name": "validNested nested test name",
"description": "validNested nested test description",
- "supports": -2,
+ "supports": -1,
+ "setup": "validNested nested test setup",
"test": "validNested nested test function"
}
]
@@ -95,7 +102,8 @@
"type": "test-case",
"name": "validNested test name",
"description": "validNested test description",
- "supports": -3,
+ "supports": -2,
+ "setup": "validNested test setup",
"test": "validNested test function"
}
]
Modified: trunk/LayoutTests/inspector/model/auditTestGroup.html (242807 => 242808)
--- trunk/LayoutTests/inspector/model/auditTestGroup.html 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/LayoutTests/inspector/model/auditTestGroup.html 2019-03-12 18:56:28 UTC (rev 242808)
@@ -77,6 +77,7 @@
name: "validWithInvalidOptionals group name",
description: null,
supports: WI.AuditTestBase.Version + 1,
+ setup: null,
tests: [
{
type: WI.AuditTestCase.TypeIdentifier,
@@ -83,6 +84,7 @@
name: "validWithInvalidOptionals test name",
description: null,
supports: WI.AuditTestBase.Version + 2,
+ setup: null,
test: "validWithInvalidOptionals test function",
},
],
@@ -95,6 +97,7 @@
name: "validWithValidOptionals group name",
description: "validWithValidOptionals group description",
supports: WI.AuditTestBase.Version - 1,
+ setup: "validWithValidOptionals group setup",
tests: [
{
type: WI.AuditTestCase.TypeIdentifier,
@@ -101,6 +104,7 @@
name: "validWithValidOptionals test name",
description: "validWithValidOptionals test description",
supports: WI.AuditTestBase.Version - 2,
+ setup: "validWithValidOptionals test setup",
test: "validWithValidOptionals test function",
},
],
@@ -113,6 +117,7 @@
name: "validNested group name",
description: "validNested group description",
supports: WI.AuditTestBase.Version - 1,
+ setup: "validNested group setup",
tests: [
{
type: WI.AuditTestGroup.TypeIdentifier,
@@ -119,6 +124,7 @@
name: "validNested nested group name",
description: "validNested nested group description",
supports: WI.AuditTestBase.Version - 2,
+ setup: "validNested nested group setup",
tests: [
{
type: WI.AuditTestCase.TypeIdentifier,
@@ -125,6 +131,7 @@
name: "validNested nested test name",
description: "validNested nested test description",
supports: WI.AuditTestBase.Version - 3,
+ setup: "validNested nested test setup",
test: "validNested nested test function",
},
],
@@ -134,6 +141,7 @@
name: "validNested test name",
description: "validNested test description",
supports: WI.AuditTestBase.Version - 4,
+ setup: "validNested test setup",
test: "validNested test function",
},
],
Modified: trunk/Source/_javascript_Core/ChangeLog (242807 => 242808)
--- trunk/Source/_javascript_Core/ChangeLog 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-03-12 18:56:28 UTC (rev 242808)
@@ -1,3 +1,14 @@
+2019-03-12 Devin Rousso <[email protected]>
+
+ Web Inspector: Audit: there should be a centralized place for reusable code
+ https://bugs.webkit.org/show_bug.cgi?id=195265
+ <rdar://problem/47040673>
+
+ Reviewed by Joseph Pecoraro.
+
+ * inspector/protocol/Audit.json:
+ Increment version.
+
2019-03-12 Robin Morisset <[email protected]>
blocksInPreOrder and blocksInPostOrder should reserve the right capacity for their result vector
Modified: trunk/Source/_javascript_Core/inspector/protocol/Audit.json (242807 => 242808)
--- trunk/Source/_javascript_Core/inspector/protocol/Audit.json 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/Source/_javascript_Core/inspector/protocol/Audit.json 2019-03-12 18:56:28 UTC (rev 242808)
@@ -1,7 +1,7 @@
{
"domain": "Audit",
"description": "",
- "version": 1,
+ "version": 2,
"commands": [
{
"name": "setup",
Modified: trunk/Source/WebInspectorUI/ChangeLog (242807 => 242808)
--- trunk/Source/WebInspectorUI/ChangeLog 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/Source/WebInspectorUI/ChangeLog 2019-03-12 18:56:28 UTC (rev 242808)
@@ -1,3 +1,29 @@
+2019-03-12 Devin Rousso <[email protected]>
+
+ Web Inspector: Audit: there should be a centralized place for reusable code
+ https://bugs.webkit.org/show_bug.cgi?id=195265
+ <rdar://problem/47040673>
+
+ Reviewed by Joseph Pecoraro.
+
+ * UserInterface/Controllers/AuditManager.js:
+ (WI.AuditManager.prototype.async start):
+ (WI.AuditManager.prototype._topLevelTestForTest): Added.
+ (WI.AuditManager.prototype._topLevelTestForTest.walk): Added.
+
+ * UserInterface/Models/AuditTestBase.js:
+ (WI.AuditTestBase):
+ (WI.AuditTestBase.prototype.async setup): Added.
+ (WI.AuditTestBase.toJSON):
+
+ * UserInterface/Models/AuditTestCase.js:
+ (WI.AuditTestCase.async.fromPayload):
+ (WI.AuditTestCase.prototype.async run.async parseResponse):
+ Allow additional data to be passed back to the result's `data` for testing.
+
+ * UserInterface/Models/AuditTestGroup.js:
+ (WI.AuditTestGroup.async.fromPayload):
+
2019-03-12 Joseph Pecoraro <[email protected]>
Web Inspector: Timelines - Improve handling of past recordings (readonly)
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js (242807 => 242808)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js 2019-03-12 18:56:28 UTC (rev 242808)
@@ -127,7 +127,7 @@
{
console.assert(this._runningState === WI.AuditManager.RunningState.Inactive);
if (this._runningState !== WI.AuditManager.RunningState.Inactive)
- return;
+ return null;
if (tests && tests.length)
tests = tests.filter((test) => typeof test === "object" && test instanceof WI.AuditTestBase);
@@ -136,7 +136,7 @@
console.assert(tests.length);
if (!tests.length)
- return;
+ return null;
let mainResource = WI.networkManager.mainFrame.mainResource;
@@ -154,6 +154,11 @@
if (InspectorBackend.domains.Audit)
await AuditAgent.setup();
+ let topLevelTest = this._topLevelTestForTest(test);
+ console.assert(topLevelTest || window.InspectorTest, "No matching top-level test found", test);
+ if (topLevelTest)
+ await topLevelTest.setup();
+
await test.start();
if (InspectorBackend.domains.Audit)
@@ -172,6 +177,8 @@
for (let test of this._tests)
test.clearResult();
}
+
+ return this._results.lastValue === result ? result : null;
}
stop()
@@ -287,6 +294,28 @@
});
}
+ _topLevelTestForTest(test)
+ {
+ function walk(group) {
+ if (group === test)
+ return true;
+ if (group instanceof WI.AuditTestGroup) {
+ for (let subtest of group.tests) {
+ if (walk(subtest))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ for (let topLevelTest of this._tests) {
+ if (walk(topLevelTest))
+ return topLevelTest;
+ }
+
+ return null;
+ }
+
_handleFrameMainResourceDidChange(event)
{
if (!event.target.isMainFrame())
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js (242807 => 242808)
--- trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js 2019-03-12 18:56:28 UTC (rev 242808)
@@ -25,11 +25,12 @@
WI.AuditTestBase = class AuditTestBase extends WI.Object
{
- constructor(name, {description, supports, disabled} = {})
+ constructor(name, {description, supports, setup, disabled} = {})
{
console.assert(typeof name === "string");
console.assert(!description || typeof description === "string");
console.assert(supports === undefined || typeof supports === "number");
+ console.assert(!setup || typeof setup === "string");
console.assert(disabled === undefined || typeof disabled === "boolean");
super();
@@ -40,6 +41,7 @@
this._name = name;
this._description = description || null;
this._supports = supports;
+ this._setup = setup || null;
this._supported = true;
if (typeof this._supports === "number") {
@@ -101,6 +103,45 @@
this.dispatchEventToListeners(WI.AuditTestBase.Event.DisabledChanged);
}
+ async setup()
+ {
+ if (!this._setup)
+ return;
+
+ let agentCommandFunction = null;
+ let agentCommandArguments = {};
+ if (InspectorBackend.domains.Audit) {
+ agentCommandFunction = AuditAgent.run;
+ agentCommandArguments.test = this._setup;
+ } else {
+ agentCommandFunction = RuntimeAgent.evaluate;
+ agentCommandArguments._expression_ = `(function() { "use strict"; return eval(\`(${this._setup.replace(/`/g, "\\`")})\`)(); })()`;
+ agentCommandArguments.objectGroup = "audit";
+ agentCommandArguments.doNotPauseOnExceptionsAndMuteConsole = true;
+ }
+
+ try {
+ let response = await agentCommandFunction.invoke(agentCommandArguments);
+
+ if (response.result.type === "object" && response.result.className === "Promise") {
+ if (WI.RuntimeManager.supportsAwaitPromise())
+ response = await RuntimeAgent.awaitPromise(response.result.objectId);
+ else {
+ response = null;
+ WI.AuditManager.synthesizeError(WI.UIString("Async audits are not supported."));
+ }
+ }
+
+ if (response) {
+ let remoteObject = WI.RemoteObject.fromPayload(response.result, WI.mainTarget);
+ if (response.wasThrown || (remoteObject.type === "object" && remoteObject.subtype === "error"))
+ WI.AuditManager.synthesizeError(remoteObject.description);
+ }
+ } catch (error) {
+ WI.AuditManager.synthesizeError(error.message);
+ }
+ }
+
async start()
{
// Called from WI.AuditManager.
@@ -171,6 +212,8 @@
json.description = this._description;
if (typeof this._supports === "number")
json.supports = this._supports;
+ if (this._setup)
+ json.setup = this._setup;
if (key === WI.ObjectStore.toJSONSymbol)
json.disabled = this.disabled;
return json;
@@ -185,7 +228,7 @@
};
// Keep this in sync with Inspector::Protocol::Audit::VERSION.
-WI.AuditTestBase.Version = 1;
+WI.AuditTestBase.Version = 2;
WI.AuditTestBase.Event = {
Completed: "audit-test-base-completed",
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js (242807 => 242808)
--- trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js 2019-03-12 18:56:28 UTC (rev 242808)
@@ -66,6 +66,11 @@
else if ("supports" in payload)
WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-number \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("supports")));
+ if (typeof payload.setup === "string")
+ options.setup = payload.setup;
+ else if ("setup" in payload)
+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("setup")));
+
if (typeof payload.disabled === "boolean")
options.disabled = payload.disabled;
@@ -235,6 +240,9 @@
addError(item.value.description);
});
+
+ if (window.InspectorTest && properties.__test)
+ data.__test = properties.__test.value;
} else
addError(WI.UIString("Return value is not an object, string, or boolean"));
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js (242807 => 242808)
--- trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js 2019-03-12 18:51:13 UTC (rev 242807)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js 2019-03-12 18:56:28 UTC (rev 242808)
@@ -106,6 +106,11 @@
else if ("supports" in payload)
WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-number \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("supports")));
+ if (typeof payload.setup === "string")
+ options.setup = payload.setup;
+ else if ("setup" in payload)
+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("setup")));
+
if (typeof payload.disabled === "boolean")
options.disabled = payload.disabled;