WebKit Bugzilla
Attachment 342727 Details for
Bug 184071
: AX: Audit Tab should have an Audit Manager
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-184071-20180613232454.patch (text/plain), 41.49 KB, created by
Aaron Chu
on 2018-06-13 23:24:55 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Aaron Chu
Created:
2018-06-13 23:24:55 PDT
Size:
41.49 KB
patch
obsolete
>Subversion Revision: 232827 >diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog >index 5959f81a80538d440f97d2f45799397048a8faf7..16f71bc8458fa764dcad3a4419b8d11a4f5fa545 100644 >--- a/Source/WebInspectorUI/ChangeLog >+++ b/Source/WebInspectorUI/ChangeLog >@@ -1,3 +1,69 @@ >+2018-06-13 Aaron Chu <aaron_chu@apple.com> >+ >+ AX: Audit Tab should have an Audit Manager >+ https://bugs.webkit.org/show_bug.cgi?id=184071 >+ <rdar://problem/38946364> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This implements the AuditManager for the audit feature. This patch revolves >+ around building out an AuditManager that facilitates an audit. The AuditManager >+ is responsible for managing and storing AuditReports and AuditTestSuites. It is >+ also tasked to decide how to run a test -- whether as a test case or as a test >+ suite. This patch also includes 4 models with which the AuditManager works to >+ perform an audit and to generate a report. These models include AuditTestCase, >+ which as a collection is stored inside an AuditTestSuite; and AuditResult, >+ which, as a collection is stored inside an AuditReport. >+ >+ * UserInterface/Controllers/AuditManager.js: Added. >+ (WI.AuditManager): >+ (WI.AuditManager.prototype.get testSuites): >+ (WI.AuditManager.prototype.get reports): >+ (WI.AuditManager.prototype.async.runAuditTestByRepresentedObject): >+ (WI.AuditManager.prototype.addTestSuite): >+ (WI.AuditManager.prototype.idForReport): >+ (WI.AuditManager.prototype.removeAllReports): >+ (WI.AuditManager.prototype.async._getAuditResultForTest): >+ * UserInterface/Models/AuditReport.js: Added. >+ (WI.AuditReport): >+ (WI.AuditReport.prototype.get representedTest): >+ (WI.AuditReport.prototype.get name): >+ (WI.AuditReport.prototype.get resultData): >+ (WI.AuditReport.prototype.get warningCount): >+ (WI.AuditReport.prototype.get errorCount): >+ (WI.AuditReport.prototype.get passedCount): >+ (WI.AuditReport.prototype.get suiteName): >+ (WI.AuditReport.prototype.get isWritable): >+ (WI.AuditReport.prototype.get failedCount): >+ (WI.AuditReport.prototype.get severity): >+ (WI.AuditReport.prototype.addResult): >+ (WI.AuditReport.prototype.close): >+ (WI.AuditReport.prototype._getFailedResults): >+ * UserInterface/Models/AuditResult.js: Added. >+ (WI.AuditResult): >+ (WI.AuditResult.prototype.get testResult): >+ (WI.AuditResult.prototype.get name): >+ (WI.AuditResult.prototype.get logLevel): >+ (WI.AuditResult.prototype.get failed): >+ * UserInterface/Models/AuditTestCase.js: Added. >+ (WI.AuditTestCase.prototype.get id): >+ (WI.AuditTestCase.prototype.get name): >+ (WI.AuditTestCase.prototype.get suite): >+ (WI.AuditTestCase.prototype.get test): >+ (WI.AuditTestCase.prototype.get setup): >+ (WI.AuditTestCase.prototype.get tearDown): >+ (WI.AuditTestCase.prototype.get errorDetails): >+ (WI.AuditTestCase): >+ * UserInterface/Models/AuditTestSuite.js: Added. >+ (WI.AuditTestSuite): >+ (WI.AuditTestSuite.testCaseDescriptors): >+ (WI.AuditTestSuite.prototype.get id): >+ (WI.AuditTestSuite.prototype.get name): >+ (WI.AuditTestSuite.prototype.get testCases): >+ (WI.AuditTestSuite.prototype.get testCaseCount): >+ (WI.AuditTestSuite.prototype._buildTestCasesFromDescriptors): >+ * UserInterface/Test.html: >+ > 2018-06-13 Nikita Vasilyev <nvasilyev@apple.com> > > Web Inspector: open source Dark Mode >diff --git a/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js b/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2eb8ebde822f60aa32ded5348dcb84adb25e44dd >--- /dev/null >+++ b/Source/WebInspectorUI/UserInterface/Controllers/AuditManager.js >@@ -0,0 +1,144 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+ WI.AuditManager = class AuditManager extends WI.Object >+{ >+ constructor() >+ { >+ super(); >+ >+ this._testSuiteConstructors = []; >+ this._reports = new Map; >+ >+ // Transforming all the constructors into AuditTestSuite instances. >+ this._testSuites = this._testSuiteConstructors.map(suite => { >+ let newTestSuite = new suite; >+ if (newTestSuite instanceof WI.AuditTestSuite) >+ return newTestSuite; >+ }); >+ } >+ >+ // Public >+ >+ get testSuites() { return this._testSuites.slice(); } >+ get reports() { >+ let reports = []; >+ for (let auditReport of this._reports.values()) { >+ reports.push(auditReport); >+ } >+ return reports; >+ } >+ >+ async runAuditTestByRepresentedObject(representedObject) >+ { >+ let auditReport = new WI.AuditReport(representedObject); >+ >+ if (representedObject instanceof WI.AuditTestCase) { >+ let auditResult = await this._getAuditResultForTest(representedObject); >+ auditReport.addResult(auditResult); >+ } >+ >+ if (representedObject instanceof WI.AuditTestSuite) { >+ let testCases = representedObject.testCases; >+ this.dispatchEventToListeners(WI.AuditManager.Event.TestStarted, {test: representedObject}); >+ >+ // Start reducing from testCases[0]. >+ let result = testCases.slice(1).reduce((chain, testCase, index) => { >+ if (testCase.setup) { >+ let setup = testCase.setup.call(testCase, testCase.suite) >+ if (testCase.setup[Symbol.toStringTag] === "AsyncFunction") >+ return setup; >+ else >+ return new Promise(setup); >+ } >+ >+ chain = chain.then((auditResult) => { >+ auditReport.addResult(auditResult); >+ return this._getAuditResultForTest(testCase) >+ }); >+ >+ if (testCase.tearDown) { >+ let tearDown = testCase.tearDown.call(testCase, testCase.suite) >+ if (testCase.tearDown[Symbol.toStringTag] === "AsyncFunction") >+ return tearDown; >+ else >+ return new Promise(tearDown); >+ } >+ return chain; >+ }, this._getAuditResultForTest(testCases[0])); >+ >+ let lastAuditResult = await result; >+ auditReport.addResult(lastAuditResult); >+ >+ // Making AuditReport read-only after all the AuditResults have been received. >+ auditReport.close(); >+ this.dispatchEventToListeners(WI.AuditManager.Event.TestEnded, {test: representedObject}); >+ } >+ >+ this._reports.set(representedObject.id, auditReport); >+ } >+ >+ addTestSuite(auditTestSuiteConstructor) >+ { >+ if (this._testSuiteConstructors.indexOf(auditTestSuiteConstructor) >= 0) >+ return; >+ >+ let auditTestSuite = new auditTestSuiteConstructor; >+ this._testSuiteConstructors.push(auditTestSuiteConstructor); >+ this._testSuites.push(auditTestSuite); >+ } >+ >+ idForReport(reportId) >+ { >+ return this._reports.get(reportId); >+ } >+ >+ removeAllReports() >+ { >+ this._reports.clear(); >+ } >+ >+ // Private >+ >+ async _getAuditResultForTest(testCase) >+ { >+ let failed = true; >+ let result; >+ this.dispatchEventToListeners(WI.AuditManager.Event.TestStarted, {test: testCase}); >+ try { >+ result = await testCase.test.call(testCase, testCase.suite); >+ failed = false; >+ } catch (resultData) { >+ result = resultData; >+ } >+ this.dispatchEventToListeners(WI.AuditManager.Event.TestEnded, {test: testCase}); >+ return new WI.AuditResult(testCase, {result}, failed); >+ } >+} >+ >+WI.AuditManager.Event = { >+ TestStarted: Symbol("test-started"), >+ TestEnded: Symbol("test-ended") >+} >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditReport.js b/Source/WebInspectorUI/UserInterface/Models/AuditReport.js >new file mode 100644 >index 0000000000000000000000000000000000000000..8a0b3513554e22f21a1024fabd9f9c5ea1a8b6d0 >--- /dev/null >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditReport.js >@@ -0,0 +1,83 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+ WI.AuditReport = class AuditReport >+{ >+ constructor(representedTest) >+ { >+ console.assert(representedTest instanceof WI.AuditTestCase || representedTest instanceof WI.AuditTestSuite); >+ >+ this._reportName = representedTest.name; >+ this._results = []; >+ this._representedTest = representedTest; >+ this._isWritable = true; >+ } >+ >+ // Public >+ >+ get representedTest() { return this._representedTest; } >+ get name() { return this._reportName; } >+ get resultData() { return this._results.slice(); } >+ get warningCount() { return this._warningsResults.length; } >+ get errorCount() { return this._errorResults.length; } >+ get passedCount() { return this._passedResults.length; } >+ get suiteName() { return this._reportForSuite; } >+ get isWritable() { return this._isWritable; } >+ >+ get failedCount() { >+ return this._getFailedResults().length; >+ } >+ >+ get severity() >+ { >+ let failedResults = this._getFailedResults(); >+ for (let result of failedResults) { >+ if (result.logLevel === WI.AuditResult.LogLevel.Error) >+ return WI.AuditResult.LogLevel.Error; >+ } >+ return WI.AuditResult.LogLevel.Warning; >+ } >+ >+ addResult(auditResult) >+ { >+ if (!this._isWritable) >+ return; >+ >+ console.assert(auditResult instanceof WI.AuditResult); >+ this._results.push(auditResult); >+ } >+ >+ close() >+ { >+ this._isWritable = false; >+ } >+ >+ // Private >+ >+ _getFailedResults() >+ { >+ return this._results.slice().filter(result => result.failed); >+ } >+} >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditResult.js b/Source/WebInspectorUI/UserInterface/Models/AuditResult.js >new file mode 100644 >index 0000000000000000000000000000000000000000..ee9ba1baa6c25d9397767a3529c8b7f8fb8af176 >--- /dev/null >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditResult.js >@@ -0,0 +1,52 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+ WI.AuditResult = class AuditResult >+{ >+ constructor(testInstance, testResult, failed) >+ { >+ this._testResult = testResult; >+ this._failed = failed || false; >+ this._testName = testInstance.name; >+ this._errorDetails = testInstance.errorDetails; >+ this._logLevel = this._errorDetails.logLevel || WI.AuditResult.LogLevel.Passed; >+ this._errorTitle = this._errorDetails.title; >+ this._hint = this._errorDetails.hint; >+ this._documentation = this._errorDetails.documentation; >+ } >+ >+ // Public >+ >+ get testResult() { return this._testResult; } >+ get name() { return this._testName; } >+ get logLevel() { return this._logLevel; } >+ get failed() { return this._failed; } >+} >+ >+WI.AuditResult.LogLevel = { >+ Error: "error", >+ Warning: "warning", >+ Passed: "passed" >+} >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js >new file mode 100644 >index 0000000000000000000000000000000000000000..3ac07f845dc6dd81d6677443e1e1998e88cb0c7a >--- /dev/null >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestCase.js >@@ -0,0 +1,61 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+ WI.AuditTestCase = class AuditTestCase extends WI.Object >+{ >+ constructor(suite, name, test, setup, tearDown, errorDetails = {}) >+ { >+ console.assert(suite instanceof WI.AuditTestSuite); >+ console.assert(typeof(name) === "string"); >+ >+ if (setup) >+ console.assert(setup instanceof Function); >+ >+ if (tearDown) >+ console.assert(tearDown instanceof Function); >+ >+ if (test[Symbol.toStringTag] !== "AsyncFunction") >+ throw new Error("Test functions must be async functions."); >+ >+ super(); >+ this._id = Symbol(name); >+ this._suite = suite; >+ this._name = name; >+ this._test = test; >+ this._setup = setup; >+ this._tearDown = tearDown; >+ this._errorDetails = errorDetails; >+ } >+ >+ // Public >+ >+ get id() { return this._id; } >+ get name() { return this._name; } >+ get suite() { return this._suite; } >+ get test() { return this._test; } >+ get setup() { return this._setup; } >+ get tearDown() { return this._tearDown; } >+ get errorDetails() { return this._errorDetails; } >+} >diff --git a/Source/WebInspectorUI/UserInterface/Models/AuditTestSuite.js b/Source/WebInspectorUI/UserInterface/Models/AuditTestSuite.js >new file mode 100644 >index 0000000000000000000000000000000000000000..0476df677a5e9e57717d3ba8a99c1d7f53029e1f >--- /dev/null >+++ b/Source/WebInspectorUI/UserInterface/Models/AuditTestSuite.js >@@ -0,0 +1,78 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+ WI.AuditTestSuite = class AuditTestSuite extends WI.Object >+{ >+ constructor(identifier, name) >+ { >+ super(); >+ this._id = Symbol(identifier); >+ this._name = name; >+ this._testCases = new Map; >+ } >+ >+ static testCaseDescriptors() { throw WI.NotImplementedError.subclassMustOverride(); } >+ >+ // Public >+ >+ get id() { return this._id; } >+ get name() { return this._name; } >+ get testCases() { >+ let testCasesArray = []; >+ >+ for (let testCase of this._testCases.values()) { >+ testCasesArray.push(testCase); >+ } >+ return testCasesArray; >+ } >+ >+ get testCaseCount() >+ { >+ return this._testCases.size; >+ } >+ >+ // Private >+ >+ _buildTestCasesFromDescriptors(descriptors) >+ { >+ for (let descriptor of descriptors) { >+ if (typeof(descriptor.name) !== "string" || !descriptor.name) >+ throw new Error("Test name must be a valid string."); >+ >+ let {name, test, setup, tearDown, errorDetails} = descriptor; >+ >+ if (!test instanceof Function || test[Symbol.toStringTag] !== "AsyncFunction") >+ throw new Error("Test function must be an async function."); >+ >+ let testCaseInstance = new WI.AuditTestCase(this, name, test, setup, tearDown, errorDetails); >+ >+ this._testCases.set(testCaseInstance.id, testCaseInstance); >+ } >+ } >+} >+ >+WI.AuditTestSuite.Event = { >+ NewAuditResultAvailable: Symbol("new-audit-result-available") >+} >diff --git a/Source/WebInspectorUI/UserInterface/Test.html b/Source/WebInspectorUI/UserInterface/Test.html >index 60fb8127e49c192a36cebe5615850b50194db247..357f69c65680da26bbe16f55ce479b5e4ce6c8e4 100644 >--- a/Source/WebInspectorUI/UserInterface/Test.html >+++ b/Source/WebInspectorUI/UserInterface/Test.html >@@ -195,6 +195,11 @@ > <script src="Models/WrappedPromise.js"></script> > <script src="Models/XHRBreakpoint.js"></script> > >+ <script src="Models/AuditReport.js"></script> >+ <script src="Models/AuditResult.js"></script> >+ <script src="Models/AuditTestCase.js"></script> >+ <script src="Models/AuditTestSuite.js"></script> >+ > <script src="Proxies/FormatterWorkerProxy.js"></script> > <script src="Proxies/HeapSnapshotDiffProxy.js"></script> > <script src="Proxies/HeapSnapshotEdgeProxy.js"></script> >@@ -222,6 +227,7 @@ > <script src="Controllers/TargetManager.js"></script> > <script src="Controllers/TimelineManager.js"></script> > <script src="Controllers/WorkerManager.js"></script> >+ <script src="Controllers/AuditManager.js"></script> > > <script src="Controllers/Formatter.js"></script> > <script src="Controllers/ResourceQueryController.js"></script> >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 4acddd5eb1240740fd9c7e3f5b679ed302071df6..669d7054454e5c67041ff6cdfc58216bb1e2b3aa 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,29 @@ >+2018-06-13 Aaron Chu <aaron_chu@apple.com> >+ >+ AX: Audit Tab should have an Audit Manager >+ https://bugs.webkit.org/show_bug.cgi?id=184071 >+ <rdar://problem/38946364> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Test cases for AuditManager, AuditTestCase, AuditTestSuite, AuditResult >+ and AuditReport. >+ >+ * inspector/audit/audit-manager-expected.txt: Added. >+ * inspector/audit/audit-manager.html: Added. >+ * inspector/audit/audit-report-expected.txt: Added. >+ * inspector/audit/audit-report.html: Added. >+ * inspector/audit/audit-test-case-expected.txt: Added. >+ * inspector/audit/audit-test-case.html: Added. >+ * inspector/audit/audit-test-suite-expected.txt: Added. >+ * inspector/audit/audit-test-suite.html: Added. >+ * inspector/audit/resources/audit-test-fixtures.js: Added. >+ (TestPage.registerInitializer.window.testSuiteFixture1): >+ (TestPage.registerInitializer.window.testSuiteFixture1.testCaseDescriptors): >+ (TestPage.registerInitializer.window.testSuiteFixture2): >+ (TestPage.registerInitializer.window.testSuiteFixture2.testCaseDescriptors): >+ (TestPage.registerInitializer): >+ > 2018-06-13 Zalan Bujtas <zalan@apple.com> > > [Mail] Use the Mail Viewer width as the base for resolving horizontal viewport units >diff --git a/LayoutTests/inspector/audit/audit-manager-expected.txt b/LayoutTests/inspector/audit/audit-manager-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5c0118e6be5a3898d4e55462c7eb68af5c3dc58b >--- /dev/null >+++ b/LayoutTests/inspector/audit/audit-manager-expected.txt >@@ -0,0 +1,47 @@ >+Test for the AuditManager Instantiation. >+ >+ >+== Running test suite: AuditManager >+-- Running test case: Adding an AuditTestSuite >+PASS: AuditManager should have 0 testSuite. >+Adding an AuditTestSuite to AuditManager. >+PASS: AuditManager should have 1 test suite. >+PASS: New test suite is of AuditTestSuite. >+PASS: New test suite has the correct name. >+ >+-- Running test case: Adding a duplicating AuditTestSuite >+PASS: There are 2 test suites in auditManager. >+PASS: Test suite name: FakeTestSuite1 >+PASS: Test suite name: FakeTestSuite2 >+PASS: There is not a third test suite. >+ >+-- Running test case: Perform tests by AuditTestSuite. >+PASS: Receive a report that is of instance AuditReport. >+PASS: AuditReport is not writable >+PASS: There are two results in AuditReport. >+PASS: auditReport at index 0 is an instance of AuditResult. >+PASS: auditReport at index 0 is expected for test case fakeTest1. >+PASS: auditReport at index 1 is an instance of AuditResult. >+PASS: auditReport at index 1 is expected for test case fakeTest2. >+AuditReport is not writable. >+Attempting to add another AuditResult to AuditReport. >+PASS: AuditReport no longer accepts new AuditResults. >+PASS: Report represents the expected AuditTestSuite. >+ >+-- Running test case: Perform a test by AuditTestCase. >+PASS: Receive a report that is of instance AuditReport. >+PASS: AuditReport represents the expected AuditTestCase. >+ >+-- Running test case: AuditReports are unique. >+Running the same test suite twice. >+PASS: auditManager only has 1 report. >+PASS: The report represents the correct AuditTestSuite. >+ >+-- Running test case: Get AuditReport by AuditTestCase/Suite id. >+Running a test for an AuditTestSuite. >+PASS: auditReport is an instance of AuditReport. >+PASS: The report represents the correct AuditTestSuite. >+Running a test for an AuditTestCase. >+PASS: auditReport is an instance of AuditReport. >+PASS: The report represents the correct AuditTestCase. >+ >diff --git a/LayoutTests/inspector/audit/audit-manager.html b/LayoutTests/inspector/audit/audit-manager.html >new file mode 100644 >index 0000000000000000000000000000000000000000..8439e71fd84f6819e1bd5d523872719f01ce2f53 >--- /dev/null >+++ b/LayoutTests/inspector/audit/audit-manager.html >@@ -0,0 +1,147 @@ >+<!doctype html> >+<html> >+<head> >+<script src="../../http/tests/inspector/resources/inspector-test.js"></script> >+<script src="./resources/audit-test-fixtures.js"></script> >+<script> >+function test() >+{ >+ let suite = InspectorTest.createAsyncSuite("AuditManager"); >+ >+ suite.addTestCase({ >+ name: "Adding an AuditTestSuite", >+ description: "AuditManager should have one instantiated AuditTestSuite.", >+ async test(){ >+ let auditManager = new WI.AuditManager; >+ >+ InspectorTest.expectThat(!auditManager.testSuites.length, "AuditManager should have 0 testSuite."); >+ >+ InspectorTest.log("Adding an AuditTestSuite to AuditManager."); >+ auditManager.addTestSuite(testSuiteFixture1); >+ let testSuite = auditManager.testSuites[0]; >+ >+ InspectorTest.expectThat(auditManager.testSuites.length === 1, "AuditManager should have 1 test suite."); >+ InspectorTest.expectThat(testSuite instanceof WI.AuditTestSuite, "New test suite is of AuditTestSuite."); >+ InspectorTest.expectThat(testSuite.name === "FakeTestSuite1", "New test suite has the correct name."); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "Adding a duplicating AuditTestSuite", >+ description: "Should ignore duplicated test suite.", >+ async test() { >+ let auditManager = new WI.AuditManager; >+ >+ auditManager.addTestSuite(testSuiteFixture1); >+ auditManager.addTestSuite(testSuiteFixture2); >+ auditManager.addTestSuite(testSuiteFixture1); >+ >+ InspectorTest.expectThat(auditManager.testSuites.length === 2, "There are 2 test suites in auditManager."); >+ InspectorTest.expectThat(auditManager.testSuites[0].name === "FakeTestSuite1", `Test suite name: ${auditManager.testSuites[0].name}`); >+ InspectorTest.expectThat(auditManager.testSuites[1].name === "FakeTestSuite2", `Test suite name: ${auditManager.testSuites[1].name}`); >+ InspectorTest.expectFalse(auditManager.testSuites[2], "There is not a third test suite."); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "Perform tests by AuditTestSuite.", >+ description: "Should produce report for AuditTestSuite.", >+ async test() { >+ let auditManager = new WI.AuditManager; >+ >+ InspectorTest.assert(!auditManager._reports.size, "auditManager has no reports."); >+ >+ let testSuite = new testSuiteFixture1; >+ let testCaseNames = testSuite.testCases.map(testCase => { >+ return testCase.name; >+ }) >+ >+ await auditManager.runAuditTestByRepresentedObject(testSuite); >+ >+ let auditReport = auditManager.reports[0]; >+ >+ InspectorTest.expectThat(auditReport instanceof WI.AuditReport, "Receive a report that is of instance AuditReport."); >+ InspectorTest.expectThat(!auditReport._isWritable, "AuditReport is not writable"); >+ InspectorTest.expectThat(auditReport.resultData.length === 2, "There are two results in AuditReport."); >+ >+ for (let i = 0; i < auditReport.resultData.length; i++) { >+ let resultToTest = auditReport.resultData[i]; >+ InspectorTest.expectThat(resultToTest instanceof WI.AuditResult, `auditReport at index ${i} is an instance of AuditResult.`) >+ InspectorTest.expectThat(testCaseNames.indexOf(resultToTest.name) >= 0, `auditReport at index ${i} is expected for test case ${resultToTest.name}.`); >+ } >+ InspectorTest.log("AuditReport is not writable."); >+ InspectorTest.log("Attempting to add another AuditResult to AuditReport."); >+ let additionalReport = auditReport.resultData[1]; >+ auditReport.addResult(additionalReport); >+ >+ InspectorTest.expectThat(auditReport.resultData.length === 2, "AuditReport no longer accepts new AuditResults."); >+ InspectorTest.expectThat(auditReport.representedTest.id === testSuite.id, "Report represents the expected AuditTestSuite."); >+ } >+ }); >+ >+ >+ suite.addTestCase({ >+ name: "Perform a test by AuditTestCase.", >+ description: "Should produce report for AuditTestCase.", >+ async test() { >+ let auditManager = new WI.AuditManager; >+ auditManager.addTestSuite(testSuiteFixture1); >+ let testCase = auditManager.testSuites[0].testCases[0]; >+ >+ await auditManager.runAuditTestByRepresentedObject(testCase); >+ >+ let auditReport = auditManager.reports[0]; >+ >+ InspectorTest.expectThat(auditReport instanceof WI.AuditReport, "Receive a report that is of instance AuditReport."); >+ InspectorTest.expectThat(auditReport.name === testCase.name, "AuditReport represents the expected AuditTestCase."); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "AuditReports are unique.", >+ description: "No AuditReport should represent the same AuditTestCase/Suite", >+ async test() { >+ let auditManager = new WI.AuditManager; >+ let testSuite = new testSuiteFixture1; >+ >+ InspectorTest.log("Running the same test suite twice."); >+ await auditManager.runAuditTestByRepresentedObject(testSuite); >+ await auditManager.runAuditTestByRepresentedObject(testSuite); >+ >+ let reports = auditManager.reports; >+ >+ InspectorTest.expectThat(reports.length === 1, "auditManager only has 1 report."); >+ InspectorTest.expectThat(reports[0].name === testSuite.name, "The report represents the correct AuditTestSuite."); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "Get AuditReport by AuditTestCase/Suite id.", >+ description: "Should return the correct AuditReport.", >+ async test() { >+ let auditManager = new WI.AuditManager; >+ let testSuite = new testSuiteFixture1; >+ >+ InspectorTest.log("Running a test for an AuditTestSuite."); >+ await auditManager.runAuditTestByRepresentedObject(testSuite); >+ let auditReportForTestSuite = auditManager.idForReport(testSuite.id); >+ InspectorTest.expectThat(auditReportForTestSuite instanceof WI.AuditReport, "auditReport is an instance of AuditReport."); >+ InspectorTest.expectThat(auditReportForTestSuite.name === testSuite.name, "The report represents the correct AuditTestSuite."); >+ >+ InspectorTest.log("Running a test for an AuditTestCase."); >+ let testCase = testSuite.testCases[0]; >+ await auditManager.runAuditTestByRepresentedObject(testCase); >+ let auditReportForTestCase = auditManager.idForReport(testCase.id); >+ InspectorTest.expectThat(auditReportForTestCase instanceof WI.AuditReport, "auditReport is an instance of AuditReport."); >+ InspectorTest.expectThat(auditReportForTestCase.name === testCase.name, "The report represents the correct AuditTestCase."); >+ } >+ }); >+ >+ suite.runTestCasesAndFinish(); >+} >+</script> >+</head> >+<body onload="runTest()"> >+<p>Test for the AuditManager Instantiation.</p> >+</body> >+</html> >diff --git a/LayoutTests/inspector/audit/audit-report-expected.txt b/LayoutTests/inspector/audit/audit-report-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6369257a07c46718cfbbbf135d3eb7839b1e6217 >--- /dev/null >+++ b/LayoutTests/inspector/audit/audit-report-expected.txt >@@ -0,0 +1,7 @@ >+Test for the AuditManager Instantiation. >+ >+ >+== Running test suite: AuditReport >+-- Running test case: Instantiation with test suite >+PASS: Instantiate AuditReport with AuditTestSuite. >+ >diff --git a/LayoutTests/inspector/audit/audit-report.html b/LayoutTests/inspector/audit/audit-report.html >new file mode 100644 >index 0000000000000000000000000000000000000000..fcd53b8ea38b6200a7ce24c8c5e6549d7cb8487c >--- /dev/null >+++ b/LayoutTests/inspector/audit/audit-report.html >@@ -0,0 +1,31 @@ >+<!doctype html> >+<html> >+<head> >+<script src="../../http/tests/inspector/resources/inspector-test.js"></script> >+<script src="./resources/audit-test-fixtures.js"></script> >+<script> >+function test() >+{ >+ >+ let suite = InspectorTest.createAsyncSuite("AuditReport"); >+ >+ suite.addTestCase({ >+ name: "Instantiation with test suite", >+ description: "should instantiate correctly.", >+ test(resolve, reject) { >+ let testSuite = new testSuiteFixture1; >+ InspectorTest.assert(testSuite instanceof WI.AuditTestSuite, "testSuite is AuditTestSuite."); >+ let report = new WI.AuditReport(testSuite); >+ InspectorTest.expectThat(report instanceof WI.AuditReport, "Instantiate AuditReport with AuditTestSuite."); >+ resolve(); >+ } >+ }); >+ >+ suite.runTestCasesAndFinish(); >+} >+</script> >+</head> >+<body onload="runTest()"> >+<p>Test for the AuditManager Instantiation.</p> >+</body> >+</html> >diff --git a/LayoutTests/inspector/audit/audit-test-case-expected.txt b/LayoutTests/inspector/audit/audit-test-case-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1054e46487af06a69cc4685ce46fad895bdaf888 >--- /dev/null >+++ b/LayoutTests/inspector/audit/audit-test-case-expected.txt >@@ -0,0 +1,11 @@ >+Test for the AudtTestCase. >+ >+ >+== Running test suite: AuditTestCase >+-- Running test case: Instantiation >+PASS: AuditTestCase is of instance test case. >+ >+-- Running test case: Test functions must be asynchronous. >+PASS: Should produce an exception. >+Error: Test functions must be async functions. >+ >diff --git a/LayoutTests/inspector/audit/audit-test-case.html b/LayoutTests/inspector/audit/audit-test-case.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e5fa332f134f7eced6a4b8f54d3d6d9cf7b13195 >--- /dev/null >+++ b/LayoutTests/inspector/audit/audit-test-case.html >@@ -0,0 +1,38 @@ >+<!doctype html> >+<html> >+<head> >+<script src="../../http/tests/inspector/resources/inspector-test.js"></script> >+<script src="./resources/audit-test-fixtures.js"></script> >+<script> >+function test() >+{ >+ >+ let suite = InspectorTest.createAsyncSuite("AuditTestCase"); >+ >+ suite.addTestCase({ >+ name: "Instantiation", >+ description: "AudtTestCase should instantiate.", >+ test(resolve, reject) { >+ let auditTestCase = new WI.AuditTestCase(new testSuiteFixture1, "fakeTest2", async () => []); >+ InspectorTest.expectThat(auditTestCase instanceof WI.AuditTestCase, "AuditTestCase is of instance test case."); >+ resolve(); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "Test functions must be asynchronous.", >+ description: "AuditTestCase should throw an exception when instantiated with a non-async function.", >+ test(resolve, reject) { >+ InspectorTest.expectException(() => {new WI.AuditTestCase(new testSuiteFixture1, "fakeTest2", () => [])}) >+ resolve(); >+ } >+ }) >+ >+ suite.runTestCasesAndFinish(); >+} >+</script> >+</head> >+<body onload="runTest()"> >+<p>Test for the AudtTestCase.</p> >+</body> >+</html> >diff --git a/LayoutTests/inspector/audit/audit-test-suite-expected.txt b/LayoutTests/inspector/audit/audit-test-suite-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1bb446bb273730edd9e9a2ca4870584d2f55f978 >--- /dev/null >+++ b/LayoutTests/inspector/audit/audit-test-suite-expected.txt >@@ -0,0 +1,13 @@ >+Test for the AuditTestSuite. >+ >+ >+== Running test suite: AuditTestSuite >+-- Running test case: AuditTestSuite Id >+PASS: AuditTestSuite1 has ID with correct type. >+PASS: AuditTestSuite2 has ID with correct type. >+PASS: AuditTestSuites with same name have different unique IDs. >+ >+-- Running test case: AuditTestSuite testCaseCount >+PASS: There are two tests. >+PASS: AuditTestSuite has correct test case count. >+ >diff --git a/LayoutTests/inspector/audit/audit-test-suite.html b/LayoutTests/inspector/audit/audit-test-suite.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d6cbfaf3ffe555dc56d40ea409dace2e0e69f608 >--- /dev/null >+++ b/LayoutTests/inspector/audit/audit-test-suite.html >@@ -0,0 +1,43 @@ >+<!doctype html> >+<html> >+<head> >+<script src="../../http/tests/inspector/resources/inspector-test.js"></script> >+<script src="./resources/audit-test-fixtures.js"></script> >+<script> >+function test() >+{ >+ >+ let suite = InspectorTest.createAsyncSuite("AuditTestSuite"); >+ >+ let auditTestSuite1 = new testSuiteFixture1("FakeTestSuite", "FakeTestSuite"); >+ let auditTestSuite2 = new testSuiteFixture1("FakeTestSuite", "FakeTestSuite"); >+ >+ suite.addTestCase({ >+ name: "AuditTestSuite Id", >+ description: "Should exist and be unique", >+ test(resolve, reject) { >+ InspectorTest.expectThat(typeof(auditTestSuite1.id) === "symbol", "AuditTestSuite1 has ID with correct type."); >+ InspectorTest.expectThat(typeof(auditTestSuite2.id) === "symbol", "AuditTestSuite2 has ID with correct type."); >+ InspectorTest.expectThat(auditTestSuite1.id !== auditTestSuite2.id, "AuditTestSuites with same name have different unique IDs."); >+ resolve(); >+ } >+ }); >+ >+ suite.addTestCase({ >+ name: "AuditTestSuite testCaseCount", >+ description: "Should represents correct number of test case.", >+ test(resolve, reject) { >+ InspectorTest.expectThat(auditTestSuite1.testCases.length === 2, "There are two tests."); >+ InspectorTest.expectThat(auditTestSuite1.testCaseCount === 2, "AuditTestSuite has correct test case count."); >+ resolve(); >+ } >+ }); >+ >+ suite.runTestCasesAndFinish(); >+} >+</script> >+</head> >+<body onload="runTest()"> >+<p>Test for the AuditTestSuite.</p> >+</body> >+</html> >diff --git a/LayoutTests/inspector/audit/resources/audit-test-fixtures.js b/LayoutTests/inspector/audit/resources/audit-test-fixtures.js >new file mode 100644 >index 0000000000000000000000000000000000000000..60f538a53e696bfb16d966c95cecdc3d46af51e0 >--- /dev/null >+++ b/LayoutTests/inspector/audit/resources/audit-test-fixtures.js >@@ -0,0 +1,52 @@ >+TestPage.registerInitializer(() => { >+ >+ window.testSuiteFixture1 = class testSuiteFixture1 extends WI.AuditTestSuite >+ { >+ constructor() >+ { >+ super("FakeTestSuite1", "FakeTestSuite1"); >+ this._buildTestCasesFromDescriptors(testSuiteFixture1.testCaseDescriptors()); >+ } >+ static testCaseDescriptors() >+ { >+ return [ >+ { >+ name: "fakeTest1", >+ async test() >+ { >+ return Promise.resolve(); >+ } >+ }, >+ { >+ name: "fakeTest2", >+ async test() >+ { >+ return Promise.reject([1, 2, 3, 4]); >+ } >+ } >+ ]; >+ } >+ } >+ >+ window.testSuiteFixture2 = class testSuiteFixture2 extends WI.AuditTestSuite >+ { >+ constructor() >+ { >+ super("FakeTestSuite2", "FakeTestSuite2"); >+ this._buildTestCasesFromDescriptors(testSuiteFixture2.testCaseDescriptors()); >+ } >+ static testCaseDescriptors() >+ { >+ return [ >+ { >+ name: "fakeTest2", >+ async test() >+ { >+ return Promise.resolve([]); >+ } >+ } >+ ]; >+ } >+ } >+ >+});
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 184071
:
336647
|
337600
|
338198
|
342727
|
344826
|
344830
|
345010
|
345015