WebKit Bugzilla
Attachment 360087 Details for
Bug 193476
: Web Inspector: improve invalid Audit/Recording JSON error messages
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-193476-20190124235132.patch (text/plain), 52.07 KB, created by
Devin Rousso
on 2019-01-24 23:51:33 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Devin Rousso
Created:
2019-01-24 23:51:33 PST
Size:
52.07 KB
patch
obsolete
>diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog >index 775a5ee6851cede8a3a51274a98255e56436d3a6..70c7b333f9fe6f58a9950f9ad39d3d21c9d81dc5 100644 >--- a/Source/WebInspectorUI/ChangeLog >+++ b/Source/WebInspectorUI/ChangeLog >@@ -1,3 +1,42 @@ >+2019-01-24 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: improve invalid Audit/Recording JSON error messages >+ https://bugs.webkit.org/show_bug.cgi?id=193476 >+ <rdar://problem/47303659> >+ >+ Reviewed by Joseph Pecoraro. >+ >+ * UserInterface/Models/AuditTestBase.js: >+ (WI.AuditTestBase): >+ * UserInterface/Models/AuditTestCase.js: >+ (WI.AuditTestCase.async fromPayload): >+ * UserInterface/Models/AuditTestGroup.js: >+ (WI.AuditTestGroup.async fromPayload): >+ * UserInterface/Models/AuditTestCaseResult.js: >+ (WI.AuditTestCaseResult.async fromPayload.checkArray): >+ (WI.AuditTestCaseResult.async fromPayload): >+ * UserInterface/Models/AuditTestGroupResult.js: >+ (WI.AuditTestGroupResult.async fromPayload): >+ * UserInterface/Controllers/AuditManager.js: >+ (WI.AuditManager.synthesizeWarning): Added. >+ (WI.AuditManager.synthesizeError): >+ (WI.AuditManager.prototype.async processJSON): >+ >+ * UserInterface/Models/Recording.js: >+ (WI.Recording.fromPayload): >+ (WI.Recording.synthesizeWarning): Added. >+ (WI.Recording.synthesizeError): >+ * UserInterface/Models/RecordingFrame.js: >+ (WI.RecordingFrame.fromPayload): >+ * UserInterface/Models/RecordingAction.js: >+ (WI.RecordingAction.fromPayload): >+ (WI.RecordingAction.prototype.async swizzle): >+ (WI.RecordingAction.prototype.apply): >+ * UserInterface/Controllers/CanvasManager.js: >+ (WI.CanvasManager.prototype.processJSON): >+ >+ * Localizations/en.lproj/localizedStrings.js: >+ > 2019-01-24 Devin Rousso <drousso@apple.com> > > Web Inspector: Audit: add supports key to test/group for compatibility >diff --git a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >index 0fce9f759a0108fbb9a5c764badbe08287519862..14150cd31fe935a3f36afd77159c91919e5daa29 100644 >--- a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >+++ b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >@@ -131,7 +131,8 @@ localizedStrings["Attribute"] = "Attribute"; > localizedStrings["Attribute Modified"] = "Attribute Modified"; > localizedStrings["Attributes"] = "Attributes"; > localizedStrings["Audit"] = "Audit"; >-localizedStrings["Audit error: %s"] = "Audit error: %s"; >+localizedStrings["Audit Error: %s"] = "Audit Error: %s"; >+localizedStrings["Audit Warning: %s"] = "Audit Warning: %s"; > localizedStrings["Audit:"] = "Audit:"; > localizedStrings["Audits"] = "Audits"; > localizedStrings["Author Stylesheet"] = "Author Stylesheet"; >@@ -726,8 +727,9 @@ localizedStrings["Record first %s frame"] = "Record first %s frame"; > localizedStrings["Record first %s frames"] = "Record first %s frames"; > localizedStrings["Recording"] = "Recording"; > localizedStrings["Recording %d"] = "Recording %d"; >+localizedStrings["Recording Error: %s"] = "Recording Error: %s"; > localizedStrings["Recording Timeline Data"] = "Recording Timeline Data"; >-localizedStrings["Recording error: %s"] = "Recording error: %s"; >+localizedStrings["Recording Warning: %s"] = "Recording Warning: %s"; > localizedStrings["Recordings"] = "Recordings"; > localizedStrings["Redirect Response"] = "Redirect Response"; > localizedStrings["Redirects"] = "Redirects"; >@@ -1054,18 +1056,30 @@ localizedStrings["XHRs"] = "XHRs"; > localizedStrings["XPath"] = "XPath"; > localizedStrings["Yes"] = "Yes"; > localizedStrings["Zoom:"] = "Zoom:"; >-localizedStrings["\u0022%s\u0022 is invalid."] = "\u0022%s\u0022 is invalid."; >+localizedStrings["\u0022%s\u0022 has a non-array \u0022%s\u0022 value"] = "\u0022%s\u0022 has a non-array \u0022%s\u0022 value"; >+localizedStrings["\u0022%s\u0022 has a non-number \u0022%s\u0022 value"] = "\u0022%s\u0022 has a non-number \u0022%s\u0022 value"; >+localizedStrings["\u0022%s\u0022 has a non-object \u0022%s\u0022 value"] = "\u0022%s\u0022 has a non-object \u0022%s\u0022 value"; >+localizedStrings["\u0022%s\u0022 has a non-string \u0022%s\u0022 value"] = "\u0022%s\u0022 has a non-string \u0022%s\u0022 value"; >+localizedStrings["\u0022%s\u0022 has an invalid \u0022%s\u0022 value"] = "\u0022%s\u0022 has an invalid \u0022%s\u0022 value"; >+localizedStrings["\u0022%s\u0022 is not valid for %s"] = "\u0022%s\u0022 is not valid for %s"; >+localizedStrings["\u0022%s\u0022 is too new to run in this Web Inspector"] = "\u0022%s\u0022 is too new to run in this Web Inspector"; >+localizedStrings["\u0022%s\u0022 is too new to run on this inspected page"] = "\u0022%s\u0022 is too new to run on this inspected page"; > localizedStrings["\u0022%s\u0022 must be a %s"] = "\u0022%s\u0022 must be a %s"; > localizedStrings["\u0022%s\u0022 must be an %s"] = "\u0022%s\u0022 must be an %s"; >-localizedStrings["\u0022%s\u0022 threw an error."] = "\u0022%s\u0022 threw an error."; >+localizedStrings["\u0022%s\u0022 threw an error"] = "\u0022%s\u0022 threw an error"; > localizedStrings["\u201C%s\u201D Event Fired"] = "\u201C%s\u201D Event Fired"; > localizedStrings["\u201C%s\u201D Profile Recorded"] = "\u201C%s\u201D Profile Recorded"; > localizedStrings["computed"] = "computed"; > localizedStrings["default"] = "default"; > localizedStrings["for changes to take effect"] = "for changes to take effect"; >-localizedStrings["invalid JSON."] = "invalid JSON."; >+localizedStrings["invalid JSON"] = "invalid JSON"; > localizedStrings["key"] = "key"; > localizedStrings["line "] = "line "; >+localizedStrings["non-array %s"] = "non-array %s"; >+localizedStrings["non-integer %s"] = "non-integer %s"; >+localizedStrings["non-number %s"] = "non-number %s"; >+localizedStrings["non-object %s"] = "non-object %s"; >+localizedStrings["non-string %s"] = "non-string %s"; > localizedStrings["originally %s"] = "originally %s"; > localizedStrings["popup"] = "popup"; > localizedStrings["popup, toggle"] = "popup, toggle"; >@@ -1074,5 +1088,6 @@ localizedStrings["spaces"] = "spaces"; > localizedStrings["time before stopping"] = "time before stopping"; > localizedStrings["times before stopping"] = "times before stopping"; > localizedStrings["toggle"] = "toggle"; >-localizedStrings["unsupported version."] = "unsupported version."; >+localizedStrings["unknown %s \u0022%s\u0022"] = "unknown %s \u0022%s\u0022"; >+localizedStrings["unsupported %s"] = "unsupported %s"; > localizedStrings["value"] = "value"; >diff --git a/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js b/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >index 3732c55852e5c13961d9fb063f3e01d3298c7d74..45a789d4be4ab9145277f69fa17df48b3a5a2c7d 100644 >--- a/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >+++ b/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >@@ -40,9 +40,33 @@ WI.AuditManager = class AuditManager extends WI.Object > WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._handleFrameMainResourceDidChange, this); > } > >+ // Static >+ >+ static synthesizeWarning(message) >+ { >+ message = WI.UIString("Audit Warning: %s").format(message); >+ >+ if (window.InspectorTest) { >+ console.warn(message); >+ return; >+ } >+ >+ let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Warning, message); >+ consoleMessage.shouldRevealConsole = true; >+ >+ WI.consoleLogViewController.appendConsoleMessage(consoleMessage); >+ } >+ > static synthesizeError(message) > { >- let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Error, WI.UIString("Audit error: %s").format(message)); >+ message = WI.UIString("Audit Error: %s").format(message); >+ >+ if (window.InspectorTest) { >+ console.error(message); >+ return; >+ } >+ >+ let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Error, message); > consoleMessage.shouldRevealConsole = true; > > WI.consoleLogViewController.appendConsoleMessage(consoleMessage); >@@ -169,15 +193,21 @@ WI.AuditManager = class AuditManager extends WI.Object > return; > } > >- let object = await WI.AuditTestGroup.fromPayload(json) || await WI.AuditTestCase.fromPayload(json); >- if (!object) { >- object = await WI.AuditTestGroupResult.fromPayload(json) || await WI.AuditTestCaseResult.fromPayload(json); >- if (!object) { >- WI.AuditManager.synthesizeError(WI.UIString("invalid JSON.")); >- return; >- } >+ if (typeof json !== "object" || json === null) { >+ WI.AuditManager.synthesizeError(WI.UIString("invalid JSON")); >+ return; > } > >+ if (json.type !== WI.AuditTestCase.TypeIdentifier || json.type !== WI.AuditTestGroup.TypeIdentifier >+ || json.type !== WI.AuditTestCaseResult.TypeIdentifier || json.type !== WI.AuditTestGroupResult.TypeIdentifier) { >+ WI.AuditManager.synthesizeError(WI.UIString("unknown %s \u0022%s\u0022").format(WI.unlocalizedString("type"), json.type)); >+ return; >+ } >+ >+ let object = await WI.AuditTestGroup.fromPayload(json) || await WI.AuditTestCase.fromPayload(json) || await WI.AuditTestGroupResult.fromPayload(json) || await WI.AuditTestCaseResult.fromPayload(json); >+ if (!object) >+ return; >+ > if (object instanceof WI.AuditTestBase) { > this._addTest(object); > WI.objectStores.audits.addObject(object); >diff --git a/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js b/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js >index 317815d309fc06abd0973521679bca73e3633e6b..a9a09df41e2d832fea2abb67794fccd3925b4d61 100644 >--- a/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js >+++ b/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js >@@ -74,12 +74,15 @@ WI.CanvasManager = class CanvasManager extends WI.Object > return; > } > >- let recording = WI.Recording.fromPayload(json); >- if (!recording) { >- WI.Recording.synthesizeError(WI.UIString("unsupported version.")); >+ if (typeof json !== "object" || json === null) { >+ WI.Recording.synthesizeError(WI.UIString("invalid JSON")); > return; > } > >+ let recording = WI.Recording.fromPayload(json); >+ if (!recording) >+ return; >+ > let extensionStart = filename.lastIndexOf("."); > if (extensionStart !== -1) > filename = filename.substring(0, extensionStart); >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js >index 713355018c8f4767e75dcd807c07308d2cfbe886..0a2b5ca447589fd05faa4c8f63739590d739cfe7 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js >@@ -43,10 +43,13 @@ WI.AuditTestBase = class AuditTestBase extends WI.Object > > this._supported = true; > if (typeof this._supports === "number") { >- if (this._supports > WI.AuditTestBase.Version) >+ if (this._supports > WI.AuditTestBase.Version) { >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 is too new to run in this Web Inspector").format(this.name)); > this._supported = false; >- else if (InspectorBackend.domains.Audit && this._supports > InspectorBackend.domains.Audit.VERSION) >+ } else if (InspectorBackend.domains.Audit && this._supports > InspectorBackend.domains.Audit.VERSION) { >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 is too new to run on this inspected page").format(this.name)); > this._supported = false; >+ } > } > > if (!this.supported) >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js >index 6c367650c4d17d298b3b4ca03e60f3b0e1339fba..85f1954cd2a0955ea4b198098386f1e956aac4c1 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js >@@ -41,26 +41,35 @@ WI.AuditTestCase = class AuditTestCase extends WI.AuditTestBase > if (typeof payload !== "object" || payload === null) > return null; > >- let {type, name, test, description, supports, disabled} = payload; >- >- if (type !== WI.AuditTestCase.TypeIdentifier) >+ if (payload.type !== WI.AuditTestCase.TypeIdentifier) > return null; > >- if (typeof name !== "string") >+ if (typeof payload.name !== "string") { >+ WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("name"))); > return null; >+ } > >- if (typeof test !== "string") >+ if (typeof payload.test !== "string") { >+ WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("test"))); > return null; >+ } > > let options = {}; >- if (typeof description === "string") >- options.description = description; >- if (typeof supports === "number") >- options.supports = supports; >- if (typeof disabled === "boolean") >- options.disabled = disabled; > >- return new WI.AuditTestCase(name, test, options); >+ if (typeof payload.description === "string") >+ options.description = payload.description; >+ else if ("description" in payload) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("description"))); >+ >+ if (typeof payload.supports === "number") >+ options.supports = payload.supports; >+ 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.disabled === "boolean") >+ options.disabled = payload.disabled; >+ >+ return new WI.AuditTestCase(payload.name, payload.test, options); > } > > // Public >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestCaseResult.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestCaseResult.js >index 23dd9cd83828826b84aa3b3ef4aea210c5ab74a6..47e7b0b32ff2063879eb88267d9f3adefaf995ef 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/AuditTestCaseResult.js >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestCaseResult.js >@@ -48,52 +48,94 @@ WI.AuditTestCaseResult = class AuditTestCaseResult extends WI.AuditTestResultBas > if (typeof payload !== "object" || payload === null) > return null; > >- let {type, name, description, level, data, metadata} = payload; >- >- if (type !== WI.AuditTestCaseResult.TypeIdentifier) >+ if (payload.type !== WI.AuditTestCaseResult.TypeIdentifier) > return null; > >- if (typeof name !== "string") >+ if (typeof payload.name !== "string") { >+ WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("name"))); > return null; >+ } > >- if (!Object.values(WI.AuditTestCaseResult.Level).includes(level)) >+ if (!Object.values(WI.AuditTestCaseResult.Level).includes(payload.level)) { >+ WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has an invalid \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("level"))); > return null; >+ } > >- if (typeof data !== "object" || data === null) >- data = {}; >- else { >+ if (typeof payload.data !== "object" || payload.data === null) { >+ if ("data" in payload) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("data"))); >+ payload.data = {}; >+ } else { > function checkArray(key) { >- if (!data[key]) >+ if (!payload.data[key]) > return; > >- if (!Array.isArray(data[key])) >- data[key] = []; >+ if (!Array.isArray(payload.data[key])) { >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-array \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("data.%s").format(key))); >+ payload.data[key] = []; >+ } > >- data[key] = data[key].filter((item) => typeof item === "string"); >+ payload.data[key] = payload.data[key].filter((item) => typeof item === "string"); > } > checkArray("domNodes"); > checkArray("domAttributes"); > checkArray("errors"); > } > >- if (typeof metadata !== "object" || metadata === null) >- metadata = {}; >- else { >- metadata.startTimestamp = typeof metadata.startTimestamp === "string" ? new Date(metadata.startTimestamp) : null; >- metadata.asyncTimestamp = typeof metadata.asyncTimestamp === "string" ? new Date(metadata.asyncTimestamp) : null; >- metadata.endTimestamp = typeof metadata.endTimestamp === "string" ? new Date(metadata.endTimestamp) : null; >- metadata.url = typeof metadata.url === "string" ? metadata.url : null; >+ if (typeof payload.metadata !== "object" || payload.metadata === null) { >+ if ("metadata" in payload) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata"))); >+ >+ payload.metadata = {}; >+ } else { >+ if (typeof payload.metadata.startTimestamp === "string") >+ payload.metadata.startTimestamp = new Date(payload.metadata.startTimestamp); >+ else { >+ if ("startTimestamp" in payload.metadata) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata.startTimestamp"))); >+ >+ payload.metadata.startTimestamp = null; >+ } >+ >+ if (typeof payload.metadata.asyncTimestamp === "string") >+ payload.metadata.asyncTimestamp = new Date(payload.metadata.asyncTimestamp); >+ else { >+ if ("asyncTimestamp" in payload.metadata) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata.asyncTimestamp"))); >+ >+ payload.metadata.asyncTimestamp = null; >+ } >+ >+ if (typeof payload.metadata.endTimestamp === "string") >+ payload.metadata.endTimestamp = new Date(payload.metadata.endTimestamp); >+ else { >+ if ("endTimestamp" in payload.metadata) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata.endTimestamp"))); >+ >+ payload.metadata.endTimestamp = null; >+ } >+ >+ if (typeof payload.metadata.url !== "string") { >+ if ("url" in payload.metadata) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata.url"))); >+ >+ payload.metadata.url = null; >+ } > } > > let options = {}; >- if (typeof description === "string") >- options.description = description; >- if (!isEmptyObject(data)) { >+ >+ if (typeof payload.description === "string") >+ options.description = payload.description; >+ else if ("description" in payload) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("description"))); >+ >+ if (!isEmptyObject(payload.data)) { > options.data = {}; >- if (data.domNodes && data.domNodes.length) { >- if (window.DOMAgent && (!metadata.url || metadata.url === WI.networkManager.mainFrame.url)) { >+ if (payload.data.domNodes && payload.data.domNodes.length) { >+ if (window.DOMAgent && (!payload.metadata.url || payload.metadata.url === WI.networkManager.mainFrame.url)) { > let documentNode = await new Promise((resolve) => WI.domManager.requestDocument(resolve)); >- options.resolvedDOMNodes = await Promise.all(data.domNodes.map(async (domNodeString) => { >+ options.resolvedDOMNodes = await Promise.all(payload.data.domNodes.map(async (domNodeString) => { > let nodeId = 0; > try { > nodeId = await WI.domManager.querySelector(documentNode, domNodeString); >@@ -102,26 +144,27 @@ WI.AuditTestCaseResult = class AuditTestCaseResult extends WI.AuditTestResultBas > })); > } > >- options.data.domNodes = data.domNodes; >+ options.data.domNodes = payload.data.domNodes; > } >- if (data.domAttributes && data.domAttributes.length) >- options.data.domAttributes = data.domAttributes; >- if (data.errors && data.errors.length) >- options.data.errors = data.errors; >- } >- if (!isEmptyObject(metadata)) { >- options.metadata = {}; >- if (metadata.startTimestamp && !isNaN(metadata.startTimestamp)) >- options.metadata.startTimestamp = metadata.startTimestamp; >- if (metadata.asyncTimestamp && !isNaN(metadata.asyncTimestamp)) >- options.metadata.asyncTimestamp = metadata.asyncTimestamp; >- if (metadata.endTimestamp && !isNaN(metadata.endTimestamp)) >- options.metadata.endTimestamp = metadata.endTimestamp; >- if (metadata.url) >- options.metadata.url = metadata.url; >+ if (payload.data.domAttributes && payload.data.domAttributes.length) >+ options.data.domAttributes = payload.data.domAttributes; >+ if (payload.data.errors && payload.data.errors.length) >+ options.data.errors = payload.data.errors; > } > >- return new WI.AuditTestCaseResult(name, level, options); >+ if (!isEmptyObject(payload.metadata)) { >+ options.metadata = {}; >+ if (payload.metadata.startTimestamp && !isNaN(payload.metadata.startTimestamp)) >+ options.metadata.startTimestamp = payload.metadata.startTimestamp; >+ if (payload.metadata.asyncTimestamp && !isNaN(payload.metadata.asyncTimestamp)) >+ options.metadata.asyncTimestamp = payload.metadata.asyncTimestamp; >+ if (payload.metadata.endTimestamp && !isNaN(payload.metadata.endTimestamp)) >+ options.metadata.endTimestamp = payload.metadata.endTimestamp; >+ if (payload.metadata.url) >+ options.metadata.url = payload.metadata.url; >+ } >+ >+ return new WI.AuditTestCaseResult(payload.name, payload.level, options); > } > > // Public >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js >index cda7d4e71f45239bd190748881a5c51dc75bf3c5..ef380780d0c8c84d1e5c91b5276198af6e8fabaa 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js >@@ -66,18 +66,20 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > if (typeof payload !== "object" || payload === null) > return null; > >- let {type, name, tests, description, supports, disabled} = payload; >- >- if (type !== WI.AuditTestGroup.TypeIdentifier) >+ if (payload.type !== WI.AuditTestGroup.TypeIdentifier) > return null; > >- if (typeof name !== "string") >+ if (typeof payload.name !== "string") { >+ WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("name"))); > return null; >+ } > >- if (!Array.isArray(tests)) >+ if (!Array.isArray(payload.tests)) { >+ WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-array \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("tests"))); > return null; >+ } > >- tests = await Promise.all(tests.map(async (test) => { >+ let tests = await Promise.all(payload.tests.map(async (test) => { > let testCase = await WI.AuditTestCase.fromPayload(test); > if (testCase) > return testCase; >@@ -93,14 +95,21 @@ WI.AuditTestGroup = class AuditTestGroup extends WI.AuditTestBase > return null; > > let options = {}; >- if (typeof description === "string") >- options.description = description; >- if (typeof supports === "number") >- options.supports = supports; >- if (typeof disabled === "boolean") >- options.disabled = disabled; > >- return new WI.AuditTestGroup(name, tests, options); >+ if (typeof payload.description === "string") >+ options.description = payload.description; >+ else if ("description" in payload) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("description"))); >+ >+ if (typeof payload.supports === "number") >+ options.supports = payload.supports; >+ 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.disabled === "boolean") >+ options.disabled = payload.disabled; >+ >+ return new WI.AuditTestGroup(payload.name, tests, options); > } > > // Public >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestGroupResult.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestGroupResult.js >index d03cd1c6edfa28c12c60b5f84712c487976430c9..397d3f985f1219876fca1bd81b17896aa57f837c 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/AuditTestGroupResult.js >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestGroupResult.js >@@ -41,18 +41,20 @@ WI.AuditTestGroupResult = class AuditTestGroupResult extends WI.AuditTestResultB > if (typeof payload !== "object" || payload === null) > return null; > >- let {type, name, description, results} = payload; >- >- if (type !== WI.AuditTestGroupResult.TypeIdentifier) >+ if (payload.type !== WI.AuditTestGroupResult.TypeIdentifier) > return null; > >- if (typeof name !== "string") >+ if (typeof payload.name !== "string") { >+ WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("name"))); > return null; >+ } > >- if (!Array.isArray(results)) >+ if (!Array.isArray(payload.results)) { >+ WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-array \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("results"))); > return null; >+ } > >- results = await Promise.all(results.map(async (test) => { >+ let results = await Promise.all(payload.results.map(async (test) => { > let testCaseResult = await WI.AuditTestCaseResult.fromPayload(test); > if (testCaseResult) > return testCaseResult; >@@ -68,10 +70,13 @@ WI.AuditTestGroupResult = class AuditTestGroupResult extends WI.AuditTestResultB > return null; > > let options = {}; >- if (typeof description === "string") >- options.description = description; > >- return new WI.AuditTestGroupResult(name, results, options); >+ if (typeof payload.description === "string") >+ options.description = payload.description; >+ else if ("description" in payload) >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("description"))); >+ >+ return new WI.AuditTestGroupResult(payload.name, results, options); > } > > // Public >diff --git a/Source/WebInspectorUI/UserInterface/Models/Recording.js b/Source/WebInspectorUI/UserInterface/Models/Recording.js >index e53f7b0dd195d12e2d7c7bc70b2118294628d350..4354c2b57fd9d0ca89c763d41921c41eba4045ee 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/Recording.js >+++ b/Source/WebInspectorUI/UserInterface/Models/Recording.js >@@ -51,8 +51,20 @@ WI.Recording = class Recording extends WI.Object > if (typeof payload !== "object" || payload === null) > return null; > >- if (isNaN(payload.version) || payload.version <= 0 || payload.version > WI.Recording.Version) >+ if (typeof payload.version !== "number") { >+ WI.Recording.synthesizeError(WI.UIString("non-number %s").format(WI.unlocalizedString("version"))); > return null; >+ } >+ >+ if (payload.version < 1 || payload.version > WI.Recording.Version) { >+ WI.Recording.synthesizeError(WI.UIString("unsupported %s").format(WI.unlocalizedString("version"))); >+ return null; >+ } >+ >+ if (parseInt(payload.version) !== payload.version) { >+ WI.Recording.synthesizeWarning(WI.UIString("non-integer %s").format(WI.unlocalizedString("version"))); >+ payload.version = parseInt(payload.version); >+ } > > let type = null; > switch (payload.type) { >@@ -66,15 +78,29 @@ WI.Recording = class Recording extends WI.Object > type = WI.Recording.Type.CanvasWebGL; > break; > default: >+ WI.Recording.synthesizeWarning(WI.UIString("unknown %s \u0022%s\u0022").format(WI.unlocalizedString("type"), payload.type)); > type = String(payload.type); > break; > } > >- if (typeof payload.initialState !== "object" || payload.initialState === null) >+ if (typeof payload.initialState !== "object" || payload.initialState === null) { >+ if ("initialState" in payload) >+ WI.Recording.synthesizeWarning(WI.UIString("non-object %s").format(WI.unlocalizedString("initialState"))); >+ > payload.initialState = {}; >- if (typeof payload.initialState.attributes !== "object" || payload.initialState.attributes === null) >+ } >+ >+ if (typeof payload.initialState.attributes !== "object" || payload.initialState.attributes === null) { >+ if ("attributes" in payload.initialState) >+ WI.Recording.synthesizeWarning(WI.UIString("non-object %s").format(WI.unlocalizedString("initialState.attributes"))); >+ > payload.initialState.attributes = {}; >+ } >+ > if (!Array.isArray(payload.initialState.states) || payload.initialState.states.some((item) => typeof item !== "object" || item === null)) { >+ if ("states" in payload.initialState) >+ WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("initialState.states"))); >+ > payload.initialState.states = []; > > // COMPATIBILITY (iOS 12.0): Recording.InitialState.states did not exist yet >@@ -84,16 +110,34 @@ WI.Recording = class Recording extends WI.Object > payload.initialState.states.push(state); > } > } >- if (!Array.isArray(payload.initialState.parameters)) >+ >+ if (!Array.isArray(payload.initialState.parameters)) { >+ if ("parameters" in payload.initialState) >+ WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("initialState.attributes"))); >+ > payload.initialState.parameters = []; >- if (typeof payload.initialState.content !== "string") >+ } >+ >+ if (typeof payload.initialState.content !== "string") { >+ if ("content" in payload.initialState) >+ WI.Recording.synthesizeWarning(WI.UIString("non-string %s").format(WI.unlocalizedString("initialState.content"))); >+ > payload.initialState.content = ""; >+ } >+ >+ if (!Array.isArray(payload.frames)) { >+ if ("frames" in payload) >+ WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("frames"))); > >- if (!Array.isArray(payload.frames)) > payload.frames = []; >+ } >+ >+ if (!Array.isArray(payload.data)) { >+ if ("data" in payload) >+ WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("data"))); > >- if (!Array.isArray(payload.data)) > payload.data = []; >+ } > > if (!frames) > frames = payload.frames.map(WI.RecordingFrame.fromPayload) >@@ -150,12 +194,31 @@ WI.Recording = class Recording extends WI.Object > } > } > >+ static synthesizeWarning(message) >+ { >+ message = WI.UIString("Recording Warning: %s").format(message); >+ >+ if (window.InspectorTest) { >+ console.warn(message); >+ return; >+ } >+ >+ let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Warning, message); >+ consoleMessage.shouldRevealConsole = true; >+ >+ WI.consoleLogViewController.appendConsoleMessage(consoleMessage); >+ } >+ > static synthesizeError(message) > { >- const target = WI.mainTarget; >- const source = WI.ConsoleMessage.MessageSource.Other; >- const level = WI.ConsoleMessage.MessageLevel.Error; >- let consoleMessage = new WI.ConsoleMessage(target, source, level, WI.UIString("Recording error: %s").format(message)); >+ message = WI.UIString("Recording Error: %s").format(message); >+ >+ if (window.InspectorTest) { >+ console.error(message); >+ return; >+ } >+ >+ let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Error, message); > consoleMessage.shouldRevealConsole = true; > > WI.consoleLogViewController.appendConsoleMessage(consoleMessage); >diff --git a/Source/WebInspectorUI/UserInterface/Models/RecordingAction.js b/Source/WebInspectorUI/UserInterface/Models/RecordingAction.js >index 534255bcf9c5129205c3512b9125e74c837f21f2..c5717c732465d8385cc973269a6a6663319f60f6 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/RecordingAction.js >+++ b/Source/WebInspectorUI/UserInterface/Models/RecordingAction.js >@@ -63,23 +63,43 @@ WI.RecordingAction = class RecordingAction extends WI.Object > if (!Array.isArray(payload)) > payload = []; > >- if (isNaN(payload[0])) >+ if (typeof payload[0] !== "number") { >+ if (payload.length > 0) >+ WI.Recording.synthesizeWarning(WI.UIString("non-number %s").format(WI.unlocalizedString("name"))); >+ > payload[0] = -1; >- >- if (!Array.isArray(payload[1])) >- payload[1] = []; >- >- if (!Array.isArray(payload[2])) >- payload[2] = []; >- >- if (isNaN(payload[3]) || (!payload[3] && payload[3] !== 0)) { >- // COMPATIBILITY (iOS 12.1): "trace" was sent as an array of call frames instead of a single call stack >- if (!Array.isArray(payload[3])) >- payload[3] = []; > } > >- if (payload.length >= 5 && isNaN(payload[4])) >+ if (!Array.isArray(payload[1])) { >+ if (payload.length > 1) >+ WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("parameters"))); >+ >+ payload[1] = []; >+ } >+ >+ if (!Array.isArray(payload[2])) { >+ if (payload.length > 2) >+ WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("swizzleTypes"))); >+ >+ payload[2] = []; >+ } >+ >+ if (typeof payload[3] !== "number" || isNaN(payload[3]) || (!payload[3] && payload[3] !== 0)) { >+ // COMPATIBILITY (iOS 12.1): "trace" was sent as an array of call frames instead of a single call stack >+ if (!Array.isArray(payload[3])) { >+ if (payload.length > 3) >+ WI.Recording.synthesizeWarning(WI.UIString("non-number %s").format(WI.unlocalizedString("trace"))); >+ >+ payload[3] = []; >+ } >+ } >+ >+ if (typeof payload[4] !== "number" || isNaN(payload[4])) { >+ if (payload.length > 4) >+ WI.Recording.synthesizeWarning(WI.UIString("non-number %s").format(WI.unlocalizedString("snapshot"))); >+ > payload[4] = -1; >+ } > > return new WI.RecordingAction(...payload); > } >@@ -310,7 +330,7 @@ WI.RecordingAction = class RecordingAction extends WI.Object > if (prototype && !(name in prototype)) { > this.markInvalid(); > >- WI.Recording.synthesizeError(WI.UIString("\u0022%s\u0022 is invalid.").format(name)); >+ WI.Recording.synthesizeWarning(WI.UIString("\u0022%s\u0022 is not valid for %s").format(name, prototype.constructor.name)); > } > } > } >@@ -360,7 +380,7 @@ WI.RecordingAction = class RecordingAction extends WI.Object > } catch { > this.markInvalid(); > >- WI.Recording.synthesizeError(WI.UIString("\u0022%s\u0022 threw an error.").format(this._name)); >+ WI.Recording.synthesizeWarning(WI.UIString("\u0022%s\u0022 threw an error").format(this._name)); > } > } > >diff --git a/Source/WebInspectorUI/UserInterface/Models/RecordingFrame.js b/Source/WebInspectorUI/UserInterface/Models/RecordingFrame.js >index 6a2a620dcf92fa7a1dcefa56b175477b4bcee523..b6ab23accbbc95d8e49ea84ee3031f6fe88a110a 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/RecordingFrame.js >+++ b/Source/WebInspectorUI/UserInterface/Models/RecordingFrame.js >@@ -39,8 +39,12 @@ WI.RecordingFrame = class RecordingFrame > if (typeof payload !== "object" || payload === null) > payload = {}; > >- if (!Array.isArray(payload.actions)) >+ if (!Array.isArray(payload.actions)) { >+ if ("actions" in payload) >+ WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("actions"))); >+ > payload.actions = []; >+ } > > let actions = payload.actions.map(WI.RecordingAction.fromPayload); > return new WI.RecordingFrame(actions, { >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 5ad33a9389860434465cbf35127af8dbca2bea50..57513074b471e15523d7b1e1494a08e551f1c06d 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,19 @@ >+2019-01-24 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: improve invalid Audit/Recording JSON error messages >+ https://bugs.webkit.org/show_bug.cgi?id=193476 >+ <rdar://problem/47303659> >+ >+ Reviewed by Joseph Pecoraro. >+ >+ * inspector/model/auditTestCase.html: >+ * inspector/model/auditTestCase-expected.txt: >+ * inspector/model/auditTestCaseResult-expected.txt: >+ * inspector/model/auditTestGroup.html: >+ * inspector/model/auditTestGroup-expected.txt: >+ * inspector/model/auditTestGroupResult-expected.txt: >+ * inspector/model/recording-expected.txt: >+ > 2019-01-24 Devin Rousso <drousso@apple.com> > > Web Inspector: Audit: add supports key to test/group for compatibility >diff --git a/LayoutTests/inspector/model/auditTestCase-expected.txt b/LayoutTests/inspector/model/auditTestCase-expected.txt >index 782db83a86fa19ae9b5b839934c88119408e3085..2d20ab4625e15849ef14e1a401b043b069dbd4fd 100644 >--- a/LayoutTests/inspector/model/auditTestCase-expected.txt >+++ b/LayoutTests/inspector/model/auditTestCase-expected.txt >@@ -22,9 +22,12 @@ null > } > > -- Running test case: AuditTestCase.fromPayload.validWithInvalidOptionals >+WARN: Audit Warning: "validWithInvalidOptionals test name" has a non-string "description" 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, > "test": "validWithInvalidOptionals test function" > } > >@@ -33,6 +36,7 @@ null > "type": "test-case", > "name": "validWithValidOptionals test name", > "description": "validWithValidOptionals test description", >+ "supports": 0, > "test": "validWithValidOptionals test function" > } > >diff --git a/LayoutTests/inspector/model/auditTestCase.html b/LayoutTests/inspector/model/auditTestCase.html >index 829d01d786a90d6c9a1cc8edfa28ea7853709102..ebcf879e9a010530b215f54ee0914d9f95defd0c 100644 >--- a/LayoutTests/inspector/model/auditTestCase.html >+++ b/LayoutTests/inspector/model/auditTestCase.html >@@ -52,6 +52,7 @@ function test() > type: WI.AuditTestCase.TypeIdentifier, > name: "validWithInvalidOptionals test name", > description: null, >+ supports: WI.AuditTestBase.Version + 1, > test: "validWithInvalidOptionals test function", > }, > }, >@@ -61,6 +62,7 @@ function test() > type: WI.AuditTestCase.TypeIdentifier, > name: "validWithValidOptionals test name", > description: "validWithValidOptionals test description", >+ supports: WI.AuditTestBase.Version - 1, > test: "validWithValidOptionals test function", > }, > }, >diff --git a/LayoutTests/inspector/model/auditTestCaseResult-expected.txt b/LayoutTests/inspector/model/auditTestCaseResult-expected.txt >index 814ad23f65b0c449df5a5f1979296c8ffaaaa07b..4e33ae2346ec41ad2fa7999929f5a8dc26f53349 100644 >--- a/LayoutTests/inspector/model/auditTestCaseResult-expected.txt >+++ b/LayoutTests/inspector/model/auditTestCaseResult-expected.txt >@@ -22,6 +22,9 @@ null > } > > -- Running test case: AuditTestCaseResult.fromPayload.validWithInvalidOptionals >+WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-object "data" value >+WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-object "metadata" value >+WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-string "description" value > { > "type": "test-case-result", > "name": "validWithInvalidOptionals test result name", >@@ -29,6 +32,10 @@ null > } > > -- Running test case: AuditTestCaseResult.fromPayload.validWithInvalidSubOptionals >+WARN: Audit Warning: "validWithInvalidSubOptionals test result name" has a non-object "metadata.startTimestamp" value >+WARN: Audit Warning: "validWithInvalidSubOptionals test result name" has a non-object "metadata.asyncTimestamp" value >+WARN: Audit Warning: "validWithInvalidSubOptionals test result name" has a non-object "metadata.endTimestamp" value >+WARN: Audit Warning: "validWithInvalidSubOptionals test result name" has a non-object "metadata.url" value > { > "type": "test-case-result", > "name": "validWithInvalidSubOptionals test result name", >diff --git a/LayoutTests/inspector/model/auditTestGroup-expected.txt b/LayoutTests/inspector/model/auditTestGroup-expected.txt >index 99b3935d6c119faabfebcd926e42e0ebb5c5dc17..5e2629e29c041e08e72a2ddc823d20d49cf3f14f 100644 >--- a/LayoutTests/inspector/model/auditTestGroup-expected.txt >+++ b/LayoutTests/inspector/model/auditTestGroup-expected.txt >@@ -34,13 +34,19 @@ null > } > > -- Running test case: AuditTestGroup.fromPayload.validWithInvalidOptionals >+WARN: Audit Warning: "validWithInvalidOptionals test name" has a non-string "description" 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" is too new to run in this Web Inspector > { > "type": "test-group", > "name": "validWithInvalidOptionals group name", >+ "supports": 2, > "tests": [ > { > "type": "test-case", > "name": "validWithInvalidOptionals test name", >+ "supports": 3, > "test": "validWithInvalidOptionals test function" > } > ] >@@ -51,11 +57,13 @@ null > "type": "test-group", > "name": "validWithValidOptionals group name", > "description": "validWithValidOptionals group description", >+ "supports": 0, > "tests": [ > { > "type": "test-case", > "name": "validWithValidOptionals test name", > "description": "validWithValidOptionals test description", >+ "supports": -1, > "test": "validWithValidOptionals test function" > } > ] >@@ -66,16 +74,19 @@ null > "type": "test-group", > "name": "validNested group name", > "description": "validNested group description", >+ "supports": 0, > "tests": [ > { > "type": "test-group", > "name": "validNested nested group name", > "description": "validNested nested group description", >+ "supports": -1, > "tests": [ > { > "type": "test-case", > "name": "validNested nested test name", > "description": "validNested nested test description", >+ "supports": -2, > "test": "validNested nested test function" > } > ] >@@ -84,6 +95,7 @@ null > "type": "test-case", > "name": "validNested test name", > "description": "validNested test description", >+ "supports": -3, > "test": "validNested test function" > } > ] >diff --git a/LayoutTests/inspector/model/auditTestGroup.html b/LayoutTests/inspector/model/auditTestGroup.html >index bdfa2900d0b040dbfa4a3674178d4c85eeb12589..dc2193f4f50ad732cd85d8cfd746c52ec0df9f0e 100644 >--- a/LayoutTests/inspector/model/auditTestGroup.html >+++ b/LayoutTests/inspector/model/auditTestGroup.html >@@ -76,11 +76,13 @@ function test() > type: WI.AuditTestGroup.TypeIdentifier, > name: "validWithInvalidOptionals group name", > description: null, >+ supports: WI.AuditTestBase.Version + 1, > tests: [ > { > type: WI.AuditTestCase.TypeIdentifier, > name: "validWithInvalidOptionals test name", > description: null, >+ supports: WI.AuditTestBase.Version + 2, > test: "validWithInvalidOptionals test function", > }, > ], >@@ -92,11 +94,13 @@ function test() > type: WI.AuditTestGroup.TypeIdentifier, > name: "validWithValidOptionals group name", > description: "validWithValidOptionals group description", >+ supports: WI.AuditTestBase.Version - 1, > tests: [ > { > type: WI.AuditTestCase.TypeIdentifier, > name: "validWithValidOptionals test name", > description: "validWithValidOptionals test description", >+ supports: WI.AuditTestBase.Version - 2, > test: "validWithValidOptionals test function", > }, > ], >@@ -108,16 +112,19 @@ function test() > type: WI.AuditTestGroup.TypeIdentifier, > name: "validNested group name", > description: "validNested group description", >+ supports: WI.AuditTestBase.Version - 1, > tests: [ > { > type: WI.AuditTestGroup.TypeIdentifier, > name: "validNested nested group name", > description: "validNested nested group description", >+ supports: WI.AuditTestBase.Version - 2, > tests: [ > { > type: WI.AuditTestCase.TypeIdentifier, > name: "validNested nested test name", > description: "validNested nested test description", >+ supports: WI.AuditTestBase.Version - 3, > test: "validNested nested test function", > }, > ], >@@ -126,6 +133,7 @@ function test() > type: WI.AuditTestCase.TypeIdentifier, > name: "validNested test name", > description: "validNested test description", >+ supports: WI.AuditTestBase.Version - 4, > test: "validNested test function", > }, > ], >diff --git a/LayoutTests/inspector/model/auditTestGroupResult-expected.txt b/LayoutTests/inspector/model/auditTestGroupResult-expected.txt >index 1b732d909f821ddd6e9cee22bd5e1b1ba318be9a..0aa2df7a08ab0aba0d9bf5b6e23552f753e6bfab 100644 >--- a/LayoutTests/inspector/model/auditTestGroupResult-expected.txt >+++ b/LayoutTests/inspector/model/auditTestGroupResult-expected.txt >@@ -34,6 +34,10 @@ null > } > > -- Running test case: AuditTestGroupResult.fromPayload.validWithInvalidOptionals >+WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-object "data" value >+WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-object "metadata" value >+WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-string "description" value >+WARN: Audit Warning: "validWithInvalidOptionals group result name" has a non-string "description" value > { > "type": "test-group-result", > "name": "validWithInvalidOptionals group result name", >diff --git a/LayoutTests/inspector/model/recording-expected.txt b/LayoutTests/inspector/model/recording-expected.txt >index 8ccec82e5e9bacb20d358f1b8fbfc8314befa6fa..f437abd8ce961b9e602bf8853fedc40b188bb670 100644 >--- a/LayoutTests/inspector/model/recording-expected.txt >+++ b/LayoutTests/inspector/model/recording-expected.txt >@@ -9,12 +9,19 @@ null > null > > -- Running test case: Recording.fromPayload.emptyObject >+ERROR: Recording Error: non-number version > null > > -- Running test case: Recording.fromPayload.invalidTopLevelMembers >+ERROR: Recording Error: non-number version > null > > -- Running test case: Recording.fromPayload.invalidSubMembers >+WARN: Recording Warning: unknown type "test" >+WARN: Recording Warning: non-object initialState.attributes >+WARN: Recording Warning: non-array initialState.states >+WARN: Recording Warning: non-array initialState.attributes >+WARN: Recording Warning: non-string initialState.content > { > "version": 1, > "type": "test", >@@ -30,6 +37,8 @@ null > } > > -- Running test case: Recording.fromPayload.invalidFrame >+WARN: Recording Warning: unknown type "test" >+WARN: Recording Warning: non-array actions > { > "version": 1, > "type": "test", >@@ -58,6 +67,7 @@ null > } > > -- Running test case: Recording.fromPayload.invalidAction >+WARN: Recording Warning: unknown type "test" > { > "version": 1, > "type": "test", >@@ -95,6 +105,11 @@ null > } > > -- Running test case: Recording.fromPayload.invalidActionMembers >+WARN: Recording Warning: unknown type "test" >+WARN: Recording Warning: non-number name >+WARN: Recording Warning: non-array parameters >+WARN: Recording Warning: non-array swizzleTypes >+WARN: Recording Warning: non-number trace > { > "version": 1, > "type": "test", >@@ -116,7 +131,7 @@ null > { > "actions": [ > [ >- null, >+ -1, > [], > [], > [] >@@ -132,6 +147,7 @@ null > } > > -- Running test case: Recording.fromPayload.valid >+WARN: Recording Warning: unknown type "test" > { > "version": 1, > "type": "test",
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 193476
:
359962
|
359963
|
360086
| 360087