Changeset 240471 in webkit


Ignore:
Timestamp:
Jan 25, 2019 1:27:50 AM (5 years ago)
Author:
Devin Rousso
Message:

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.

Source/WebInspectorUI:

  • 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:

LayoutTests:

  • 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:
Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r240469 r240471  
     12019-01-25  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: improve invalid Audit/Recording JSON error messages
     4        https://bugs.webkit.org/show_bug.cgi?id=193476
     5        <rdar://problem/47303659>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * inspector/model/auditTestCase.html:
     10        * inspector/model/auditTestCase-expected.txt:
     11        * inspector/model/auditTestCaseResult-expected.txt:
     12        * inspector/model/auditTestGroup.html:
     13        * inspector/model/auditTestGroup-expected.txt:
     14        * inspector/model/auditTestGroupResult-expected.txt:
     15        * inspector/model/recording-expected.txt:
     16
    1172019-01-24  Devin Rousso  <drousso@apple.com>
    218
  • trunk/LayoutTests/inspector/model/auditTestCase-expected.txt

    r237613 r240471  
    2323
    2424-- Running test case: AuditTestCase.fromPayload.validWithInvalidOptionals
     25WARN: Audit Warning: "validWithInvalidOptionals test name" has a non-string "description" value
     26WARN: Audit Warning: "validWithInvalidOptionals test name" is too new to run in this Web Inspector
    2527{
    2628  "type": "test-case",
    2729  "name": "validWithInvalidOptionals test name",
     30  "supports": 2,
    2831  "test": "validWithInvalidOptionals test function"
    2932}
     
    3437  "name": "validWithValidOptionals test name",
    3538  "description": "validWithValidOptionals test description",
     39  "supports": 0,
    3640  "test": "validWithValidOptionals test function"
    3741}
  • trunk/LayoutTests/inspector/model/auditTestCase.html

    r237656 r240471  
    5353                name: "validWithInvalidOptionals test name",
    5454                description: null,
     55                supports: WI.AuditTestBase.Version + 1,
    5556                test: "validWithInvalidOptionals test function",
    5657            },
     
    6263                name: "validWithValidOptionals test name",
    6364                description: "validWithValidOptionals test description",
     65                supports: WI.AuditTestBase.Version - 1,
    6466                test: "validWithValidOptionals test function",
    6567            },
  • trunk/LayoutTests/inspector/model/auditTestCaseResult-expected.txt

    r238850 r240471  
    2323
    2424-- Running test case: AuditTestCaseResult.fromPayload.validWithInvalidOptionals
     25WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-object "data" value
     26WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-object "metadata" value
     27WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-string "description" value
    2528{
    2629  "type": "test-case-result",
     
    3033
    3134-- Running test case: AuditTestCaseResult.fromPayload.validWithInvalidSubOptionals
     35WARN: Audit Warning: "validWithInvalidSubOptionals test result name" has a non-object "metadata.startTimestamp" value
     36WARN: Audit Warning: "validWithInvalidSubOptionals test result name" has a non-object "metadata.asyncTimestamp" value
     37WARN: Audit Warning: "validWithInvalidSubOptionals test result name" has a non-object "metadata.endTimestamp" value
     38WARN: Audit Warning: "validWithInvalidSubOptionals test result name" has a non-object "metadata.url" value
    3239{
    3340  "type": "test-case-result",
  • trunk/LayoutTests/inspector/model/auditTestGroup-expected.txt

    r237613 r240471  
    3535
    3636-- Running test case: AuditTestGroup.fromPayload.validWithInvalidOptionals
     37WARN: Audit Warning: "validWithInvalidOptionals test name" has a non-string "description" value
     38WARN: Audit Warning: "validWithInvalidOptionals test name" is too new to run in this Web Inspector
     39WARN: Audit Warning: "validWithInvalidOptionals group name" has a non-string "description" value
     40WARN: Audit Warning: "validWithInvalidOptionals group name" is too new to run in this Web Inspector
    3741{
    3842  "type": "test-group",
    3943  "name": "validWithInvalidOptionals group name",
     44  "supports": 2,
    4045  "tests": [
    4146    {
    4247      "type": "test-case",
    4348      "name": "validWithInvalidOptionals test name",
     49      "supports": 3,
    4450      "test": "validWithInvalidOptionals test function"
    4551    }
     
    5258  "name": "validWithValidOptionals group name",
    5359  "description": "validWithValidOptionals group description",
     60  "supports": 0,
    5461  "tests": [
    5562    {
     
    5764      "name": "validWithValidOptionals test name",
    5865      "description": "validWithValidOptionals test description",
     66      "supports": -1,
    5967      "test": "validWithValidOptionals test function"
    6068    }
     
    6775  "name": "validNested group name",
    6876  "description": "validNested group description",
     77  "supports": 0,
    6978  "tests": [
    7079    {
     
    7281      "name": "validNested nested group name",
    7382      "description": "validNested nested group description",
     83      "supports": -1,
    7484      "tests": [
    7585        {
     
    7787          "name": "validNested nested test name",
    7888          "description": "validNested nested test description",
     89          "supports": -2,
    7990          "test": "validNested nested test function"
    8091        }
     
    8596      "name": "validNested test name",
    8697      "description": "validNested test description",
     98      "supports": -3,
    8799      "test": "validNested test function"
    88100    }
  • trunk/LayoutTests/inspector/model/auditTestGroup.html

    r237656 r240471  
    7777                name: "validWithInvalidOptionals group name",
    7878                description: null,
     79                supports: WI.AuditTestBase.Version + 1,
    7980                tests: [
    8081                    {
     
    8283                        name: "validWithInvalidOptionals test name",
    8384                        description: null,
     85                        supports: WI.AuditTestBase.Version + 2,
    8486                        test: "validWithInvalidOptionals test function",
    8587                    },
     
    9395                name: "validWithValidOptionals group name",
    9496                description: "validWithValidOptionals group description",
     97                supports: WI.AuditTestBase.Version - 1,
    9598                tests: [
    9699                    {
     
    98101                        name: "validWithValidOptionals test name",
    99102                        description: "validWithValidOptionals test description",
     103                        supports: WI.AuditTestBase.Version - 2,
    100104                        test: "validWithValidOptionals test function",
    101105                    },
     
    109113                name: "validNested group name",
    110114                description: "validNested group description",
     115                supports: WI.AuditTestBase.Version - 1,
    111116                tests: [
    112117                    {
     
    114119                        name: "validNested nested group name",
    115120                        description: "validNested nested group description",
     121                        supports: WI.AuditTestBase.Version - 2,
    116122                        tests: [
    117123                            {
     
    119125                                name: "validNested nested test name",
    120126                                description: "validNested nested test description",
     127                                supports: WI.AuditTestBase.Version - 3,
    121128                                test: "validNested nested test function",
    122129                            },
     
    127134                        name: "validNested test name",
    128135                        description: "validNested test description",
     136                        supports: WI.AuditTestBase.Version - 4,
    129137                        test: "validNested test function",
    130138                    },
  • trunk/LayoutTests/inspector/model/auditTestGroupResult-expected.txt

    r238850 r240471  
    3535
    3636-- Running test case: AuditTestGroupResult.fromPayload.validWithInvalidOptionals
     37WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-object "data" value
     38WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-object "metadata" value
     39WARN: Audit Warning: "validWithInvalidOptionals test result name" has a non-string "description" value
     40WARN: Audit Warning: "validWithInvalidOptionals group result name" has a non-string "description" value
    3741{
    3842  "type": "test-group-result",
  • trunk/LayoutTests/inspector/model/recording-expected.txt

    r238199 r240471  
    1010
    1111-- Running test case: Recording.fromPayload.emptyObject
     12ERROR: Recording Error: non-number version
    1213null
    1314
    1415-- Running test case: Recording.fromPayload.invalidTopLevelMembers
     16ERROR: Recording Error: non-number version
    1517null
    1618
    1719-- Running test case: Recording.fromPayload.invalidSubMembers
     20WARN: Recording Warning: unknown type "test"
     21WARN: Recording Warning: non-object initialState.attributes
     22WARN: Recording Warning: non-array initialState.states
     23WARN: Recording Warning: non-array initialState.attributes
     24WARN: Recording Warning: non-string initialState.content
    1825{
    1926  "version": 1,
     
    3138
    3239-- Running test case: Recording.fromPayload.invalidFrame
     40WARN: Recording Warning: unknown type "test"
     41WARN: Recording Warning: non-array actions
    3342{
    3443  "version": 1,
     
    5968
    6069-- Running test case: Recording.fromPayload.invalidAction
     70WARN: Recording Warning: unknown type "test"
    6171{
    6272  "version": 1,
     
    96106
    97107-- Running test case: Recording.fromPayload.invalidActionMembers
     108WARN: Recording Warning: unknown type "test"
     109WARN: Recording Warning: non-number name
     110WARN: Recording Warning: non-array parameters
     111WARN: Recording Warning: non-array swizzleTypes
     112WARN: Recording Warning: non-number trace
    98113{
    99114  "version": 1,
     
    117132      "actions": [
    118133        [
    119           null,
     134          -1,
    120135          [],
    121136          [],
     
    133148
    134149-- Running test case: Recording.fromPayload.valid
     150WARN: Recording Warning: unknown type "test"
    135151{
    136152  "version": 1,
  • trunk/Source/WebInspectorUI/ChangeLog

    r240469 r240471  
     12019-01-25  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: improve invalid Audit/Recording JSON error messages
     4        https://bugs.webkit.org/show_bug.cgi?id=193476
     5        <rdar://problem/47303659>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * UserInterface/Models/AuditTestBase.js:
     10        (WI.AuditTestBase):
     11        * UserInterface/Models/AuditTestCase.js:
     12        (WI.AuditTestCase.async fromPayload):
     13        * UserInterface/Models/AuditTestGroup.js:
     14        (WI.AuditTestGroup.async fromPayload):
     15        * UserInterface/Models/AuditTestCaseResult.js:
     16        (WI.AuditTestCaseResult.async fromPayload.checkArray):
     17        (WI.AuditTestCaseResult.async fromPayload):
     18        * UserInterface/Models/AuditTestGroupResult.js:
     19        (WI.AuditTestGroupResult.async fromPayload):
     20        * UserInterface/Controllers/AuditManager.js:
     21        (WI.AuditManager.synthesizeWarning): Added.
     22        (WI.AuditManager.synthesizeError):
     23        (WI.AuditManager.prototype.async processJSON):
     24
     25        * UserInterface/Models/Recording.js:
     26        (WI.Recording.fromPayload):
     27        (WI.Recording.synthesizeWarning): Added.
     28        (WI.Recording.synthesizeError):
     29        * UserInterface/Models/RecordingFrame.js:
     30        (WI.RecordingFrame.fromPayload):
     31        * UserInterface/Models/RecordingAction.js:
     32        (WI.RecordingAction.fromPayload):
     33        (WI.RecordingAction.prototype.async swizzle):
     34        (WI.RecordingAction.prototype.apply):
     35        * UserInterface/Controllers/CanvasManager.js:
     36        (WI.CanvasManager.prototype.processJSON):
     37
     38        * Localizations/en.lproj/localizedStrings.js:
     39
    1402019-01-24  Devin Rousso  <drousso@apple.com>
    241
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r240469 r240471  
    132132localizedStrings["Attributes"] = "Attributes";
    133133localizedStrings["Audit"] = "Audit";
    134 localizedStrings["Audit error: %s"] = "Audit error: %s";
     134localizedStrings["Audit Error: %s"] = "Audit Error: %s";
     135localizedStrings["Audit Warning: %s"] = "Audit Warning: %s";
    135136localizedStrings["Audit:"] = "Audit:";
    136137localizedStrings["Audits"] = "Audits";
     
    727728localizedStrings["Recording"] = "Recording";
    728729localizedStrings["Recording %d"] = "Recording %d";
     730localizedStrings["Recording Error: %s"] = "Recording Error: %s";
    729731localizedStrings["Recording Timeline Data"] = "Recording Timeline Data";
    730 localizedStrings["Recording error: %s"] = "Recording error: %s";
     732localizedStrings["Recording Warning: %s"] = "Recording Warning: %s";
    731733localizedStrings["Recordings"] = "Recordings";
    732734localizedStrings["Redirect Response"] = "Redirect Response";
     
    10551057localizedStrings["Yes"] = "Yes";
    10561058localizedStrings["Zoom:"] = "Zoom:";
    1057 localizedStrings["\u0022%s\u0022 is invalid."] = "\u0022%s\u0022 is invalid.";
     1059localizedStrings["\u0022%s\u0022 has a non-array \u0022%s\u0022 value"] = "\u0022%s\u0022 has a non-array \u0022%s\u0022 value";
     1060localizedStrings["\u0022%s\u0022 has a non-number \u0022%s\u0022 value"] = "\u0022%s\u0022 has a non-number \u0022%s\u0022 value";
     1061localizedStrings["\u0022%s\u0022 has a non-object \u0022%s\u0022 value"] = "\u0022%s\u0022 has a non-object \u0022%s\u0022 value";
     1062localizedStrings["\u0022%s\u0022 has a non-string \u0022%s\u0022 value"] = "\u0022%s\u0022 has a non-string \u0022%s\u0022 value";
     1063localizedStrings["\u0022%s\u0022 has an invalid \u0022%s\u0022 value"] = "\u0022%s\u0022 has an invalid \u0022%s\u0022 value";
     1064localizedStrings["\u0022%s\u0022 is not valid for %s"] = "\u0022%s\u0022 is not valid for %s";
     1065localizedStrings["\u0022%s\u0022 is too new to run in this Web Inspector"] = "\u0022%s\u0022 is too new to run in this Web Inspector";
     1066localizedStrings["\u0022%s\u0022 is too new to run on this inspected page"] = "\u0022%s\u0022 is too new to run on this inspected page";
    10581067localizedStrings["\u0022%s\u0022 must be a %s"] = "\u0022%s\u0022 must be a %s";
    10591068localizedStrings["\u0022%s\u0022 must be an %s"] = "\u0022%s\u0022 must be an %s";
    1060 localizedStrings["\u0022%s\u0022 threw an error."] = "\u0022%s\u0022 threw an error.";
     1069localizedStrings["\u0022%s\u0022 threw an error"] = "\u0022%s\u0022 threw an error";
    10611070localizedStrings["\u201C%s\u201D Event Fired"] = "\u201C%s\u201D Event Fired";
    10621071localizedStrings["\u201C%s\u201D Profile Recorded"] = "\u201C%s\u201D Profile Recorded";
     
    10641073localizedStrings["default"] = "default";
    10651074localizedStrings["for changes to take effect"] = "for changes to take effect";
    1066 localizedStrings["invalid JSON."] = "invalid JSON.";
     1075localizedStrings["invalid JSON"] = "invalid JSON";
    10671076localizedStrings["key"] = "key";
    10681077localizedStrings["line "] = "line ";
     1078localizedStrings["non-array %s"] = "non-array %s";
     1079localizedStrings["non-integer %s"] = "non-integer %s";
     1080localizedStrings["non-number %s"] = "non-number %s";
     1081localizedStrings["non-object %s"] = "non-object %s";
     1082localizedStrings["non-string %s"] = "non-string %s";
    10691083localizedStrings["originally %s"] = "originally %s";
    10701084localizedStrings["popup"] = "popup";
     
    10751089localizedStrings["times before stopping"] = "times before stopping";
    10761090localizedStrings["toggle"] = "toggle";
    1077 localizedStrings["unsupported version."] = "unsupported version.";
     1091localizedStrings["unknown %s \u0022%s\u0022"] = "unknown %s \u0022%s\u0022";
     1092localizedStrings["unsupported %s"] = "unsupported %s";
    10781093localizedStrings["value"] = "value";
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js

    r239976 r240471  
    4141    }
    4242
     43    // Static
     44
     45    static synthesizeWarning(message)
     46    {
     47        message = WI.UIString("Audit Warning: %s").format(message);
     48
     49        if (window.InspectorTest) {
     50            console.warn(message);
     51            return;
     52        }
     53
     54        let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Warning, message);
     55        consoleMessage.shouldRevealConsole = true;
     56
     57        WI.consoleLogViewController.appendConsoleMessage(consoleMessage);
     58    }
     59
    4360    static synthesizeError(message)
    4461    {
    45         let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Error, WI.UIString("Audit error: %s").format(message));
     62        message = WI.UIString("Audit Error: %s").format(message);
     63
     64        if (window.InspectorTest) {
     65            console.error(message);
     66            return;
     67        }
     68
     69        let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Error, message);
    4670        consoleMessage.shouldRevealConsole = true;
    4771
     
    170194        }
    171195
    172         let object = await WI.AuditTestGroup.fromPayload(json) || await WI.AuditTestCase.fromPayload(json);
    173         if (!object) {
    174             object = await WI.AuditTestGroupResult.fromPayload(json) || await WI.AuditTestCaseResult.fromPayload(json);
    175             if (!object) {
    176                 WI.AuditManager.synthesizeError(WI.UIString("invalid JSON."));
    177                 return;
    178             }
    179         }
     196        if (typeof json !== "object" || json === null) {
     197            WI.AuditManager.synthesizeError(WI.UIString("invalid JSON"));
     198            return;
     199        }
     200
     201        if (json.type !== WI.AuditTestCase.TypeIdentifier || json.type !== WI.AuditTestGroup.TypeIdentifier
     202            || json.type !== WI.AuditTestCaseResult.TypeIdentifier || json.type !== WI.AuditTestGroupResult.TypeIdentifier) {
     203            WI.AuditManager.synthesizeError(WI.UIString("unknown %s \u0022%s\u0022").format(WI.unlocalizedString("type"), json.type));
     204            return;
     205        }
     206
     207        let object = await WI.AuditTestGroup.fromPayload(json) || await WI.AuditTestCase.fromPayload(json) || await WI.AuditTestGroupResult.fromPayload(json) || await WI.AuditTestCaseResult.fromPayload(json);
     208        if (!object)
     209            return;
    180210
    181211        if (object instanceof WI.AuditTestBase) {
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js

    r238198 r240471  
    7575        }
    7676
     77        if (typeof json !== "object" || json === null) {
     78            WI.Recording.synthesizeError(WI.UIString("invalid JSON"));
     79            return;
     80        }
     81
    7782        let recording = WI.Recording.fromPayload(json);
    78         if (!recording) {
    79             WI.Recording.synthesizeError(WI.UIString("unsupported version."));
    80             return;
    81         }
     83        if (!recording)
     84            return;
    8285
    8386        let extensionStart = filename.lastIndexOf(".");
  • trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestBase.js

    r240469 r240471  
    4444        this._supported = true;
    4545        if (typeof this._supports === "number") {
    46             if (this._supports > WI.AuditTestBase.Version)
     46            if (this._supports > WI.AuditTestBase.Version) {
     47                WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 is too new to run in this Web Inspector").format(this.name));
    4748                this._supported = false;
    48             else if (InspectorBackend.domains.Audit && this._supports > InspectorBackend.domains.Audit.VERSION)
     49            } else if (InspectorBackend.domains.Audit && this._supports > InspectorBackend.domains.Audit.VERSION) {
     50                WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 is too new to run on this inspected page").format(this.name));
    4951                this._supported = false;
     52            }
    5053        }
    5154
  • trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js

    r240469 r240471  
    4242            return null;
    4343
    44         let {type, name, test, description, supports, disabled} = payload;
    45 
    46         if (type !== WI.AuditTestCase.TypeIdentifier)
    47             return null;
    48 
    49         if (typeof name !== "string")
    50             return null;
    51 
    52         if (typeof test !== "string")
    53             return null;
     44        if (payload.type !== WI.AuditTestCase.TypeIdentifier)
     45            return null;
     46
     47        if (typeof payload.name !== "string") {
     48            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("name")));
     49            return null;
     50        }
     51
     52        if (typeof payload.test !== "string") {
     53            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("test")));
     54            return null;
     55        }
    5456
    5557        let options = {};
    56         if (typeof description === "string")
    57             options.description = description;
    58         if (typeof supports === "number")
    59             options.supports = supports;
    60         if (typeof disabled === "boolean")
    61             options.disabled = disabled;
    62 
    63         return new WI.AuditTestCase(name, test, options);
     58
     59        if (typeof payload.description === "string")
     60            options.description = payload.description;
     61        else if ("description" in payload)
     62            WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("description")));
     63
     64        if (typeof payload.supports === "number")
     65            options.supports = payload.supports;
     66        else if ("supports" in payload)
     67            WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-number \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("supports")));
     68
     69        if (typeof payload.disabled === "boolean")
     70            options.disabled = payload.disabled;
     71
     72        return new WI.AuditTestCase(payload.name, payload.test, options);
    6473    }
    6574
  • trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestCaseResult.js

    r238850 r240471  
    4949            return null;
    5050
    51         let {type, name, description, level, data, metadata} = payload;
    52 
    53         if (type !== WI.AuditTestCaseResult.TypeIdentifier)
    54             return null;
    55 
    56         if (typeof name !== "string")
    57             return null;
    58 
    59         if (!Object.values(WI.AuditTestCaseResult.Level).includes(level))
    60             return null;
    61 
    62         if (typeof data !== "object" || data === null)
    63             data = {};
    64         else {
     51        if (payload.type !== WI.AuditTestCaseResult.TypeIdentifier)
     52            return null;
     53
     54        if (typeof payload.name !== "string") {
     55            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("name")));
     56            return null;
     57        }
     58
     59        if (!Object.values(WI.AuditTestCaseResult.Level).includes(payload.level)) {
     60            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has an invalid \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("level")));
     61            return null;
     62        }
     63
     64        if (typeof payload.data !== "object" || payload.data === null) {
     65            if ("data" in payload)
     66                WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("data")));
     67            payload.data = {};
     68        } else {
    6569            function checkArray(key) {
    66                 if (!data[key])
     70                if (!payload.data[key])
    6771                    return;
    6872
    69                 if (!Array.isArray(data[key]))
    70                     data[key] = [];
    71 
    72                 data[key] = data[key].filter((item) => typeof item === "string");
     73                if (!Array.isArray(payload.data[key])) {
     74                    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)));
     75                    payload.data[key] = [];
     76                }
     77
     78                payload.data[key] = payload.data[key].filter((item) => typeof item === "string");
    7379            }
    7480            checkArray("domNodes");
     
    7783        }
    7884
    79         if (typeof metadata !== "object" || metadata === null)
    80             metadata = {};
    81         else {
    82             metadata.startTimestamp = typeof metadata.startTimestamp === "string" ? new Date(metadata.startTimestamp) : null;
    83             metadata.asyncTimestamp = typeof metadata.asyncTimestamp === "string" ? new Date(metadata.asyncTimestamp) : null;
    84             metadata.endTimestamp = typeof metadata.endTimestamp === "string" ? new Date(metadata.endTimestamp) : null;
    85             metadata.url = typeof metadata.url === "string" ? metadata.url : null;
     85        if (typeof payload.metadata !== "object" || payload.metadata === null) {
     86            if ("metadata" in payload)
     87                WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata")));
     88
     89            payload.metadata = {};
     90        } else {
     91            if (typeof payload.metadata.startTimestamp === "string")
     92                payload.metadata.startTimestamp = new Date(payload.metadata.startTimestamp);
     93            else {
     94                if ("startTimestamp" in payload.metadata)
     95                    WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata.startTimestamp")));
     96
     97                payload.metadata.startTimestamp = null;
     98            }
     99
     100            if (typeof payload.metadata.asyncTimestamp === "string")
     101                payload.metadata.asyncTimestamp = new Date(payload.metadata.asyncTimestamp);
     102            else {
     103                if ("asyncTimestamp" in payload.metadata)
     104                    WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata.asyncTimestamp")));
     105
     106                payload.metadata.asyncTimestamp = null;
     107            }
     108
     109            if (typeof payload.metadata.endTimestamp === "string")
     110                payload.metadata.endTimestamp = new Date(payload.metadata.endTimestamp);
     111            else {
     112                if ("endTimestamp" in payload.metadata)
     113                    WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata.endTimestamp")));
     114
     115                payload.metadata.endTimestamp = null;
     116            }
     117
     118            if (typeof payload.metadata.url !== "string") {
     119                if ("url" in payload.metadata)
     120                    WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-object \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("metadata.url")));
     121
     122                payload.metadata.url = null;
     123            }
    86124        }
    87125
    88126        let options = {};
    89         if (typeof description === "string")
    90             options.description = description;
    91         if (!isEmptyObject(data)) {
     127
     128        if (typeof payload.description === "string")
     129            options.description = payload.description;
     130        else if ("description" in payload)
     131            WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("description")));
     132
     133        if (!isEmptyObject(payload.data)) {
    92134            options.data = {};
    93             if (data.domNodes && data.domNodes.length) {
    94                 if (window.DOMAgent && (!metadata.url || metadata.url === WI.networkManager.mainFrame.url)) {
     135            if (payload.data.domNodes && payload.data.domNodes.length) {
     136                if (window.DOMAgent && (!payload.metadata.url || payload.metadata.url === WI.networkManager.mainFrame.url)) {
    95137                    let documentNode = await new Promise((resolve) => WI.domManager.requestDocument(resolve));
    96                     options.resolvedDOMNodes = await Promise.all(data.domNodes.map(async (domNodeString) => {
     138                    options.resolvedDOMNodes = await Promise.all(payload.data.domNodes.map(async (domNodeString) => {
    97139                        let nodeId = 0;
    98140                        try {
     
    103145                }
    104146
    105                 options.data.domNodes = data.domNodes;
    106             }
    107             if (data.domAttributes && data.domAttributes.length)
    108                 options.data.domAttributes = data.domAttributes;
    109             if (data.errors && data.errors.length)
    110                 options.data.errors = data.errors;
    111         }
    112         if (!isEmptyObject(metadata)) {
     147                options.data.domNodes = payload.data.domNodes;
     148            }
     149            if (payload.data.domAttributes && payload.data.domAttributes.length)
     150                options.data.domAttributes = payload.data.domAttributes;
     151            if (payload.data.errors && payload.data.errors.length)
     152                options.data.errors = payload.data.errors;
     153        }
     154
     155        if (!isEmptyObject(payload.metadata)) {
    113156            options.metadata = {};
    114             if (metadata.startTimestamp && !isNaN(metadata.startTimestamp))
    115                 options.metadata.startTimestamp = metadata.startTimestamp;
    116             if (metadata.asyncTimestamp && !isNaN(metadata.asyncTimestamp))
    117                 options.metadata.asyncTimestamp = metadata.asyncTimestamp;
    118             if (metadata.endTimestamp && !isNaN(metadata.endTimestamp))
    119                 options.metadata.endTimestamp = metadata.endTimestamp;
    120             if (metadata.url)
    121                 options.metadata.url = metadata.url;
    122         }
    123 
    124         return new WI.AuditTestCaseResult(name, level, options);
     157            if (payload.metadata.startTimestamp && !isNaN(payload.metadata.startTimestamp))
     158                options.metadata.startTimestamp = payload.metadata.startTimestamp;
     159            if (payload.metadata.asyncTimestamp && !isNaN(payload.metadata.asyncTimestamp))
     160                options.metadata.asyncTimestamp = payload.metadata.asyncTimestamp;
     161            if (payload.metadata.endTimestamp && !isNaN(payload.metadata.endTimestamp))
     162                options.metadata.endTimestamp = payload.metadata.endTimestamp;
     163            if (payload.metadata.url)
     164                options.metadata.url = payload.metadata.url;
     165        }
     166
     167        return new WI.AuditTestCaseResult(payload.name, payload.level, options);
    125168    }
    126169
  • trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestGroup.js

    r240469 r240471  
    6767            return null;
    6868
    69         let {type, name, tests, description, supports, disabled} = payload;
    70 
    71         if (type !== WI.AuditTestGroup.TypeIdentifier)
    72             return null;
    73 
    74         if (typeof name !== "string")
    75             return null;
    76 
    77         if (!Array.isArray(tests))
    78             return null;
    79 
    80         tests = await Promise.all(tests.map(async (test) => {
     69        if (payload.type !== WI.AuditTestGroup.TypeIdentifier)
     70            return null;
     71
     72        if (typeof payload.name !== "string") {
     73            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("name")));
     74            return null;
     75        }
     76
     77        if (!Array.isArray(payload.tests)) {
     78            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-array \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("tests")));
     79            return null;
     80        }
     81
     82        let tests = await Promise.all(payload.tests.map(async (test) => {
    8183            let testCase = await WI.AuditTestCase.fromPayload(test);
    8284            if (testCase)
     
    9496
    9597        let options = {};
    96         if (typeof description === "string")
    97             options.description = description;
    98         if (typeof supports === "number")
    99             options.supports = supports;
    100         if (typeof disabled === "boolean")
    101             options.disabled = disabled;
    102 
    103         return new WI.AuditTestGroup(name, tests, options);
     98
     99        if (typeof payload.description === "string")
     100            options.description = payload.description;
     101        else if ("description" in payload)
     102            WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("description")));
     103
     104        if (typeof payload.supports === "number")
     105            options.supports = payload.supports;
     106        else if ("supports" in payload)
     107            WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-number \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("supports")));
     108
     109        if (typeof payload.disabled === "boolean")
     110            options.disabled = payload.disabled;
     111
     112        return new WI.AuditTestGroup(payload.name, tests, options);
    104113    }
    105114
  • trunk/Source/WebInspectorUI/UserInterface/Models/AuditTestGroupResult.js

    r237656 r240471  
    4242            return null;
    4343
    44         let {type, name, description, results} = payload;
    45 
    46         if (type !== WI.AuditTestGroupResult.TypeIdentifier)
     44        if (payload.type !== WI.AuditTestGroupResult.TypeIdentifier)
    4745            return null;
    4846
    49         if (typeof name !== "string")
     47        if (typeof payload.name !== "string") {
     48            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("name")));
    5049            return null;
     50        }
    5151
    52         if (!Array.isArray(results))
     52        if (!Array.isArray(payload.results)) {
     53            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-array \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("results")));
    5354            return null;
     55        }
    5456
    55         results = await Promise.all(results.map(async (test) => {
     57        let results = await Promise.all(payload.results.map(async (test) => {
    5658            let testCaseResult = await WI.AuditTestCaseResult.fromPayload(test);
    5759            if (testCaseResult)
     
    6971
    7072        let options = {};
    71         if (typeof description === "string")
    72             options.description = description;
    7373
    74         return new WI.AuditTestGroupResult(name, results, options);
     74        if (typeof payload.description === "string")
     75            options.description = payload.description;
     76        else if ("description" in payload)
     77            WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("description")));
     78
     79        return new WI.AuditTestGroupResult(payload.name, results, options);
    7580    }
    7681
  • trunk/Source/WebInspectorUI/UserInterface/Models/Recording.js

    r240318 r240471  
    5252            return null;
    5353
    54         if (isNaN(payload.version) || payload.version <= 0 || payload.version > WI.Recording.Version)
     54        if (typeof payload.version !== "number") {
     55            WI.Recording.synthesizeError(WI.UIString("non-number %s").format(WI.unlocalizedString("version")));
    5556            return null;
     57        }
     58
     59        if (payload.version < 1 || payload.version > WI.Recording.Version) {
     60            WI.Recording.synthesizeError(WI.UIString("unsupported %s").format(WI.unlocalizedString("version")));
     61            return null;
     62        }
     63
     64        if (parseInt(payload.version) !== payload.version) {
     65            WI.Recording.synthesizeWarning(WI.UIString("non-integer %s").format(WI.unlocalizedString("version")));
     66            payload.version = parseInt(payload.version);
     67        }
    5668
    5769        let type = null;
     
    6779            break;
    6880        default:
     81            WI.Recording.synthesizeWarning(WI.UIString("unknown %s \u0022%s\u0022").format(WI.unlocalizedString("type"), payload.type));
    6982            type = String(payload.type);
    7083            break;
    7184        }
    7285
    73         if (typeof payload.initialState !== "object" || payload.initialState === null)
     86        if (typeof payload.initialState !== "object" || payload.initialState === null) {
     87            if ("initialState" in payload)
     88                WI.Recording.synthesizeWarning(WI.UIString("non-object %s").format(WI.unlocalizedString("initialState")));
     89
    7490            payload.initialState = {};
    75         if (typeof payload.initialState.attributes !== "object" || payload.initialState.attributes === null)
     91        }
     92
     93        if (typeof payload.initialState.attributes !== "object" || payload.initialState.attributes === null) {
     94            if ("attributes" in payload.initialState)
     95                WI.Recording.synthesizeWarning(WI.UIString("non-object %s").format(WI.unlocalizedString("initialState.attributes")));
     96
    7697            payload.initialState.attributes = {};
     98        }
     99
    77100        if (!Array.isArray(payload.initialState.states) || payload.initialState.states.some((item) => typeof item !== "object" || item === null)) {
     101            if ("states" in payload.initialState)
     102                WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("initialState.states")));
     103
    78104            payload.initialState.states = [];
    79105
     
    85111            }
    86112        }
    87         if (!Array.isArray(payload.initialState.parameters))
     113
     114        if (!Array.isArray(payload.initialState.parameters)) {
     115            if ("parameters" in payload.initialState)
     116                WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("initialState.attributes")));
     117
    88118            payload.initialState.parameters = [];
    89         if (typeof payload.initialState.content !== "string")
     119        }
     120
     121        if (typeof payload.initialState.content !== "string") {
     122            if ("content" in payload.initialState)
     123                WI.Recording.synthesizeWarning(WI.UIString("non-string %s").format(WI.unlocalizedString("initialState.content")));
     124
    90125            payload.initialState.content = "";
    91 
    92         if (!Array.isArray(payload.frames))
     126        }
     127
     128        if (!Array.isArray(payload.frames)) {
     129            if ("frames" in payload)
     130                WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("frames")));
     131
    93132            payload.frames = [];
    94 
    95         if (!Array.isArray(payload.data))
     133        }
     134
     135        if (!Array.isArray(payload.data)) {
     136            if ("data" in payload)
     137                WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("data")));
     138
    96139            payload.data = [];
     140        }
    97141
    98142        if (!frames)
     
    151195    }
    152196
     197    static synthesizeWarning(message)
     198    {
     199        message = WI.UIString("Recording Warning: %s").format(message);
     200
     201        if (window.InspectorTest) {
     202            console.warn(message);
     203            return;
     204        }
     205
     206        let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Warning, message);
     207        consoleMessage.shouldRevealConsole = true;
     208
     209        WI.consoleLogViewController.appendConsoleMessage(consoleMessage);
     210    }
     211
    153212    static synthesizeError(message)
    154213    {
    155         const target = WI.mainTarget;
    156         const source = WI.ConsoleMessage.MessageSource.Other;
    157         const level = WI.ConsoleMessage.MessageLevel.Error;
    158         let consoleMessage = new WI.ConsoleMessage(target, source, level, WI.UIString("Recording error: %s").format(message));
     214        message = WI.UIString("Recording Error: %s").format(message);
     215
     216        if (window.InspectorTest) {
     217            console.error(message);
     218            return;
     219        }
     220
     221        let consoleMessage = new WI.ConsoleMessage(WI.mainTarget, WI.ConsoleMessage.MessageSource.Other, WI.ConsoleMessage.MessageLevel.Error, message);
    159222        consoleMessage.shouldRevealConsole = true;
    160223
  • trunk/Source/WebInspectorUI/UserInterface/Models/RecordingAction.js

    r238743 r240471  
    6464            payload = [];
    6565
    66         if (isNaN(payload[0]))
     66        if (typeof payload[0] !== "number") {
     67            if (payload.length > 0)
     68                WI.Recording.synthesizeWarning(WI.UIString("non-number %s").format(WI.unlocalizedString("name")));
     69
    6770            payload[0] = -1;
    68 
    69         if (!Array.isArray(payload[1]))
     71        }
     72
     73        if (!Array.isArray(payload[1])) {
     74            if (payload.length > 1)
     75                WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("parameters")));
     76
    7077            payload[1] = [];
    71 
    72         if (!Array.isArray(payload[2]))
     78        }
     79
     80        if (!Array.isArray(payload[2])) {
     81            if (payload.length > 2)
     82                WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("swizzleTypes")));
     83
    7384            payload[2] = [];
    74 
    75         if (isNaN(payload[3]) || (!payload[3] && payload[3] !== 0)) {
     85        }
     86
     87        if (typeof payload[3] !== "number" || isNaN(payload[3]) || (!payload[3] && payload[3] !== 0)) {
    7688            // COMPATIBILITY (iOS 12.1): "trace" was sent as an array of call frames instead of a single call stack
    77             if (!Array.isArray(payload[3]))
     89            if (!Array.isArray(payload[3])) {
     90                if (payload.length > 3)
     91                    WI.Recording.synthesizeWarning(WI.UIString("non-number %s").format(WI.unlocalizedString("trace")));
     92
    7893                payload[3] = [];
    79         }
    80 
    81         if (payload.length >= 5 && isNaN(payload[4]))
     94            }
     95        }
     96
     97        if (typeof payload[4] !== "number" || isNaN(payload[4])) {
     98            if (payload.length > 4)
     99                WI.Recording.synthesizeWarning(WI.UIString("non-number %s").format(WI.unlocalizedString("snapshot")));
     100
    82101            payload[4] = -1;
     102        }
    83103
    84104        return new WI.RecordingAction(...payload);
     
    311331                    this.markInvalid();
    312332
    313                     WI.Recording.synthesizeError(WI.UIString("\u0022%s\u0022 is invalid.").format(name));
     333                    WI.Recording.synthesizeWarning(WI.UIString("\u0022%s\u0022 is not valid for %s").format(name, prototype.constructor.name));
    314334                }
    315335            }
     
    361381            this.markInvalid();
    362382
    363             WI.Recording.synthesizeError(WI.UIString("\u0022%s\u0022 threw an error.").format(this._name));
     383            WI.Recording.synthesizeWarning(WI.UIString("\u0022%s\u0022 threw an error").format(this._name));
    364384        }
    365385    }
  • trunk/Source/WebInspectorUI/UserInterface/Models/RecordingFrame.js

    r224389 r240471  
    4040            payload = {};
    4141
    42         if (!Array.isArray(payload.actions))
     42        if (!Array.isArray(payload.actions)) {
     43            if ("actions" in payload)
     44                WI.Recording.synthesizeWarning(WI.UIString("non-array %s").format(WI.unlocalizedString("actions")));
     45
    4346            payload.actions = [];
     47        }
    4448
    4549        let actions = payload.actions.map(WI.RecordingAction.fromPayload);
Note: See TracChangeset for help on using the changeset viewer.