WebKit Bugzilla
Attachment 359962 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
193476.diff (text/plain), 46.04 KB, created by
Devin Rousso
on 2019-01-23 15:44:53 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Devin Rousso
Created:
2019-01-23 15:44:53 PST
Size:
46.04 KB
patch
obsolete
>diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 0d64e29ecca..35826562dd2 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,19 @@ >+2019-01-23 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 NOBODY (OOPS!). >+ >+ * 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-23 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 782db83a86f..1ba4c5db056 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" expects a newer frontend > { > "type": "test-case", > "name": "validWithInvalidOptionals test name", >+ "supports": null, > "test": "validWithInvalidOptionals test function" > } > >@@ -33,6 +36,7 @@ null > "type": "test-case", > "name": "validWithValidOptionals test name", > "description": "validWithValidOptionals test description", >+ "supports": 1, > "test": "validWithValidOptionals test function" > } > >diff --git a/LayoutTests/inspector/model/auditTestCase.html b/LayoutTests/inspector/model/auditTestCase.html >index 829d01d786a..2175434dc9e 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: Infinity, > 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, > test: "validWithValidOptionals test function", > }, > }, >diff --git a/LayoutTests/inspector/model/auditTestCaseResult-expected.txt b/LayoutTests/inspector/model/auditTestCaseResult-expected.txt >index 814ad23f65b..5122bd757ed 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 99b3935d6c1..282aa50a933 100644 >--- a/LayoutTests/inspector/model/auditTestGroup-expected.txt >+++ b/LayoutTests/inspector/model/auditTestGroup-expected.txt >@@ -34,6 +34,9 @@ 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" expects a newer frontend >+WARN: Audit warning: "validWithInvalidOptionals group name" has a non-string "description" value > { > "type": "test-group", > "name": "validWithInvalidOptionals group name", >@@ -41,6 +44,7 @@ null > { > "type": "test-case", > "name": "validWithInvalidOptionals test name", >+ "supports": null, > "test": "validWithInvalidOptionals test function" > } > ] >@@ -56,6 +60,7 @@ null > "type": "test-case", > "name": "validWithValidOptionals test name", > "description": "validWithValidOptionals test description", >+ "supports": 1, > "test": "validWithValidOptionals test function" > } > ] >diff --git a/LayoutTests/inspector/model/auditTestGroup.html b/LayoutTests/inspector/model/auditTestGroup.html >index bdfa2900d0b..b373b1a46cc 100644 >--- a/LayoutTests/inspector/model/auditTestGroup.html >+++ b/LayoutTests/inspector/model/auditTestGroup.html >@@ -81,6 +81,7 @@ function test() > type: WI.AuditTestCase.TypeIdentifier, > name: "validWithInvalidOptionals test name", > description: null, >+ supports: Infinity, > test: "validWithInvalidOptionals test function", > }, > ], >@@ -97,6 +98,7 @@ function test() > type: WI.AuditTestCase.TypeIdentifier, > name: "validWithValidOptionals test name", > description: "validWithValidOptionals test description", >+ supports: WI.AuditTestBase.Version, > test: "validWithValidOptionals test function", > }, > ], >diff --git a/LayoutTests/inspector/model/auditTestGroupResult-expected.txt b/LayoutTests/inspector/model/auditTestGroupResult-expected.txt >index 1b732d909f8..6867825dd09 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 8ccec82e5e9..fde64cad66f 100644 >--- a/LayoutTests/inspector/model/recording-expected.txt >+++ b/LayoutTests/inspector/model/recording-expected.txt >@@ -12,9 +12,14 @@ null > null > > -- Running test case: Recording.fromPayload.invalidTopLevelMembers >+ERROR: Recording error: non-number version > null > > -- Running test case: Recording.fromPayload.invalidSubMembers >+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 +35,7 @@ null > } > > -- Running test case: Recording.fromPayload.invalidFrame >+WARN: Recording warning: non-array actions > { > "version": 1, > "type": "test", >@@ -95,6 +101,10 @@ null > } > > -- Running test case: Recording.fromPayload.invalidActionMembers >+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 +126,7 @@ null > { > "actions": [ > [ >- null, >+ -1, > [], > [], > [] >diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog >index de793157e6e..e7c349c9abe 100644 >--- a/Source/WebInspectorUI/ChangeLog >+++ b/Source/WebInspectorUI/ChangeLog >@@ -1,3 +1,42 @@ >+2019-01-23 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 NOBODY (OOPS!). >+ >+ * 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-23 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 93f02687e3f..5899574827e 100644 >--- a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >+++ b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js >@@ -132,6 +132,7 @@ localizedStrings["Attribute Modified"] = "Attribute Modified"; > localizedStrings["Attributes"] = "Attributes"; > localizedStrings["Audit"] = "Audit"; > 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"; >@@ -724,6 +725,7 @@ localizedStrings["Recording"] = "Recording"; > localizedStrings["Recording %d"] = "Recording %d"; > 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"; >@@ -1050,18 +1052,29 @@ 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 expects a newer backend"] = "\u0022%s\u0022 expects a newer backend"; >+localizedStrings["\u0022%s\u0022 expects a newer frontend"] = "\u0022%s\u0022 expects a newer frontend"; >+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 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["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"; >@@ -1070,5 +1083,5 @@ 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["unsupported %s"] = "unsupported %s"; > localizedStrings["value"] = "value"; >diff --git a/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js b/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >index 3732c55852e..77daf2884ee 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); >@@ -172,10 +196,8 @@ WI.AuditManager = class AuditManager extends WI.Object > 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.")); >+ if (!object) > return; >- } > } > > if (object instanceof WI.AuditTestBase) { >diff --git a/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js b/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js >index 317815d309f..a038620d1a9 100644 >--- a/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js >+++ b/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js >@@ -75,10 +75,8 @@ WI.CanvasManager = class CanvasManager extends WI.Object > } > > let recording = WI.Recording.fromPayload(json); >- if (!recording) { >- WI.Recording.synthesizeError(WI.UIString("unsupported version.")); >+ if (!recording) > return; >- } > > let extensionStart = filename.lastIndexOf("."); > if (extensionStart !== -1) >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js >index dec3c327394..2574db66992 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js >@@ -29,7 +29,7 @@ WI.AuditTestBase = class AuditTestBase extends WI.Object > { > console.assert(typeof name === "string"); > console.assert(!description || typeof description === "string"); >- console.assert(supports === undefined || typeof supports === "number"); >+ console.assert(supports === undefined || (typeof supports === "number" && !isNaN(supports))); > console.assert(disabled === undefined || typeof disabled === "boolean"); > > super(); >@@ -42,11 +42,14 @@ WI.AuditTestBase = class AuditTestBase extends WI.Object > this._supports = supports; > > this._supported = true; >- if (typeof this._supports === "number") { >- if (this._supports > WI.AuditTestBase.Version) >+ if (typeof this._supports === "number" && !isNaN(this._supports)) { >+ if (this._supports > WI.AuditTestBase.Version) { >+ WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 expects a newer frontend").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 expects a newer backend").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 6c367650c4d..338fe7dd80b 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" && !isNaN(payload.supports)) >+ 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 23dd9cd8382..47e7b0b32ff 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 cda7d4e71f4..4a6cd9cecd7 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" && !isNaN(payload.supports)) >+ 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 d03cd1c6edf..397d3f985f1 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 e53f7b0dd19..fe8fd45cc71 100644 >--- a/Source/WebInspectorUI/UserInterface/Models/Recording.js >+++ b/Source/WebInspectorUI/UserInterface/Models/Recording.js >@@ -51,8 +51,26 @@ 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" || isNaN(payload.version)) { >+ if ("version" in payload) >+ WI.Recording.synthesizeError(WI.UIString("non-number %s").format(WI.unlocalizedString("version"))); >+ > return null; >+ } >+ >+ if (payload.version < 1 || payload.version > WI.Recording.Version) { >+ if ("version" in payload) >+ WI.Recording.synthesizeError(WI.UIString("unsupported %s").format(WI.unlocalizedString("version"))); >+ >+ return null; >+ } >+ >+ if (parseInt(payload.version) !== payload.version) { >+ if ("version" in payload) >+ WI.Recording.synthesizeWarning(WI.UIString("non-integer %s").format(WI.unlocalizedString("version"))); >+ >+ payload.version = parseInt(payload.version); >+ } > > let type = null; > switch (payload.type) { >@@ -70,11 +88,24 @@ WI.Recording = class Recording extends WI.Object > 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 +115,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 +199,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 534255bcf9c..564a6fe109b 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" || isNaN(payload[0])) { >+ 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 6a2a620dcf9..b6ab23accbb 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, {
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