haikuwebkit/LayoutTests/inspector/unit-tests/target-manager.html

75 lines
3.0 KiB
HTML
Raw Permalink Normal View History

Web Inspector: Include RuntimeAgent in Workers - evaluate in Worker context https://bugs.webkit.org/show_bug.cgi?id=163835 <rdar://problem/28901465> Reviewed by Brian Burg. Source/WebCore: Tests: inspector/unit-tests/target-manager.html inspector/worker/runtime-basic.html * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * inspector/InspectorAllInOne.cpp: New file. * inspector/InspectorWebAgentBase.h: (WebCore::WorkerAgentContext::WorkerAgentContext): New agent context creation struct for Workers. * inspector/WorkerInspectorController.cpp: (WebCore::WorkerInspectorController::WorkerInspectorController): Create a RuntimeAgent for Workers. * inspector/WorkerRuntimeAgent.cpp: Added. (WebCore::WorkerRuntimeAgent::WorkerRuntimeAgent): (WebCore::WorkerRuntimeAgent::didCreateFrontendAndBackend): (WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend): (WebCore::WorkerRuntimeAgent::injectedScriptForEval): * inspector/WorkerRuntimeAgent.h: Added. Workers currently only ever have a single execution context. Source/WebInspectorUI: This introduces the idea that the frontend may communication with multiple backend "Targets" which each have their own set of Agents. - WebInspector.Target - has its own list of Agents - has a InspectorBackend.Connection to communicate with the backend - WebInspector.mainTarget - always exists and represents the thing we are debugging (Page or JSContext) - WebInspector.targets / WebInspector.targetManager - management of all Targets - create new Targets for Workers This also slowly introduces the concept that Model objects may be tied to a specific Target: - WebInspector.RemoteObject - in order to evaluate JS and interact with this object we must know the target (Page or Worker) - when fetching PropertyDescriptors and other RemoteObjects we must continue to pass on the target Finally this makes the QuickConsole list Worker execution contexts in the context picker so that users can choose a Worker context and evaluate JavaScript in that context using the console. * Localizations/en.lproj/localizedStrings.js: * UserInterface/Main.html: * UserInterface/Base/Main.js: (WebInspector.loaded): * UserInterface/Test.html: * UserInterface/Test/Test.js: (WebInspector.loaded): New files, strings, and managers. New global WebInspector.mainTarget. New convenience WebInspector.targets. * UserInterface/Protocol/Target.js: Added. (WebInspector.Target): (WebInspector.Target.prototype.get RuntimeAgent): (WebInspector.Target.prototype.get name): (WebInspector.Target.prototype.get type): (WebInspector.Target.prototype.get connection): (WebInspector.Target.prototype.get executionContext): (WebInspector.Target.prototype.get displayName): (WebInspector.Target.prototype._intializeMainTarget): (WebInspector.Target.prototype._initializeNonMainTarget): Target has some basic properties. * UserInterface/Controllers/TargetManager.js: (WebInspector.TargetManager): (WebInspector.TargetManager.prototype.get targets): (WebInspector.TargetManager.prototype.addTarget): (WebInspector.TargetManager.prototype.removeTarget): Holds the list of Targets and events when created / removed. Each target with a RuntimeAgent has an ExecutionContext. * UserInterface/Controllers/WorkerManager.js: (WebInspector.WorkerManager): (WebInspector.WorkerManager.prototype.workerCreated): (WebInspector.WorkerManager.prototype.workerTerminated): (WebInspector.WorkerManager.prototype.dispatchMessageFromWorker): Create / remove / dispatch on a Worker Target. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass): (InspectorBackendClass.prototype.registerCommand): (InspectorBackendClass.prototype.dispatch): (InspectorBackendClass.prototype.runAfterPendingDispatches): (InspectorBackendClass.prototype._agentForDomain): Keep the original implementations and just dispatch to the main connection. (InspectorBackend.Agent): (InspectorBackend.Agent.prototype.get connection): (InspectorBackend.Agent.prototype.set connection): (InspectorBackend.Agent.prototype.get dispatcher): We will share Agent implementations but just give new "copies" a different connection and dispatcher. (InspectorBackend.Command): (InspectorBackend.Command.create): (InspectorBackend.Command.prototype.invoke): (InspectorBackend.Command.prototype.supports): We continue to have a single Command instance on the Agent. However instead of using the hardcoded Agent on the Instance when evaluated as a function it uses the `this` object which should be an agent. This way: target1.RuntimeAgent.evaluate - `this` is target1 and we use the connection for that target target2.RuntimeAgent.evaluate - `this` is target2 and we use the connection for that target Unfortunately this breaks `RuntimeAgent.evaluate.invoke`. Currently this is solved by providing an extra parameter. In the case where we need to invoke on a particular agent we must provide the agent. target.RuntimeAgent.evaluate.invoke({options}, target.RuntimeAgent) This is unfortunate but only needed in a handful of places right now. (InspectorBackendClass.prototype._sendCommandToBackendWithCallback): Deleted. (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise): Deleted. (InspectorBackendClass.prototype._sendMessageToBackend): Deleted. (InspectorBackendClass.prototype._dispatchResponse): Deleted. (InspectorBackendClass.prototype._dispatchResponseToCallback): Deleted. (InspectorBackendClass.prototype._dispatchResponseToPromise): Deleted. (InspectorBackendClass.prototype._dispatchEvent): Deleted. (InspectorBackendClass.prototype._flushPendingScripts): Deleted. (InspectorBackend.Agent.prototype.get currentDispatchState): Deleted. (InspectorBackend.Command.prototype.deliverFailure): Deleted. * UserInterface/Protocol/Connection.js: Added. (InspectorBackend.Connection): (InspectorBackend.Connection.prototype.get target): (InspectorBackend.Connection.prototype.set target): (InspectorBackend.Connection.prototype.dispatch): (InspectorBackend.Connection.prototype.runAfterPendingDispatches): (InspectorBackend.Connection.prototype.sendMessageToBackend): (InspectorBackend.Connection.prototype._dispatchResponse): (InspectorBackend.Connection.prototype._dispatchResponseToCallback): (InspectorBackend.Connection.prototype._dispatchResponseToPromise): (InspectorBackend.Connection.prototype._dispatchEvent): (InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback): (InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise): (InspectorBackend.Connection.prototype._sendMessageToBackend): (InspectorBackend.Connection.prototype._flushPendingScripts): This extracts the Connection details into its own class. Although we make it appear as though a Target has a list of Agents, we actually have the Connection hold the list of Agents. Instead of cloning the entire Agent we just create a new object extended from the original Agent instance. This allows us to keep the same interface but just change the connection / dispatcher properties within the Agent. (InspectorBackend.MainConnection): (InspectorBackend.MainConnection.prototype.sendMessageToBackend): (InspectorBackend.WorkerConnection): (InspectorBackend.WorkerConnection.sendMessageToBackend): Two different kinds of connections. One for the Main connection and one for Workers. Currently the list of agents we expose on a Worker Target/Connection is hardcoded. * UserInterface/Models/ExecutionContext.js: (WebInspector.ExecutionContext): (WebInspector.ExecutionContext.prototype.get target): We may now have ExecutionContexts that mean a Page, Frames, and Workers. To do this we include the (target, executionContextId) tuple in this object. With this we have everything we need to evaluate JavaScript. * UserInterface/Controllers/RuntimeManager.js: (WebInspector.RuntimeManager): (WebInspector.RuntimeManager.prototype.get activeExecutionContext): (WebInspector.RuntimeManager.prototype.set activeExecutionContext): (WebInspector.RuntimeManager.prototype.get defaultExecutionContextIdentifier): Deleted. (WebInspector.RuntimeManager.prototype.set defaultExecutionContextIdentifier): Deleted. Update from contextId to a full ExecutionContext object. (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow.evalCallback): (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow): (WebInspector.RuntimeManager.prototype.saveResult): (WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject): (WebInspector.RuntimeManager.prototype._frameExecutionContextsCleared): * UserInterface/Controllers/FrameResourceManager.js: (WebInspector.FrameResourceManager.prototype.executionContextCreated): * UserInterface/Controllers/JavaScriptLogViewController.js: (WebInspector.JavaScriptLogViewController.prototype.consolePromptShouldCommitText): * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: Anywhere that wants to use the "activeExecutionContext" must use the specific RuntimeAgent tied to that ExecutionContext's Target. * UserInterface/Models/PropertyDescriptor.js: (WebInspector.PropertyDescriptor.fromPayload): * UserInterface/Protocol/RemoteObject.js: (WebInspector.RemoteObject): (WebInspector.RemoteObject.createFakeRemoteObject): (WebInspector.RemoteObject.fromPrimitiveValue): (WebInspector.RemoteObject.fromPayload): (WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors): (WebInspector.RemoteObject.prototype.deprecatedGetDisplayableProperties): (WebInspector.RemoteObject.prototype.setPropertyValue): (WebInspector.RemoteObject.prototype.getCollectionEntries): (WebInspector.RemoteObject.prototype.releaseWeakCollectionEntries): (WebInspector.RemoteObject.prototype.callFunction): (WebInspector.RemoteObject.prototype.callFunctionJSON): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor.wrappedCallback): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor): (WebInspector.RemoteObject.prototype.release): (WebInspector.RemoteObject.prototype._getPropertyDescriptors): (WebInspector.RemoteObject.prototype._getPropertyDescriptorsResolver): (WebInspector.RemoteObject.prototype._deprecatedGetProperties): RemoteObject and related Model Objects now must be tied to a specific Target, because we need to know which Target it belongs to in order to interact with it further. * UserInterface/Views/QuickConsole.js: (WebInspector.QuickConsole): (WebInspector.QuickConsole.prototype.get selectedExecutionContext): (WebInspector.QuickConsole.prototype.set selectedExecutionContext): (WebInspector.QuickConsole.prototype._executionContextPathComponentsToDisplay): (WebInspector.QuickConsole.prototype._rebuildExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._framePageExecutionContextsChanged): (WebInspector.QuickConsole.prototype._frameExecutionContextsCleared): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): (WebInspector.QuickConsole.prototype._compareExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._insertOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._removeOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._insertExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._removeExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._targetAdded): (WebInspector.QuickConsole.prototype._targetRemoved): (WebInspector.QuickConsole.prototype._pathComponentSelected): (WebInspector.QuickConsole.prototype.get selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype.set selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype._defaultExecutionContextChanged): Deleted. Update the code from executionContextId to ExecutionContext objects. Update the picker with ExecutionContextPathComponent for Workers (new Targets). Generalize and cleanup the code to make it easier to follow. LayoutTests: * inspector/unit-tests/target-manager-expected.txt: Added. * inspector/unit-tests/target-manager.html: Added. Unit test for TargetManager and its events with Worker creation. * inspector/worker/resources/worker-1.js: * inspector/worker/runtime-basic-expected.txt: Added. * inspector/worker/runtime-basic.html: Added. Test comparing RuntimeAgent between Main target and Worker target. * inspector/runtime/change-execution-context-identifier-expected.txt: * inspector/runtime/change-execution-context-identifier.html: RuntimeManager has been updated to have a full ExecutionContext object containing a Target + ContextId instead of just a ContextId. * inspector/console/console-api-expected.txt: * inspector/console/console-api.html: * inspector/console/console-table-expected.txt: * inspector/console/console-table.html: * inspector/debugger/tail-deleted-frames-from-vm-entry.html: * inspector/debugger/tail-deleted-frames.html: * inspector/debugger/tail-recursion.html: * inspector/model/remote-object-expected.txt: * inspector/model/remote-object-weak-collection-expected.txt: * inspector/model/remote-object-weak-collection.html: * inspector/model/remote-object.html: * platform/mac/inspector/model/remote-object-expected.txt: Introduce a better JSON Filter for RemoteObject in more tests. It is important that we filter the _target, because otherwise JSON.stringify would throw an error about cycles. Canonical link: https://commits.webkit.org/181797@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208009 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-27 22:19:12 +00:00
<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
let worker;
function createWorker() {
worker = new Worker("../worker/resources/worker-1.js");
}
function terminateWorker() {
worker.terminate();
}
function test()
{
function dumpTargets() {
for (let target of WI.targets)
ServiceWorker Inspector: Frontend changes to support Network tab and sub resources https://bugs.webkit.org/show_bug.cgi?id=179642 <rdar://problem/35517704> Reviewed by Brian Burg. Source/WebInspectorUI: This patch makes use of the NetworkAgent and ServiceWorker agents in the frontend for a ServiceWorker inspection target. It also makes changes to ensure that the subresources requested by a ServiceWorker appear as expected in both the Resources and Network Tabs. The backends of ServiceWorkers and DedicatedWorkers for network requests are different, but we want the presentation to be very similiar. Ultimately we'd like to move to more similiar backends if possible. The first (after Inspector.enable) message a ServiceWorker inspector sends to the backend is ServiceWorker.getInitializationInfo. This parallels a Page inspector sending Page.getResourceTree. From the response we get enough information to setup the MainTarget with enough information (targetId, URL) to know what its main resource URL will be. Like DedicatedWorkers, the target's main resource will be filled in with the first WI.Script matching the URL. With this initialization message alone the ServiceWorker Target behaves almost identically to a Worker target and Network loads associated with the target (by targetId) are added as sub-resources as expected. The biggest tension in this patch is within FrameResourceManager. The class, as its name indicates, assumes page resources with Frames, navigation, and loader semantics. It takes a few modifications to make it better handle resources not associated with a Page. A follow-up will rename this to just ResourceManager as the class' main task is now to associate Resources with Targets. * UserInterface/Base/Main.js: (WI.loaded): There are assumptions in a few places that the main target is a Page. Those places can now be reached when the main target is a ServiceWorker. Add a convenience WI.pageTarget that can be used in these places. * UserInterface/Test/Test.js: (WI.loaded): Add pageTarget. * UserInterface/Controllers/DebuggerManager.js: (WI.DebuggerManager.prototype.scriptDidParse): Generalize the condition so the main target can have its main resource populated. This will be the case when a ServiceWorker is the main target and its main resource needs to be populated from a Script. * UserInterface/Controllers/FrameResourceManager.js: (WI.FrameResourceManager): (WI.FrameResourceManager.prototype._processServiceWorkerInitializationInfo): Handle ServiceWorker Resource initialization which is different from Page initialization. (WI.FrameResourceManager.prototype._addNewResourceToFrameOrTarget): (WI.FrameResourceManager.prototype._addResourceToTarget): (WI.FrameResourceManager.prototype._addFrameTreeFromFrameResourceTreePayload): Eliminate PageAgent, which might not be available in some targets. Use pageTarget instead of mainTarget where appropriate. * UserInterface/Controllers/TargetManager.js: (WI.TargetManager.prototype.targetForIdentifier): A ServiceWorker is the first time that the main target has an identifier, so let TargetManager find it by target id. * UserInterface/Models/Resource.js: (WI.Resource): (WI.Resource.resolvedType): (WI.Resource.prototype.updateForResponse): For Resource.Type.Other resources include a better type inferred from the MIME type. ServiceWorker loads currently don't have type information and this provides a great type for such loads. This should also provide nice types for CacheStorage.add* populated resources which are otherwise type-less fetches. * UserInterface/Protocol/Connection.js: Rename the class since this may no longer be a "Page". * UserInterface/Protocol/MainTarget.js: (WI.MainTarget): (WI.MainTarget.mainConnectionInfo): (WI.MainTarget.prototype.get mainResource): (WI.MainTarget.prototype.set mainResource): (WI.MainTarget.prototype.get displayName): Deleted. * UserInterface/Protocol/Target.js: (WI.Target.prototype.set identifier): (WI.Target.prototype.set name): (WI.Target.prototype.get mainResource): (WI.Target.prototype.set mainResource): (WI.Target.prototype.get displayName): Give richer types for the main target. And allow a few things to be initialized lazily, which will be necessary from an initialization message. * UserInterface/Views/NetworkTabContentView.js: (WI.NetworkTabContentView.isTabAllowed): Remove a PageAgent requirement for the Network tab. A ServiceWorker will not have a PageAgent, but it will have a NetworkAgent, which should be good enough. * UserInterface/Views/NetworkTableContentView.js: (WI.NetworkTableContentView.prototype._populateWithInitialResourcesIfNeeded): Initial populate should populate all subresources of all targets. * UserInterface/Views/ResourceContentView.js: (WI.ResourceContentView.prototype.contentAvailable): This was getting used by ResourceType.Other without warning. Make it warn. * UserInterface/Views/ResourceSidebarPanel.js: (WI.ResourceSidebarPanel.prototype._addScript): (WI.ResourceSidebarPanel.prototype._addTargetWithMainResource): * UserInterface/Views/ScriptTreeElement.js: (WI.ScriptTreeElement): Allow WorkerTreeElements for ServiceWorker targets which may also be the main target. Also when adding such a tree element, promote the resource sidebar to a full tree outline, and stop hiding disclosure buttons. Source/WebInspectorUI/../../LayoutTests: * inspector/unit-tests/target-manager-expected.txt: * inspector/unit-tests/target-manager.html: Generalize. Source/WebInspectorUI/../JavaScriptCore: * inspector/protocol/Network.json: Expose the NetworkAgent for a Service Worker inspector. Canonical link: https://commits.webkit.org/196105@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225244 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-11-28 23:45:01 +00:00
InspectorTest.log(`Target - ${String(target.type)} - ${target.displayName}`);
Web Inspector: Include RuntimeAgent in Workers - evaluate in Worker context https://bugs.webkit.org/show_bug.cgi?id=163835 <rdar://problem/28901465> Reviewed by Brian Burg. Source/WebCore: Tests: inspector/unit-tests/target-manager.html inspector/worker/runtime-basic.html * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * inspector/InspectorAllInOne.cpp: New file. * inspector/InspectorWebAgentBase.h: (WebCore::WorkerAgentContext::WorkerAgentContext): New agent context creation struct for Workers. * inspector/WorkerInspectorController.cpp: (WebCore::WorkerInspectorController::WorkerInspectorController): Create a RuntimeAgent for Workers. * inspector/WorkerRuntimeAgent.cpp: Added. (WebCore::WorkerRuntimeAgent::WorkerRuntimeAgent): (WebCore::WorkerRuntimeAgent::didCreateFrontendAndBackend): (WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend): (WebCore::WorkerRuntimeAgent::injectedScriptForEval): * inspector/WorkerRuntimeAgent.h: Added. Workers currently only ever have a single execution context. Source/WebInspectorUI: This introduces the idea that the frontend may communication with multiple backend "Targets" which each have their own set of Agents. - WebInspector.Target - has its own list of Agents - has a InspectorBackend.Connection to communicate with the backend - WebInspector.mainTarget - always exists and represents the thing we are debugging (Page or JSContext) - WebInspector.targets / WebInspector.targetManager - management of all Targets - create new Targets for Workers This also slowly introduces the concept that Model objects may be tied to a specific Target: - WebInspector.RemoteObject - in order to evaluate JS and interact with this object we must know the target (Page or Worker) - when fetching PropertyDescriptors and other RemoteObjects we must continue to pass on the target Finally this makes the QuickConsole list Worker execution contexts in the context picker so that users can choose a Worker context and evaluate JavaScript in that context using the console. * Localizations/en.lproj/localizedStrings.js: * UserInterface/Main.html: * UserInterface/Base/Main.js: (WebInspector.loaded): * UserInterface/Test.html: * UserInterface/Test/Test.js: (WebInspector.loaded): New files, strings, and managers. New global WebInspector.mainTarget. New convenience WebInspector.targets. * UserInterface/Protocol/Target.js: Added. (WebInspector.Target): (WebInspector.Target.prototype.get RuntimeAgent): (WebInspector.Target.prototype.get name): (WebInspector.Target.prototype.get type): (WebInspector.Target.prototype.get connection): (WebInspector.Target.prototype.get executionContext): (WebInspector.Target.prototype.get displayName): (WebInspector.Target.prototype._intializeMainTarget): (WebInspector.Target.prototype._initializeNonMainTarget): Target has some basic properties. * UserInterface/Controllers/TargetManager.js: (WebInspector.TargetManager): (WebInspector.TargetManager.prototype.get targets): (WebInspector.TargetManager.prototype.addTarget): (WebInspector.TargetManager.prototype.removeTarget): Holds the list of Targets and events when created / removed. Each target with a RuntimeAgent has an ExecutionContext. * UserInterface/Controllers/WorkerManager.js: (WebInspector.WorkerManager): (WebInspector.WorkerManager.prototype.workerCreated): (WebInspector.WorkerManager.prototype.workerTerminated): (WebInspector.WorkerManager.prototype.dispatchMessageFromWorker): Create / remove / dispatch on a Worker Target. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass): (InspectorBackendClass.prototype.registerCommand): (InspectorBackendClass.prototype.dispatch): (InspectorBackendClass.prototype.runAfterPendingDispatches): (InspectorBackendClass.prototype._agentForDomain): Keep the original implementations and just dispatch to the main connection. (InspectorBackend.Agent): (InspectorBackend.Agent.prototype.get connection): (InspectorBackend.Agent.prototype.set connection): (InspectorBackend.Agent.prototype.get dispatcher): We will share Agent implementations but just give new "copies" a different connection and dispatcher. (InspectorBackend.Command): (InspectorBackend.Command.create): (InspectorBackend.Command.prototype.invoke): (InspectorBackend.Command.prototype.supports): We continue to have a single Command instance on the Agent. However instead of using the hardcoded Agent on the Instance when evaluated as a function it uses the `this` object which should be an agent. This way: target1.RuntimeAgent.evaluate - `this` is target1 and we use the connection for that target target2.RuntimeAgent.evaluate - `this` is target2 and we use the connection for that target Unfortunately this breaks `RuntimeAgent.evaluate.invoke`. Currently this is solved by providing an extra parameter. In the case where we need to invoke on a particular agent we must provide the agent. target.RuntimeAgent.evaluate.invoke({options}, target.RuntimeAgent) This is unfortunate but only needed in a handful of places right now. (InspectorBackendClass.prototype._sendCommandToBackendWithCallback): Deleted. (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise): Deleted. (InspectorBackendClass.prototype._sendMessageToBackend): Deleted. (InspectorBackendClass.prototype._dispatchResponse): Deleted. (InspectorBackendClass.prototype._dispatchResponseToCallback): Deleted. (InspectorBackendClass.prototype._dispatchResponseToPromise): Deleted. (InspectorBackendClass.prototype._dispatchEvent): Deleted. (InspectorBackendClass.prototype._flushPendingScripts): Deleted. (InspectorBackend.Agent.prototype.get currentDispatchState): Deleted. (InspectorBackend.Command.prototype.deliverFailure): Deleted. * UserInterface/Protocol/Connection.js: Added. (InspectorBackend.Connection): (InspectorBackend.Connection.prototype.get target): (InspectorBackend.Connection.prototype.set target): (InspectorBackend.Connection.prototype.dispatch): (InspectorBackend.Connection.prototype.runAfterPendingDispatches): (InspectorBackend.Connection.prototype.sendMessageToBackend): (InspectorBackend.Connection.prototype._dispatchResponse): (InspectorBackend.Connection.prototype._dispatchResponseToCallback): (InspectorBackend.Connection.prototype._dispatchResponseToPromise): (InspectorBackend.Connection.prototype._dispatchEvent): (InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback): (InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise): (InspectorBackend.Connection.prototype._sendMessageToBackend): (InspectorBackend.Connection.prototype._flushPendingScripts): This extracts the Connection details into its own class. Although we make it appear as though a Target has a list of Agents, we actually have the Connection hold the list of Agents. Instead of cloning the entire Agent we just create a new object extended from the original Agent instance. This allows us to keep the same interface but just change the connection / dispatcher properties within the Agent. (InspectorBackend.MainConnection): (InspectorBackend.MainConnection.prototype.sendMessageToBackend): (InspectorBackend.WorkerConnection): (InspectorBackend.WorkerConnection.sendMessageToBackend): Two different kinds of connections. One for the Main connection and one for Workers. Currently the list of agents we expose on a Worker Target/Connection is hardcoded. * UserInterface/Models/ExecutionContext.js: (WebInspector.ExecutionContext): (WebInspector.ExecutionContext.prototype.get target): We may now have ExecutionContexts that mean a Page, Frames, and Workers. To do this we include the (target, executionContextId) tuple in this object. With this we have everything we need to evaluate JavaScript. * UserInterface/Controllers/RuntimeManager.js: (WebInspector.RuntimeManager): (WebInspector.RuntimeManager.prototype.get activeExecutionContext): (WebInspector.RuntimeManager.prototype.set activeExecutionContext): (WebInspector.RuntimeManager.prototype.get defaultExecutionContextIdentifier): Deleted. (WebInspector.RuntimeManager.prototype.set defaultExecutionContextIdentifier): Deleted. Update from contextId to a full ExecutionContext object. (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow.evalCallback): (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow): (WebInspector.RuntimeManager.prototype.saveResult): (WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject): (WebInspector.RuntimeManager.prototype._frameExecutionContextsCleared): * UserInterface/Controllers/FrameResourceManager.js: (WebInspector.FrameResourceManager.prototype.executionContextCreated): * UserInterface/Controllers/JavaScriptLogViewController.js: (WebInspector.JavaScriptLogViewController.prototype.consolePromptShouldCommitText): * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: Anywhere that wants to use the "activeExecutionContext" must use the specific RuntimeAgent tied to that ExecutionContext's Target. * UserInterface/Models/PropertyDescriptor.js: (WebInspector.PropertyDescriptor.fromPayload): * UserInterface/Protocol/RemoteObject.js: (WebInspector.RemoteObject): (WebInspector.RemoteObject.createFakeRemoteObject): (WebInspector.RemoteObject.fromPrimitiveValue): (WebInspector.RemoteObject.fromPayload): (WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors): (WebInspector.RemoteObject.prototype.deprecatedGetDisplayableProperties): (WebInspector.RemoteObject.prototype.setPropertyValue): (WebInspector.RemoteObject.prototype.getCollectionEntries): (WebInspector.RemoteObject.prototype.releaseWeakCollectionEntries): (WebInspector.RemoteObject.prototype.callFunction): (WebInspector.RemoteObject.prototype.callFunctionJSON): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor.wrappedCallback): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor): (WebInspector.RemoteObject.prototype.release): (WebInspector.RemoteObject.prototype._getPropertyDescriptors): (WebInspector.RemoteObject.prototype._getPropertyDescriptorsResolver): (WebInspector.RemoteObject.prototype._deprecatedGetProperties): RemoteObject and related Model Objects now must be tied to a specific Target, because we need to know which Target it belongs to in order to interact with it further. * UserInterface/Views/QuickConsole.js: (WebInspector.QuickConsole): (WebInspector.QuickConsole.prototype.get selectedExecutionContext): (WebInspector.QuickConsole.prototype.set selectedExecutionContext): (WebInspector.QuickConsole.prototype._executionContextPathComponentsToDisplay): (WebInspector.QuickConsole.prototype._rebuildExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._framePageExecutionContextsChanged): (WebInspector.QuickConsole.prototype._frameExecutionContextsCleared): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): (WebInspector.QuickConsole.prototype._compareExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._insertOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._removeOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._insertExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._removeExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._targetAdded): (WebInspector.QuickConsole.prototype._targetRemoved): (WebInspector.QuickConsole.prototype._pathComponentSelected): (WebInspector.QuickConsole.prototype.get selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype.set selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype._defaultExecutionContextChanged): Deleted. Update the code from executionContextId to ExecutionContext objects. Update the picker with ExecutionContextPathComponent for Workers (new Targets). Generalize and cleanup the code to make it easier to follow. LayoutTests: * inspector/unit-tests/target-manager-expected.txt: Added. * inspector/unit-tests/target-manager.html: Added. Unit test for TargetManager and its events with Worker creation. * inspector/worker/resources/worker-1.js: * inspector/worker/runtime-basic-expected.txt: Added. * inspector/worker/runtime-basic.html: Added. Test comparing RuntimeAgent between Main target and Worker target. * inspector/runtime/change-execution-context-identifier-expected.txt: * inspector/runtime/change-execution-context-identifier.html: RuntimeManager has been updated to have a full ExecutionContext object containing a Target + ContextId instead of just a ContextId. * inspector/console/console-api-expected.txt: * inspector/console/console-api.html: * inspector/console/console-table-expected.txt: * inspector/console/console-table.html: * inspector/debugger/tail-deleted-frames-from-vm-entry.html: * inspector/debugger/tail-deleted-frames.html: * inspector/debugger/tail-recursion.html: * inspector/model/remote-object-expected.txt: * inspector/model/remote-object-weak-collection-expected.txt: * inspector/model/remote-object-weak-collection.html: * inspector/model/remote-object.html: * platform/mac/inspector/model/remote-object-expected.txt: Introduce a better JSON Filter for RemoteObject in more tests. It is important that we filter the _target, because otherwise JSON.stringify would throw an error about cycles. Canonical link: https://commits.webkit.org/181797@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208009 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-27 22:19:12 +00:00
}
let suite = InspectorTest.createAsyncSuite("TargetManager");
suite.addTestCase({
name: "TargetManager.MainTarget",
description: "We should always have the main target.",
Web Inspector: Support `async test() { ... }` in Inspector Test Suites https://bugs.webkit.org/show_bug.cgi?id=178614 Patch by Joseph Pecoraro <pecoraro@apple.com> on 2017-10-20 Reviewed by Devin Rousso. Add the ability to have test functions be async functions. A successful async test function just needs to complete evaluation. To indicate failure it should throw an exception. suite.addTestCase({ name: "ExceptionOfNormal", async test() { InspectorTest.expectThat(...); } }); suite.addTestCase({ name: "ExampleOfRejection", async test() { let value = await SomeAgent.method(); if (value.error) throw "Exception"; ... } }); Using async test functions has the added benefit that a runtime exception inside of asynchronous test code will reject the current test case instead of timing out. For example... suite.addTestCase({ name: "ExampleOfRejectionThroughRuntimeException", async test() { let arr = []; arr.this.does.not.exist; } }); ... should will lead to a failure instead of a timeout. This should allow us to structure some common tests more naturally, like so: suite.addTestCase({ name: "ExampleOfNormalAsyncTest", async test() { InspectorTest.evaluateInPage(`...`); let event = await WI.Manager.awaitEvent(...); let resource = event.data.resource; InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); } }); * inspector/unit-tests/async-test-suite-expected.txt: * inspector/unit-tests/async-test-suite.html: * inspector/unit-tests/target-manager.html: Canonical link: https://commits.webkit.org/194811@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-21 06:52:47 +00:00
async test() {
InspectorTest.assert(WI.targets === WI.targetManager.targets);
Web Inspector: Keep Web Inspector window alive across process swaps (PSON) (Remote Inspector) https://bugs.webkit.org/show_bug.cgi?id=191494 <rdar://problem/45469854> Reviewed by Devin Rousso. Source/JavaScriptCore: * CMakeLists.txt: * DerivedSources.make: * JavaScriptCore.xcodeproj/project.pbxproj: * Sources.txt: New domain and resources. * inspector/protocol/Target.json: Added. New protocol domain, modeled after Worker.json, to allow for multiplexing between different targets. * inspector/InspectorTarget.h: Each target will instantiate an InspectorTarget and must provide an identifier, type, and means of connecting/disconnecting to a frontend channel. * inspector/agents/InspectorTargetAgent.cpp: Added. (Inspector::InspectorTargetAgent::InspectorTargetAgent): (Inspector::InspectorTargetAgent::didCreateFrontendAndBackend): (Inspector::InspectorTargetAgent::willDestroyFrontendAndBackend): (Inspector::InspectorTargetAgent::exists): (Inspector::InspectorTargetAgent::initialized): (Inspector::InspectorTargetAgent::sendMessageToTarget): (Inspector::InspectorTargetAgent::sendMessageFromTargetToFrontend): (Inspector::targetTypeToProtocolType): (Inspector::buildTargetInfoObject): (Inspector::InspectorTargetAgent::targetCreated): (Inspector::InspectorTargetAgent::targetTerminated): (Inspector::InspectorTargetAgent::connectToTargets): (Inspector::InspectorTargetAgent::disconnectFromTargets): * inspector/agents/InspectorTargetAgent.h: Added. TargetAgent holds a list of targets, and connects/disconnects to each of the targets when a frontend connects/disconnects. * inspector/scripts/codegen/generator.py: Better enum casing of ServiceWorker. Source/WebCore: * inspector/InspectorClient.h: (WebCore::InspectorClient::allowRemoteInspectionToPageDirectly const): Provide a hook so that a client may wish to allow direct remote inspection of the Page. This is used by WebKitLegacy only. * page/Page.cpp: (Page::Page): Only enable the PageDebuggable if the client wishes remote inspection of the Page directly. This is used by WebKitLegacy only. * inspector/InspectorController.cpp: (WebCore::InspectorController::connectFrontend): * inspector/InspectorController.h: * page/PageDebuggable.cpp: (WebCore::PageDebuggable::connect): (WebCore::PageDebuggable::disconnect): * page/PageDebuggable.h: When a frontend connects, always enable the developer extras for the Page. This is pretty much only for the remote path, which allows inspection if developer extras were not already enabled (iOS). This simplifies the logic, and toggling developer extras after it was already enabled is not really important. Source/WebInspectorUI: This starts introducing multi-target support into the Web Inspector frontend. Specifically a backend connection that is persistent, but has the ability to connect to and transition between Page targets received through that backend connection. This patch introduces the concept of a "Backend Target" which is the single connection that the frontend contains to a backend. The old way of connecting directly to a target is still supported. In that case the frontend constructs a DirectBackendTarget for the debuggable type the frontend was spawns for. However, if the frontend opens and has a TargetAgent, then it is likely connected to a multi-target supporting backend and instead constructs a MultiplexingBackendTarget, and will receive further information about sub-targets to connect to. The only sub-target at the moment is a Page sub-target. As part of bringing up multi-target support this adds a few measures to handle situations where the frontend is playing fast and loose with agents. When the frontend does `FooAgent.method` it intends that to be performed on the "main" target being debugged. Likewise when the frontend loops over targets it expects them to be the debuggable targets. This patch profiles a new implementation of `WI.mainTarget` and `WI.targets` to match the assumptions being made by the frontend. - In a direct-target world, there is a single target which should be used for global agents and in WI.targets. - In a multi-target world, the page target is the one that should be used for global agents and WI.targets is the list of sub-targets (excluding the MultiplexingBackendTarget). In a multi-target world, there are now commonly two Targets. The MultiplexingBackendTarget and a PageTarget sub-target. In the future this may include more targets, such as ServiceWorkers, DedicatedWorkers, and perhaps even frames. In a multi-target world, the frontend is immediately told about targets as soon as it opens (via Target.targetCreated). In order to support this, frontend initialization happens without a main target being available. So this makes a few small changes to frontend initialization to perform a bit of work once we know what the main target is. During a page transition the frontend is told to destroy existing targets and is soon after told about any new page targets (via Target.targetDestroyed and Target.targetCreated). The frontend special cases this page transition. It expects only one Page target to be alive at any time, accessible through WI.pageTarget. When a page transition happens the WI.pageTarget changes, and the frontend performs a bit of work to prepare the UI to handle the transition: `<Manager>.transitionPageTarget` / WI.Notification.TransitionPageTarget. For the most part the UI behaves fine as long once there are main frame change and main resource change events, but those other events allow the frontend to respond to the specific page transition cases. * UserInterface/Base/Main.js: (WI.loaded): (WI.initializeBackendTarget): (WI.initializePageTarget): (WI.transitionPageTarget): (WI.terminatePageTarget): (WI.resetMainExecutionContext): (WI.redirectGlobalAgentsToConnection): (WI.contentLoaded): New global functions for target initialization and page transitioning. * UserInterface/Test/Test.js: (WI.loaded): (WI.initializeBackendTarget): (WI.initializePageTarget): (WI.transitionPageTarget): (WI.terminatePageTarget): (WI.resetMainExecutionContext): (WI.redirectGlobalAgentsToConnection): New global functions for target initialization. Tests continue to be a direct connection to the Page. * UserInterface/Protocol/TargetObserver.js: (WI.TargetObserver.prototype.targetCreated): (WI.TargetObserver.prototype.targetDestroyed): (WI.TargetObserver.prototype.dispatchMessageFromTarget): New observer goes to the manager. * UserInterface/Controllers/TargetManager.js: (WI.TargetManager): (WI.TargetManager.prototype.get targets): (WI.TargetManager.prototype.get allTargets): (WI.TargetManager.prototype.targetForIdentifier): (WI.TargetManager.prototype.targetCreated): (WI.TargetManager.prototype.targetDestroyed): (WI.TargetManager.prototype.dispatchMessageFromTarget): (WI.TargetManager.prototype.createMultiplexingBackendTarget): (WI.TargetManager.prototype.createDirectBackendTarget): (WI.TargetManager.prototype._addTarget): (WI.TargetManager.prototype._removeTarget): (WI.TargetManager.prototype._createTarget): (WI.TargetManager.prototype._checkAndHandlePageTargetTransition): (WI.TargetManager.prototype._checkAndHandlePageTargetTermination): (WI.TargetManager.prototype.addTarget): Deleted. (WI.TargetManager.prototype.removeTarget): Deleted. (WI.TargetManager.prototype.initializeMainTarget): Deleted. TargetManager is where we handle creating and destroying targets and their connections. In order to simplify things a bit we make `WI.targets`, which goes through `get targets()` an array instead of a Set. And this includes only the sub-targets. * UserInterface/Controllers/WorkerManager.js: (WI.WorkerManager.prototype.workerCreated): (WI.WorkerManager.prototype.workerTerminated): Workers are still special-target-like things that multiplex through WorkerAgent instead of TargetAgent. We'd like to promote these to be full targets in the future. * UserInterface/Protocol/DirectBackendTarget.js: Renamed from Source/WebInspectorUI/UserInterface/Protocol/MainTarget.js. (WI.DirectBackendTarget): (WI.DirectBackendTarget.connectionInfoForDebuggable): (WI.DirectBackendTarget.prototype.get mainResource): (WI.DirectBackendTarget.prototype.set mainResource): This is the only "MainTarget" class. It is the backend target for a direct connection. * UserInterface/Protocol/MultiplexingBackendTarget.js: (WI.MultiplexingBackendTarget): (WI.MultiplexingBackendTarget.prototype.initialize): (WI.MultiplexingBackendTarget.prototype.get name): (WI.MultiplexingBackendTarget.prototype.get executionContext): (WI.MultiplexingBackendTarget.prototype.get mainResource): This is the new backend target for a multi-target connection. We don't expect it to be treated like other targets, so we don't expect anyone to ask it for resources/executionContext/name info. * UserInterface/Controllers/RuntimeManager.js: (WI.TargetManager.prototype.evaluateInInspectedWindow): This can be triggered by watch expressions before any target, and therefore execution context, is available. Just return null, when an execution context is available those clients will try again. * UserInterface/Debug/Bootstrap.js: Provide an WI.isEngineeringBuild boolean that can be used for various debugging features. * UserInterface/Main.html: * UserInterface/Test.html: New resources. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass.prototype.dispatch): (InspectorBackendClass.prototype.runAfterPendingDispatches): (InspectorBackend.Agent): `InspectorBackend.mainConnection` was renamed `InspectorBackend.backendConnection`. * UserInterface/Protocol/Connection.js: (InspectorBackend.Connection): (InspectorBackend.Connection.prototype._dispatchResponse): (InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback): (InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise): (InspectorBackend.BackendConnection): (InspectorBackend.BackendConnection.prototype.sendMessageToBackend): (InspectorBackend.WorkerConnection): (InspectorBackend.TargetConnection): (InspectorBackend.TargetConnection.sendMessageToBackend): Use a global sequence id to make filtering a bit easier in protocol tracing. TargetConnection is identical to WorkerConnection except it uses TargetAgent instead of WorkerAgent to perform multiplexing. * UserInterface/Protocol/JavaScriptContextTarget.js: (WI.JavaScriptContextTarget): * UserInterface/Protocol/PageTarget.js: (WI.PageTarget): (WI.PageTarget.prototype.get displayName): Specialized target types. * UserInterface/Views/DebuggerSidebarPanel.js: (WI.DebuggerSidebarPanel): (WI.DebuggerSidebarPanel.prototype._targetAdded): (WI.DebuggerSidebarPanel.prototype._targetRemoved): (WI.DebuggerSidebarPanel.prototype._updateCallStackTreeOutline): * UserInterface/Views/SourceCodeTextEditor.js: (WI.SourceCodeTextEditor.prototype._targetAdded): (WI.SourceCodeTextEditor.prototype._targetRemoved): (WI.SourceCodeTextEditor.prototype._callFramesDidChange): (WI.SourceCodeTextEditor.prototype._updateThreadIndicatorWidget): (WI.SourceCodeTextEditor.prototype._reinsertAllThreadIndicators): * UserInterface/Views/QuickConsole.js: (WI.QuickConsole.prototype.initializeMainExecutionContextPathComponent): (WI.QuickConsole.prototype._targetAdded): (WI.QuickConsole.prototype._targetRemoved): We make target added get called with all targets, including the MultiplexingBackendTarget and PageTargets, both of which would not have happened before. Before it was only WorkerTargets. Make these sites a little more robust for the type of target they expect to be able to handle. * UserInterface/Base/Object.js: * UserInterface/Controllers/DOMManager.js: (WI.DOMManager): (WI.DOMManager.prototype.transitionPageTarget): (WI.DOMManager.prototype.requestDocument): (WI.DOMManager.prototype._setDocument): * UserInterface/Controllers/NetworkManager.js: (WI.NetworkManager): (WI.NetworkManager.prototype.transitionPageTarget): (WI.NetworkManager.prototype.executionContextCreated): (WI.NetworkManager.prototype._processMainFrameResourceTreePayload): * UserInterface/Models/DefaultDashboard.js: (WI.DefaultDashboard): (WI.DefaultDashboard.prototype._mainResourceDidChange): (WI.DefaultDashboard.prototype._transitionPageTarget): * UserInterface/Views/NetworkTableContentView.js: (WI.NetworkTableContentView): (WI.NetworkTableContentView.prototype._mainResourceDidChange): (WI.NetworkTableContentView.prototype._transitionPageTarget): Special case handling when performing a page transition. * UserInterface/Views/SettingsTabContentView.js: * UserInterface/Debug/UncaughtExceptionReporter.js: Document reloads are not supported right now. Source/WebKit: To support process swapping a slim Web Inspector backend lives in the UIProcess. The Web Inspector frontend connects to it and is told about sub-targets, namely pages, that it can further connect to. When performing a process swap the backend tells the frontend to destroy existing targets and create new targets. In the UIProcess the WebPageProxy has a WebPageInspectorController, with a single TargetAgent holding InspectorTargetProxies to targets it knows about. Inspector protocol messages go through this inspector controller and are routed to the WebPage and its WebCore::Page's InspectorController. The WebPageProxy decides when to close and expose new page targets during process swap, or basically any time it reconnects to a WebProcess. So this patch also makes Web Inspector stay alive and reconnect to a page when the inspected page crashes! In the WebContentProcess the WebPage has a WebPageInspectorTarget. It also has a WebPageInspectorTargetController in anticipation of further sub-targets within the page (workers, frames) but none exist at the moment. The WebPage relies on the WebPageProxy to know when to expose this target as a debuggable. * Sources.txt: * WebKit.xcodeproj/project.pbxproj: New files. * Shared/WebPageCreationParameters.cpp: (WebKit::WebPageCreationParameters::encode const): (WebKit::WebPageCreationParameters::decode): * Shared/WebPageCreationParameters.h: Remote inspector state can now stay in the UIProcess and does not need to be passed down to the WebContentProcess. * UIProcess/WebPageDebuggable.cpp: Copied from Source/WebCore/page/PageDebuggable.cpp. (WebKit::WebPageDebuggable::WebPageDebuggable): (WebKit::WebPageDebuggable::name const): (WebKit::WebPageDebuggable::url const): (WebKit::WebPageDebuggable::hasLocalDebugger const): (WebKit::WebPageDebuggable::connect): (WebKit::WebPageDebuggable::disconnect): (WebKit::WebPageDebuggable::dispatchMessageFromRemote): (WebKit::WebPageDebuggable::setIndicating): (WebKit::WebPageDebuggable::setNameOverride): * UIProcess/WebPageDebuggable.h: Copied from Source/WebCore/page/PageDebuggable.h. Remote debuggable entry point into the UIProcess for a page. This is pretty much identical to the PageDebuggable in WebCore. * Scripts/webkit/messages.py: * UIProcess/WebPageProxy.messages.in: * UIProcess/WebPageProxy.cpp: (WebKit::m_resetRecentCrashCountTimer): (WebKit::WebPageProxy::finishAttachingToWebProcess): (WebKit::WebPageProxy::close): (WebKit::WebPageProxy::createInspectorTarget): (WebKit::WebPageProxy::destroyInspectorTarget): (WebKit::WebPageProxy::sendMessageToInspectorFrontend): (WebKit::WebPageProxy::setIndicating): (WebKit::WebPageProxy::allowsRemoteInspection const): (WebKit::WebPageProxy::setAllowsRemoteInspection): (WebKit::WebPageProxy::remoteInspectionNameOverride const): (WebKit::WebPageProxy::setRemoteInspectionNameOverride): (WebKit::WebPageProxy::remoteInspectorInformationDidChange): (WebKit::WebPageProxy::clearInspectorTargets): (WebKit::WebPageProxy::createInspectorTargets): (WebKit::WebPageProxy::didCommitLoadForFrame): (WebKit::WebPageProxy::didReceiveTitleForFrame): (WebKit::WebPageProxy::creationParameters): * UIProcess/WebPageProxy.h: (WebKit::WebPageProxy::inspectorController): (WebKit::WebPageProxy::allowsRemoteInspection const): Deleted. (WebKit::WebPageProxy::remoteInspectionNameOverride const): Deleted. Own more inspector state in the UIProcess including a debuggable and inspector controller. * UIProcess/WebPageInspectorController.h: Added. * UIProcess/WebPageInspectorController.cpp: Added. (WebKit::WebPageInspectorController::WebPageInspectorController): (WebKit::WebPageInspectorController::pageClosed): (WebKit::WebPageInspectorController::hasLocalFrontend const): (WebKit::WebPageInspectorController::hasRemoteFrontend const): (WebKit::WebPageInspectorController::connectFrontend): (WebKit::WebPageInspectorController::disconnectFrontend): (WebKit::WebPageInspectorController::disconnectAllFrontends): (WebKit::WebPageInspectorController::dispatchMessageFromFrontend): (WebKit::WebPageInspectorController::setIndicating): (WebKit::WebPageInspectorController::clearTargets): (WebKit::WebPageInspectorController::createInspectorTarget): (WebKit::WebPageInspectorController::destroyInspectorTarget): (WebKit::WebPageInspectorController::sendMessageToInspectorFrontend): InspectorController with a single TargetAgent in the UIProcess. * UIProcess/WebPageInspectorTargetAgent.h: * UIProcess/WebPageInspectorTargetAgent.cpp: (WebKit::WebPageInspectorTargetAgent::WebPageInspectorTargetAgent): (WebKit::WebPageInspectorTargetAgent::frontendChannel): Target agent implementation. * UIProcess/InspectorTargetProxy.cpp: (WebKit::InspectorTargetProxy::create): (WebKit::InspectorTargetProxy::InspectorTargetProxy): (WebKit::InspectorTargetProxy::connect): (WebKit::InspectorTargetProxy::disconnect): (WebKit::InspectorTargetProxy::sendMessageToTargetBackend): * UIProcess/InspectorTargetProxy.h: UIProcess proxy for an InspectorTarget in the WebContentProcess. * UIProcess/WebProcessPool.cpp: (WebKit::WebProcessPool::processForNavigationInternal): * WebProcess/WebPage/WebPage.cpp: (WebKit::m_shouldAttachDrawingAreaOnPageTransition): (WebKit::WebPage::connectInspector): (WebKit::WebPage::disconnectInspector): (WebKit::WebPage::sendMessageToTargetBackend): (WebKit::WebPage::setIndicating): (WebKit::WebPage::setAllowsRemoteInspection): Deleted. (WebKit::WebPage::setRemoteInspectionNameOverride): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * WebProcess/WebPage/WebPageInspectorTarget.h: * WebProcess/WebPage/WebPageInspectorTarget.cpp: (WebKit::WebPageInspectorTarget::WebPageInspectorTarget): (WebKit::WebPageInspectorTarget::identifier const): (WebKit::WebPageInspectorTarget::connect): (WebKit::WebPageInspectorTarget::disconnect): (WebKit::WebPageInspectorTarget::sendMessageToTargetBackend): InspectorTarget for this WebPage. * WebProcess/WebPage/WebPageInspectorTargetController.cpp: Added. (WebKit::WebPageInspectorTargetController::WebPageInspectorTargetController): (WebKit::WebPageInspectorTargetController::~WebPageInspectorTargetController): (WebKit::WebPageInspectorTargetController::addTarget): (WebKit::WebPageInspectorTargetController::removeTarget): (WebKit::WebPageInspectorTargetController::connectInspector): (WebKit::WebPageInspectorTargetController::disconnectInspector): (WebKit::WebPageInspectorTargetController::sendMessageToTargetBackend): (WebKit::WebPageInspectorTargetController::sendMessageToTargetFrontend): * WebProcess/WebPage/WebPageInspectorTargetController.h: * WebProcess/WebPage/WebPageInspectorTargetFrontendChannel.h: * WebProcess/WebPage/WebPageInspectorTargetFrontendChannel.cpp: (WebKit::WebPageInspectorTargetFrontendChannel::create): (WebKit::WebPageInspectorTargetFrontendChannel::WebPageInspectorTargetFrontendChannel): (WebKit::WebPageInspectorTargetFrontendChannel::sendMessageToFrontend): Preparation for more target managment in the WebContentProcess. Source/WebKitLegacy/mac: * WebCoreSupport/WebInspectorClient.h: WebKitLegacy will still have remote inspection of the Page directly. LayoutTests: * inspector/unit-tests/target-manager.html: WI.targets has switched to being an array instead of a set. Canonical link: https://commits.webkit.org/206396@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238192 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-14 21:03:49 +00:00
InspectorTest.expectEqual(WI.targets.length, 1, "Targets list should always start out with the main target.");
InspectorTest.expectEqual([...WI.targets][0], WI.mainTarget, "Target list should always contain the main target.");
InspectorTest.expectNotNull(WI.mainTarget.executionContext, "Main target should have an ExecutionContext.");
Web Inspector: Keep Web Inspector window alive across process swaps (PSON) (Local Inspector) https://bugs.webkit.org/show_bug.cgi?id=191740 <rdar://problem/45470897> Reviewed by Timothy Hatcher. Source/JavaScriptCore: * inspector/InspectorFrontendChannel.h: Expose EnumTraits for ConnectionType for WebKit IPC messages. Source/WebInspectorUI: * UserInterface/Protocol/Connection.js: (InspectorBackend.Connection.prototype._dispatchResponse): Hide the TargetAgent does not exist message. This is necessary so that WebKitLegacy tests don't include this line in output each test. * UserInterface/Test.html: * UserInterface/Test/Test.js: (WI.loaded): (WI.resetMainExecutionContext): (WI.performOneTimeFrontendInitializationsUsingTarget): Behave more like Main.js and initialize a MultiplexingBackendTarget when the TargetAgent is available. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass.prototype.runAfterPendingDispatches): Use the main target, a.k.a. the page connection. The backend target's messages don't have any responses, so this was effectively not waiting at all. Source/WebKit: When a web page asks to open a local Web Inspector, that inspector will now connect in the UIProcess (WebPageProxy / WebPageInspectorController) instead of the WebContentProcess (WebKit::WebInspector / InspectorController). Previously a WebInspectorProxy was re-created every time the WebPageProxy's WebPage / WebProcess was changed, effectively closing the Web Inspector frontend when the WebPage was swapped or crashed. This change keeps the WebInspectorProxy alive as long as the WebPageProxy is alive. During process swaps, or process crashes, the WebInspectorProxy is reset when the page is reset and updated when the page's WebProcess changes. Since WebInspectorProxy owns the Web Inspector view / window the Web Inspector window can be kept alive across (and attached state) across WebPage / WebProcess changes. Previously the WebContentProcess's WebKit::WebInspector was the Local FrontendChannel for the WebCore::InspectorController. This can't outlive the single WebContentProcess. This change makes the UIProcesses' WebInspectorProxy the Local FrontendChannel for the WebKit::WebPageInspectorController. Given the WebInspectorProxy now stays alive alongside the WebPageProxy this will live across process changes. This means that the WebInspectorUI process must send its backend messages to the WebInspectorProxy -> WebPageInspectorController now instead of the old path WebInspector -> WebCore::InspectorController. A direct IPC connection is still maintained between the WebContentProcess's WebKit::WebInspector and the InspectorProcess's WebInspectorUI. Previously this connection was established by WebKit::WebInspector vending an IPC::Attachment to the WebInspectorUI process. This patch inverts that relationship, because the WebInspectorUI process now lives across multiple WebContentProcess changes. The WebInspectorUI now vends the IPC::Attachment to the WebContentProcess each time the process changes. This way they can both still communicate through normal Messages::WebInspector/WebInspectorUI messages and everything behaves as previously expected. * Scripts/webkit/messages.py: Header for Inspector::FrontendChannel::ConnectionType. * WebProcess/WebCoreSupport/WebInspectorClient.cpp: (WebKit::WebInspectorClient::openLocalFrontend): * WebProcess/WebPage/WebInspector.cpp: (WebKit::WebInspector::openLocalInspectorFrontend): (WebKit::WebInspector::setFrontendConnection): (WebKit::WebInspector::closeFrontendConnection): (WebKit::WebInspector::close): (WebKit::WebInspector::openFrontendConnection): Deleted. (WebKit::WebInspector::sendMessageToBackend): Deleted. (WebKit::WebInspector::sendMessageToFrontend): Deleted. On the WebProcess side we ask the UIProcess to open a local frontend and now receive instead of vend an IPC connection to the WebInspectorUI process. * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::finishAttachingToWebProcess): (WebKit::WebPageProxy::close): (WebKit::WebPageProxy::resetState): Keep the WebInspectorProxy alive alongside the WebPageProxy. Update it as processes / states change. * UIProcess/WebInspectorProxy.h: * UIProcess/WebInspectorProxy.messages.in: * UIProcess/WebInspectorProxy.cpp: (WebKit::WebInspectorProxy::openLocalInspectorFrontend): (WebKit::WebInspectorProxy::createInspectorPage): Deleted. (WebKit::WebInspectorProxy::sendMessageToFrontend): (WebKit::WebInspectorProxy::closeFrontendPageAndWindow): Open and close a local frontend by being the FrontendChannel on the UIProcess side. (WebKit::WebInspectorProxy::sendMessageToBackend): Dispatch WebInspectorUI backend messages to the UIProcess's InspectorController now that the InspectorController is here instead of in the WebProcess. (WebKit::WebInspectorProxy::setFrontendConnection): Transfer the WebProcess <-> InspectorProcess IPC connection through us because we are the one link between them when processes change. (WebKit::WebInspectorProxy::invalidate): (WebKit::WebInspectorProxy::frontendLoaded): Be safer and handle inspectedPage being potentially null. * WebProcess/WebPage/WebPageInspectorTargetController.cpp: (WebKit::WebPageInspectorTargetController::connectInspector): * WebProcess/WebPage/WebPageInspectorTargetController.h: * WebProcess/WebPage/WebPageInspectorTargetFrontendChannel.cpp: (WebKit::WebPageInspectorTargetFrontendChannel::create): (WebKit::WebPageInspectorTargetFrontendChannel::WebPageInspectorTargetFrontendChannel): * WebProcess/WebPage/WebPageInspectorTargetFrontendChannel.h: * UIProcess/InspectorTargetProxy.cpp: (WebKit::InspectorTargetProxy::connect): Proxy the ConnectionType received on the UIProcess side to the WebProcess side when connecting to sub-targets. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::connectInspector): (WebKit::WebPage::setHasLocalInspectorFrontend): Deleted. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/WebPage.messages.in: * UIProcess/WebPageProxy.h: (WebKit::WebPageProxy::hasLocalInspectorFrontend const): Deleted. (WebKit::WebPageProxy::setHasLocalInspectorFrontend): Deleted. * UIProcess/WebPageProxy.messages.in: * UIProcess/WebProcessPool.cpp: (WebKit::WebProcessPool::processForNavigationInternal): Eliminate the hasLocalInspectorFrontend state that was only used to disable PSON. PSON no longer needs to be disabled for this reason. * WebProcess/WebPage/WebInspector.h: * WebProcess/WebPage/WebInspector.messages.in: * WebProcess/WebPage/WebInspectorUI.cpp: (WebKit::WebInspectorUI::establishConnection): (WebKit::WebInspectorUI::updateConnection): (WebKit::WebInspectorUI::closeWindow): (WebKit::WebInspectorUI::sendMessageToBackend): * WebProcess/WebPage/WebInspectorUI.h: * WebProcess/WebPage/WebInspectorUI.messages.in: Vend an IPC connection on demand to the WebProcess side. LayoutTests: * inspector/unit-tests/target-manager-expected.txt: * inspector/unit-tests/target-manager.html: Update test to pass in both a MultiplexingBackendTarget and DirectBackendTarget world. Canonical link: https://commits.webkit.org/206509@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238330 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-11-17 01:28:41 +00:00
InspectorTest.expectEqual(WI.mainTarget.RuntimeAgent, WI.pageTarget.RuntimeAgent, "Main target should have the page target's RuntimeAgent.");
Web Inspector: Include RuntimeAgent in Workers - evaluate in Worker context https://bugs.webkit.org/show_bug.cgi?id=163835 <rdar://problem/28901465> Reviewed by Brian Burg. Source/WebCore: Tests: inspector/unit-tests/target-manager.html inspector/worker/runtime-basic.html * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * inspector/InspectorAllInOne.cpp: New file. * inspector/InspectorWebAgentBase.h: (WebCore::WorkerAgentContext::WorkerAgentContext): New agent context creation struct for Workers. * inspector/WorkerInspectorController.cpp: (WebCore::WorkerInspectorController::WorkerInspectorController): Create a RuntimeAgent for Workers. * inspector/WorkerRuntimeAgent.cpp: Added. (WebCore::WorkerRuntimeAgent::WorkerRuntimeAgent): (WebCore::WorkerRuntimeAgent::didCreateFrontendAndBackend): (WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend): (WebCore::WorkerRuntimeAgent::injectedScriptForEval): * inspector/WorkerRuntimeAgent.h: Added. Workers currently only ever have a single execution context. Source/WebInspectorUI: This introduces the idea that the frontend may communication with multiple backend "Targets" which each have their own set of Agents. - WebInspector.Target - has its own list of Agents - has a InspectorBackend.Connection to communicate with the backend - WebInspector.mainTarget - always exists and represents the thing we are debugging (Page or JSContext) - WebInspector.targets / WebInspector.targetManager - management of all Targets - create new Targets for Workers This also slowly introduces the concept that Model objects may be tied to a specific Target: - WebInspector.RemoteObject - in order to evaluate JS and interact with this object we must know the target (Page or Worker) - when fetching PropertyDescriptors and other RemoteObjects we must continue to pass on the target Finally this makes the QuickConsole list Worker execution contexts in the context picker so that users can choose a Worker context and evaluate JavaScript in that context using the console. * Localizations/en.lproj/localizedStrings.js: * UserInterface/Main.html: * UserInterface/Base/Main.js: (WebInspector.loaded): * UserInterface/Test.html: * UserInterface/Test/Test.js: (WebInspector.loaded): New files, strings, and managers. New global WebInspector.mainTarget. New convenience WebInspector.targets. * UserInterface/Protocol/Target.js: Added. (WebInspector.Target): (WebInspector.Target.prototype.get RuntimeAgent): (WebInspector.Target.prototype.get name): (WebInspector.Target.prototype.get type): (WebInspector.Target.prototype.get connection): (WebInspector.Target.prototype.get executionContext): (WebInspector.Target.prototype.get displayName): (WebInspector.Target.prototype._intializeMainTarget): (WebInspector.Target.prototype._initializeNonMainTarget): Target has some basic properties. * UserInterface/Controllers/TargetManager.js: (WebInspector.TargetManager): (WebInspector.TargetManager.prototype.get targets): (WebInspector.TargetManager.prototype.addTarget): (WebInspector.TargetManager.prototype.removeTarget): Holds the list of Targets and events when created / removed. Each target with a RuntimeAgent has an ExecutionContext. * UserInterface/Controllers/WorkerManager.js: (WebInspector.WorkerManager): (WebInspector.WorkerManager.prototype.workerCreated): (WebInspector.WorkerManager.prototype.workerTerminated): (WebInspector.WorkerManager.prototype.dispatchMessageFromWorker): Create / remove / dispatch on a Worker Target. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass): (InspectorBackendClass.prototype.registerCommand): (InspectorBackendClass.prototype.dispatch): (InspectorBackendClass.prototype.runAfterPendingDispatches): (InspectorBackendClass.prototype._agentForDomain): Keep the original implementations and just dispatch to the main connection. (InspectorBackend.Agent): (InspectorBackend.Agent.prototype.get connection): (InspectorBackend.Agent.prototype.set connection): (InspectorBackend.Agent.prototype.get dispatcher): We will share Agent implementations but just give new "copies" a different connection and dispatcher. (InspectorBackend.Command): (InspectorBackend.Command.create): (InspectorBackend.Command.prototype.invoke): (InspectorBackend.Command.prototype.supports): We continue to have a single Command instance on the Agent. However instead of using the hardcoded Agent on the Instance when evaluated as a function it uses the `this` object which should be an agent. This way: target1.RuntimeAgent.evaluate - `this` is target1 and we use the connection for that target target2.RuntimeAgent.evaluate - `this` is target2 and we use the connection for that target Unfortunately this breaks `RuntimeAgent.evaluate.invoke`. Currently this is solved by providing an extra parameter. In the case where we need to invoke on a particular agent we must provide the agent. target.RuntimeAgent.evaluate.invoke({options}, target.RuntimeAgent) This is unfortunate but only needed in a handful of places right now. (InspectorBackendClass.prototype._sendCommandToBackendWithCallback): Deleted. (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise): Deleted. (InspectorBackendClass.prototype._sendMessageToBackend): Deleted. (InspectorBackendClass.prototype._dispatchResponse): Deleted. (InspectorBackendClass.prototype._dispatchResponseToCallback): Deleted. (InspectorBackendClass.prototype._dispatchResponseToPromise): Deleted. (InspectorBackendClass.prototype._dispatchEvent): Deleted. (InspectorBackendClass.prototype._flushPendingScripts): Deleted. (InspectorBackend.Agent.prototype.get currentDispatchState): Deleted. (InspectorBackend.Command.prototype.deliverFailure): Deleted. * UserInterface/Protocol/Connection.js: Added. (InspectorBackend.Connection): (InspectorBackend.Connection.prototype.get target): (InspectorBackend.Connection.prototype.set target): (InspectorBackend.Connection.prototype.dispatch): (InspectorBackend.Connection.prototype.runAfterPendingDispatches): (InspectorBackend.Connection.prototype.sendMessageToBackend): (InspectorBackend.Connection.prototype._dispatchResponse): (InspectorBackend.Connection.prototype._dispatchResponseToCallback): (InspectorBackend.Connection.prototype._dispatchResponseToPromise): (InspectorBackend.Connection.prototype._dispatchEvent): (InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback): (InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise): (InspectorBackend.Connection.prototype._sendMessageToBackend): (InspectorBackend.Connection.prototype._flushPendingScripts): This extracts the Connection details into its own class. Although we make it appear as though a Target has a list of Agents, we actually have the Connection hold the list of Agents. Instead of cloning the entire Agent we just create a new object extended from the original Agent instance. This allows us to keep the same interface but just change the connection / dispatcher properties within the Agent. (InspectorBackend.MainConnection): (InspectorBackend.MainConnection.prototype.sendMessageToBackend): (InspectorBackend.WorkerConnection): (InspectorBackend.WorkerConnection.sendMessageToBackend): Two different kinds of connections. One for the Main connection and one for Workers. Currently the list of agents we expose on a Worker Target/Connection is hardcoded. * UserInterface/Models/ExecutionContext.js: (WebInspector.ExecutionContext): (WebInspector.ExecutionContext.prototype.get target): We may now have ExecutionContexts that mean a Page, Frames, and Workers. To do this we include the (target, executionContextId) tuple in this object. With this we have everything we need to evaluate JavaScript. * UserInterface/Controllers/RuntimeManager.js: (WebInspector.RuntimeManager): (WebInspector.RuntimeManager.prototype.get activeExecutionContext): (WebInspector.RuntimeManager.prototype.set activeExecutionContext): (WebInspector.RuntimeManager.prototype.get defaultExecutionContextIdentifier): Deleted. (WebInspector.RuntimeManager.prototype.set defaultExecutionContextIdentifier): Deleted. Update from contextId to a full ExecutionContext object. (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow.evalCallback): (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow): (WebInspector.RuntimeManager.prototype.saveResult): (WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject): (WebInspector.RuntimeManager.prototype._frameExecutionContextsCleared): * UserInterface/Controllers/FrameResourceManager.js: (WebInspector.FrameResourceManager.prototype.executionContextCreated): * UserInterface/Controllers/JavaScriptLogViewController.js: (WebInspector.JavaScriptLogViewController.prototype.consolePromptShouldCommitText): * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: Anywhere that wants to use the "activeExecutionContext" must use the specific RuntimeAgent tied to that ExecutionContext's Target. * UserInterface/Models/PropertyDescriptor.js: (WebInspector.PropertyDescriptor.fromPayload): * UserInterface/Protocol/RemoteObject.js: (WebInspector.RemoteObject): (WebInspector.RemoteObject.createFakeRemoteObject): (WebInspector.RemoteObject.fromPrimitiveValue): (WebInspector.RemoteObject.fromPayload): (WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors): (WebInspector.RemoteObject.prototype.deprecatedGetDisplayableProperties): (WebInspector.RemoteObject.prototype.setPropertyValue): (WebInspector.RemoteObject.prototype.getCollectionEntries): (WebInspector.RemoteObject.prototype.releaseWeakCollectionEntries): (WebInspector.RemoteObject.prototype.callFunction): (WebInspector.RemoteObject.prototype.callFunctionJSON): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor.wrappedCallback): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor): (WebInspector.RemoteObject.prototype.release): (WebInspector.RemoteObject.prototype._getPropertyDescriptors): (WebInspector.RemoteObject.prototype._getPropertyDescriptorsResolver): (WebInspector.RemoteObject.prototype._deprecatedGetProperties): RemoteObject and related Model Objects now must be tied to a specific Target, because we need to know which Target it belongs to in order to interact with it further. * UserInterface/Views/QuickConsole.js: (WebInspector.QuickConsole): (WebInspector.QuickConsole.prototype.get selectedExecutionContext): (WebInspector.QuickConsole.prototype.set selectedExecutionContext): (WebInspector.QuickConsole.prototype._executionContextPathComponentsToDisplay): (WebInspector.QuickConsole.prototype._rebuildExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._framePageExecutionContextsChanged): (WebInspector.QuickConsole.prototype._frameExecutionContextsCleared): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): (WebInspector.QuickConsole.prototype._compareExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._insertOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._removeOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._insertExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._removeExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._targetAdded): (WebInspector.QuickConsole.prototype._targetRemoved): (WebInspector.QuickConsole.prototype._pathComponentSelected): (WebInspector.QuickConsole.prototype.get selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype.set selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype._defaultExecutionContextChanged): Deleted. Update the code from executionContextId to ExecutionContext objects. Update the picker with ExecutionContextPathComponent for Workers (new Targets). Generalize and cleanup the code to make it easier to follow. LayoutTests: * inspector/unit-tests/target-manager-expected.txt: Added. * inspector/unit-tests/target-manager.html: Added. Unit test for TargetManager and its events with Worker creation. * inspector/worker/resources/worker-1.js: * inspector/worker/runtime-basic-expected.txt: Added. * inspector/worker/runtime-basic.html: Added. Test comparing RuntimeAgent between Main target and Worker target. * inspector/runtime/change-execution-context-identifier-expected.txt: * inspector/runtime/change-execution-context-identifier.html: RuntimeManager has been updated to have a full ExecutionContext object containing a Target + ContextId instead of just a ContextId. * inspector/console/console-api-expected.txt: * inspector/console/console-api.html: * inspector/console/console-table-expected.txt: * inspector/console/console-table.html: * inspector/debugger/tail-deleted-frames-from-vm-entry.html: * inspector/debugger/tail-deleted-frames.html: * inspector/debugger/tail-recursion.html: * inspector/model/remote-object-expected.txt: * inspector/model/remote-object-weak-collection-expected.txt: * inspector/model/remote-object-weak-collection.html: * inspector/model/remote-object.html: * platform/mac/inspector/model/remote-object-expected.txt: Introduce a better JSON Filter for RemoteObject in more tests. It is important that we filter the _target, because otherwise JSON.stringify would throw an error about cycles. Canonical link: https://commits.webkit.org/181797@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208009 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-27 22:19:12 +00:00
dumpTargets();
}
});
suite.addTestCase({
name: "TargetManager.WorkerTarget.Create",
description: "Creating a Worker should create a new Worker Target.",
Web Inspector: Support `async test() { ... }` in Inspector Test Suites https://bugs.webkit.org/show_bug.cgi?id=178614 Patch by Joseph Pecoraro <pecoraro@apple.com> on 2017-10-20 Reviewed by Devin Rousso. Add the ability to have test functions be async functions. A successful async test function just needs to complete evaluation. To indicate failure it should throw an exception. suite.addTestCase({ name: "ExceptionOfNormal", async test() { InspectorTest.expectThat(...); } }); suite.addTestCase({ name: "ExampleOfRejection", async test() { let value = await SomeAgent.method(); if (value.error) throw "Exception"; ... } }); Using async test functions has the added benefit that a runtime exception inside of asynchronous test code will reject the current test case instead of timing out. For example... suite.addTestCase({ name: "ExampleOfRejectionThroughRuntimeException", async test() { let arr = []; arr.this.does.not.exist; } }); ... should will lead to a failure instead of a timeout. This should allow us to structure some common tests more naturally, like so: suite.addTestCase({ name: "ExampleOfNormalAsyncTest", async test() { InspectorTest.evaluateInPage(`...`); let event = await WI.Manager.awaitEvent(...); let resource = event.data.resource; InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); } }); * inspector/unit-tests/async-test-suite-expected.txt: * inspector/unit-tests/async-test-suite.html: * inspector/unit-tests/target-manager.html: Canonical link: https://commits.webkit.org/194811@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-21 06:52:47 +00:00
async test() {
Web Inspector: Include RuntimeAgent in Workers - evaluate in Worker context https://bugs.webkit.org/show_bug.cgi?id=163835 <rdar://problem/28901465> Reviewed by Brian Burg. Source/WebCore: Tests: inspector/unit-tests/target-manager.html inspector/worker/runtime-basic.html * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * inspector/InspectorAllInOne.cpp: New file. * inspector/InspectorWebAgentBase.h: (WebCore::WorkerAgentContext::WorkerAgentContext): New agent context creation struct for Workers. * inspector/WorkerInspectorController.cpp: (WebCore::WorkerInspectorController::WorkerInspectorController): Create a RuntimeAgent for Workers. * inspector/WorkerRuntimeAgent.cpp: Added. (WebCore::WorkerRuntimeAgent::WorkerRuntimeAgent): (WebCore::WorkerRuntimeAgent::didCreateFrontendAndBackend): (WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend): (WebCore::WorkerRuntimeAgent::injectedScriptForEval): * inspector/WorkerRuntimeAgent.h: Added. Workers currently only ever have a single execution context. Source/WebInspectorUI: This introduces the idea that the frontend may communication with multiple backend "Targets" which each have their own set of Agents. - WebInspector.Target - has its own list of Agents - has a InspectorBackend.Connection to communicate with the backend - WebInspector.mainTarget - always exists and represents the thing we are debugging (Page or JSContext) - WebInspector.targets / WebInspector.targetManager - management of all Targets - create new Targets for Workers This also slowly introduces the concept that Model objects may be tied to a specific Target: - WebInspector.RemoteObject - in order to evaluate JS and interact with this object we must know the target (Page or Worker) - when fetching PropertyDescriptors and other RemoteObjects we must continue to pass on the target Finally this makes the QuickConsole list Worker execution contexts in the context picker so that users can choose a Worker context and evaluate JavaScript in that context using the console. * Localizations/en.lproj/localizedStrings.js: * UserInterface/Main.html: * UserInterface/Base/Main.js: (WebInspector.loaded): * UserInterface/Test.html: * UserInterface/Test/Test.js: (WebInspector.loaded): New files, strings, and managers. New global WebInspector.mainTarget. New convenience WebInspector.targets. * UserInterface/Protocol/Target.js: Added. (WebInspector.Target): (WebInspector.Target.prototype.get RuntimeAgent): (WebInspector.Target.prototype.get name): (WebInspector.Target.prototype.get type): (WebInspector.Target.prototype.get connection): (WebInspector.Target.prototype.get executionContext): (WebInspector.Target.prototype.get displayName): (WebInspector.Target.prototype._intializeMainTarget): (WebInspector.Target.prototype._initializeNonMainTarget): Target has some basic properties. * UserInterface/Controllers/TargetManager.js: (WebInspector.TargetManager): (WebInspector.TargetManager.prototype.get targets): (WebInspector.TargetManager.prototype.addTarget): (WebInspector.TargetManager.prototype.removeTarget): Holds the list of Targets and events when created / removed. Each target with a RuntimeAgent has an ExecutionContext. * UserInterface/Controllers/WorkerManager.js: (WebInspector.WorkerManager): (WebInspector.WorkerManager.prototype.workerCreated): (WebInspector.WorkerManager.prototype.workerTerminated): (WebInspector.WorkerManager.prototype.dispatchMessageFromWorker): Create / remove / dispatch on a Worker Target. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass): (InspectorBackendClass.prototype.registerCommand): (InspectorBackendClass.prototype.dispatch): (InspectorBackendClass.prototype.runAfterPendingDispatches): (InspectorBackendClass.prototype._agentForDomain): Keep the original implementations and just dispatch to the main connection. (InspectorBackend.Agent): (InspectorBackend.Agent.prototype.get connection): (InspectorBackend.Agent.prototype.set connection): (InspectorBackend.Agent.prototype.get dispatcher): We will share Agent implementations but just give new "copies" a different connection and dispatcher. (InspectorBackend.Command): (InspectorBackend.Command.create): (InspectorBackend.Command.prototype.invoke): (InspectorBackend.Command.prototype.supports): We continue to have a single Command instance on the Agent. However instead of using the hardcoded Agent on the Instance when evaluated as a function it uses the `this` object which should be an agent. This way: target1.RuntimeAgent.evaluate - `this` is target1 and we use the connection for that target target2.RuntimeAgent.evaluate - `this` is target2 and we use the connection for that target Unfortunately this breaks `RuntimeAgent.evaluate.invoke`. Currently this is solved by providing an extra parameter. In the case where we need to invoke on a particular agent we must provide the agent. target.RuntimeAgent.evaluate.invoke({options}, target.RuntimeAgent) This is unfortunate but only needed in a handful of places right now. (InspectorBackendClass.prototype._sendCommandToBackendWithCallback): Deleted. (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise): Deleted. (InspectorBackendClass.prototype._sendMessageToBackend): Deleted. (InspectorBackendClass.prototype._dispatchResponse): Deleted. (InspectorBackendClass.prototype._dispatchResponseToCallback): Deleted. (InspectorBackendClass.prototype._dispatchResponseToPromise): Deleted. (InspectorBackendClass.prototype._dispatchEvent): Deleted. (InspectorBackendClass.prototype._flushPendingScripts): Deleted. (InspectorBackend.Agent.prototype.get currentDispatchState): Deleted. (InspectorBackend.Command.prototype.deliverFailure): Deleted. * UserInterface/Protocol/Connection.js: Added. (InspectorBackend.Connection): (InspectorBackend.Connection.prototype.get target): (InspectorBackend.Connection.prototype.set target): (InspectorBackend.Connection.prototype.dispatch): (InspectorBackend.Connection.prototype.runAfterPendingDispatches): (InspectorBackend.Connection.prototype.sendMessageToBackend): (InspectorBackend.Connection.prototype._dispatchResponse): (InspectorBackend.Connection.prototype._dispatchResponseToCallback): (InspectorBackend.Connection.prototype._dispatchResponseToPromise): (InspectorBackend.Connection.prototype._dispatchEvent): (InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback): (InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise): (InspectorBackend.Connection.prototype._sendMessageToBackend): (InspectorBackend.Connection.prototype._flushPendingScripts): This extracts the Connection details into its own class. Although we make it appear as though a Target has a list of Agents, we actually have the Connection hold the list of Agents. Instead of cloning the entire Agent we just create a new object extended from the original Agent instance. This allows us to keep the same interface but just change the connection / dispatcher properties within the Agent. (InspectorBackend.MainConnection): (InspectorBackend.MainConnection.prototype.sendMessageToBackend): (InspectorBackend.WorkerConnection): (InspectorBackend.WorkerConnection.sendMessageToBackend): Two different kinds of connections. One for the Main connection and one for Workers. Currently the list of agents we expose on a Worker Target/Connection is hardcoded. * UserInterface/Models/ExecutionContext.js: (WebInspector.ExecutionContext): (WebInspector.ExecutionContext.prototype.get target): We may now have ExecutionContexts that mean a Page, Frames, and Workers. To do this we include the (target, executionContextId) tuple in this object. With this we have everything we need to evaluate JavaScript. * UserInterface/Controllers/RuntimeManager.js: (WebInspector.RuntimeManager): (WebInspector.RuntimeManager.prototype.get activeExecutionContext): (WebInspector.RuntimeManager.prototype.set activeExecutionContext): (WebInspector.RuntimeManager.prototype.get defaultExecutionContextIdentifier): Deleted. (WebInspector.RuntimeManager.prototype.set defaultExecutionContextIdentifier): Deleted. Update from contextId to a full ExecutionContext object. (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow.evalCallback): (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow): (WebInspector.RuntimeManager.prototype.saveResult): (WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject): (WebInspector.RuntimeManager.prototype._frameExecutionContextsCleared): * UserInterface/Controllers/FrameResourceManager.js: (WebInspector.FrameResourceManager.prototype.executionContextCreated): * UserInterface/Controllers/JavaScriptLogViewController.js: (WebInspector.JavaScriptLogViewController.prototype.consolePromptShouldCommitText): * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: Anywhere that wants to use the "activeExecutionContext" must use the specific RuntimeAgent tied to that ExecutionContext's Target. * UserInterface/Models/PropertyDescriptor.js: (WebInspector.PropertyDescriptor.fromPayload): * UserInterface/Protocol/RemoteObject.js: (WebInspector.RemoteObject): (WebInspector.RemoteObject.createFakeRemoteObject): (WebInspector.RemoteObject.fromPrimitiveValue): (WebInspector.RemoteObject.fromPayload): (WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors): (WebInspector.RemoteObject.prototype.deprecatedGetDisplayableProperties): (WebInspector.RemoteObject.prototype.setPropertyValue): (WebInspector.RemoteObject.prototype.getCollectionEntries): (WebInspector.RemoteObject.prototype.releaseWeakCollectionEntries): (WebInspector.RemoteObject.prototype.callFunction): (WebInspector.RemoteObject.prototype.callFunctionJSON): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor.wrappedCallback): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor): (WebInspector.RemoteObject.prototype.release): (WebInspector.RemoteObject.prototype._getPropertyDescriptors): (WebInspector.RemoteObject.prototype._getPropertyDescriptorsResolver): (WebInspector.RemoteObject.prototype._deprecatedGetProperties): RemoteObject and related Model Objects now must be tied to a specific Target, because we need to know which Target it belongs to in order to interact with it further. * UserInterface/Views/QuickConsole.js: (WebInspector.QuickConsole): (WebInspector.QuickConsole.prototype.get selectedExecutionContext): (WebInspector.QuickConsole.prototype.set selectedExecutionContext): (WebInspector.QuickConsole.prototype._executionContextPathComponentsToDisplay): (WebInspector.QuickConsole.prototype._rebuildExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._framePageExecutionContextsChanged): (WebInspector.QuickConsole.prototype._frameExecutionContextsCleared): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): (WebInspector.QuickConsole.prototype._compareExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._insertOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._removeOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._insertExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._removeExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._targetAdded): (WebInspector.QuickConsole.prototype._targetRemoved): (WebInspector.QuickConsole.prototype._pathComponentSelected): (WebInspector.QuickConsole.prototype.get selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype.set selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype._defaultExecutionContextChanged): Deleted. Update the code from executionContextId to ExecutionContext objects. Update the picker with ExecutionContextPathComponent for Workers (new Targets). Generalize and cleanup the code to make it easier to follow. LayoutTests: * inspector/unit-tests/target-manager-expected.txt: Added. * inspector/unit-tests/target-manager.html: Added. Unit test for TargetManager and its events with Worker creation. * inspector/worker/resources/worker-1.js: * inspector/worker/runtime-basic-expected.txt: Added. * inspector/worker/runtime-basic.html: Added. Test comparing RuntimeAgent between Main target and Worker target. * inspector/runtime/change-execution-context-identifier-expected.txt: * inspector/runtime/change-execution-context-identifier.html: RuntimeManager has been updated to have a full ExecutionContext object containing a Target + ContextId instead of just a ContextId. * inspector/console/console-api-expected.txt: * inspector/console/console-api.html: * inspector/console/console-table-expected.txt: * inspector/console/console-table.html: * inspector/debugger/tail-deleted-frames-from-vm-entry.html: * inspector/debugger/tail-deleted-frames.html: * inspector/debugger/tail-recursion.html: * inspector/model/remote-object-expected.txt: * inspector/model/remote-object-weak-collection-expected.txt: * inspector/model/remote-object-weak-collection.html: * inspector/model/remote-object.html: * platform/mac/inspector/model/remote-object-expected.txt: Introduce a better JSON Filter for RemoteObject in more tests. It is important that we filter the _target, because otherwise JSON.stringify would throw an error about cycles. Canonical link: https://commits.webkit.org/181797@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208009 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-27 22:19:12 +00:00
InspectorTest.evaluateInPage("createWorker()");
Web Inspector: Support `async test() { ... }` in Inspector Test Suites https://bugs.webkit.org/show_bug.cgi?id=178614 Patch by Joseph Pecoraro <pecoraro@apple.com> on 2017-10-20 Reviewed by Devin Rousso. Add the ability to have test functions be async functions. A successful async test function just needs to complete evaluation. To indicate failure it should throw an exception. suite.addTestCase({ name: "ExceptionOfNormal", async test() { InspectorTest.expectThat(...); } }); suite.addTestCase({ name: "ExampleOfRejection", async test() { let value = await SomeAgent.method(); if (value.error) throw "Exception"; ... } }); Using async test functions has the added benefit that a runtime exception inside of asynchronous test code will reject the current test case instead of timing out. For example... suite.addTestCase({ name: "ExampleOfRejectionThroughRuntimeException", async test() { let arr = []; arr.this.does.not.exist; } }); ... should will lead to a failure instead of a timeout. This should allow us to structure some common tests more naturally, like so: suite.addTestCase({ name: "ExampleOfNormalAsyncTest", async test() { InspectorTest.evaluateInPage(`...`); let event = await WI.Manager.awaitEvent(...); let resource = event.data.resource; InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); } }); * inspector/unit-tests/async-test-suite-expected.txt: * inspector/unit-tests/async-test-suite.html: * inspector/unit-tests/target-manager.html: Canonical link: https://commits.webkit.org/194811@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-21 06:52:47 +00:00
let event = await WI.targetManager.awaitEvent(WI.TargetManager.Event.TargetAdded);
let target = event.data.target;
InspectorTest.assert(target instanceof WI.Target);
Web Inspector: rework frontend agent construction to allow commands/events to be controlled by the related target's type https://bugs.webkit.org/show_bug.cgi?id=200384 <rdar://problem/53850352> Reviewed by Joseph Pecoraro. Source/JavaScriptCore: * inspector/scripts/codegen/generate_js_backend_commands.py: (JSBackendCommandsGenerator.generate_domain): (JSBackendCommandsGenerator.generate_domain.generate_parameter_object): * inspector/scripts/codegen/models.py: (validate_target_types): Added. (Protocol.parse_domain): (Protocol.parse_command): (Protocol.parse_event): (Domain.__init__): (Domains): (Command.__init__): (Event.__init__): * inspector/protocol/ApplicationCache.json: * inspector/protocol/Audit.json: * inspector/protocol/CPUProfiler.json: * inspector/protocol/CSS.json: * inspector/protocol/Canvas.json: * inspector/protocol/Console.json: * inspector/protocol/DOM.json: * inspector/protocol/DOMDebugger.json: * inspector/protocol/DOMStorage.json: * inspector/protocol/Database.json: * inspector/protocol/Debugger.json: * inspector/protocol/Heap.json: * inspector/protocol/IndexedDB.json: * inspector/protocol/Inspector.json: * inspector/protocol/LayerTree.json: * inspector/protocol/Memory.json: * inspector/protocol/Network.json: * inspector/protocol/Page.json: * inspector/protocol/Recording.json: * inspector/protocol/Runtime.json: * inspector/protocol/ScriptProfiler.json: * inspector/protocol/Security.json: * inspector/protocol/ServiceWorker.json: * inspector/protocol/Target.json: * inspector/protocol/Timeline.json: * inspector/protocol/Worker.json: Add `debuggableTypes` and `targetTypes` arrays to domains/commands/events that are used when generating InspectorBackendCommands.js for more accurate compatibility checks. * inspector/InspectorTarget.h: * inspector/agents/InspectorTargetAgent.h: * inspector/agents/InspectorTargetAgent.cpp: (Inspector::targetTypeToProtocolType): (Inspector::InspectorTargetAgent::exists): Deleted. Remove `Target.exists` now that the frontend can do proper feature checking. * inspector/remote/RemoteControllableTarget.h: * inspector/remote/RemoteInspectionTarget.h: * inspector/remote/RemoteInspectorConstants.h: * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::listingForInspectionTarget const): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::listingForInspectionTarget const): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::listingForInspectionTarget const): Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). * inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result: * inspector/scripts/tests/generic/command-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/domain-availability.json: Removed. * inspector/scripts/tests/generic/domain-debuggableTypes.json: Added. * inspector/scripts/tests/generic/domain-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/domain-targetTypes.json: Added. * inspector/scripts/tests/generic/event-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result: Added. * inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result: * inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result: * inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result: Added. * inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result: Added. * inspector/scripts/tests/generic/expected/domain-targetTypes.json-result: Added. * inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result: * inspector/scripts/tests/generic/expected/enum-values.json-result: * inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result: Added. * inspector/scripts/tests/generic/expected/events-with-optional-parameters.json-result: * inspector/scripts/tests/generic/expected/fail-on-command-targetType-matching-domain-debuggableType.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-command-targetTypes-type.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-command-targetTypes-value.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-availability-type.json-error: Removed. * inspector/scripts/tests/generic/expected/fail-on-domain-availability-value.json-error: Removed. * inspector/scripts/tests/generic/expected/fail-on-domain-availability.json-error: Removed. * inspector/scripts/tests/generic/expected/fail-on-domain-debuggableTypes-type.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-debuggableTypes-value.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-targetType-matching-domain-debuggableType.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-targetTypes-type.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-targetTypes-value.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-event-targetType-matching-domain-debuggableType.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-event-targetTypes-type.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-event-targetTypes-value.json-error: Added. * inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result: * inspector/scripts/tests/generic/expected/type-declaration-array-type.json-result: * inspector/scripts/tests/generic/expected/type-declaration-enum-type.json-result: * inspector/scripts/tests/generic/expected/type-declaration-object-type.json-result: * inspector/scripts/tests/generic/expected/type-requiring-runtime-casts.json-result: * inspector/scripts/tests/generic/expected/version.json-result: * inspector/scripts/tests/generic/fail-on-command-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/fail-on-command-targetTypes-type.json: Added. * inspector/scripts/tests/generic/fail-on-command-targetTypes-value.json: Added. * inspector/scripts/tests/generic/fail-on-domain-debuggableTypes-type.json: Added. * inspector/scripts/tests/generic/fail-on-domain-debuggableTypes-value.json: Added. * inspector/scripts/tests/generic/fail-on-domain-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/fail-on-domain-targetTypes-type.json: Added. * inspector/scripts/tests/generic/fail-on-domain-targetTypes-value.json: Added. * inspector/scripts/tests/generic/fail-on-event-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/fail-on-event-targetTypes-type.json: Added. * inspector/scripts/tests/generic/fail-on-event-targetTypes-value.json: Added. * inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result: Update test results, as well as added new tests for `debuggableTypes` and `targetTypes`. Source/WebCore: * inspector/InspectorFrontendClient.h: (WebCore::InspectorFrontendClient::backendCommandsURL): Deleted. (WebCore::InspectorFrontendClient::debuggableType): Deleted. * inspector/InspectorFrontendClientLocal.h: * page/PageDebuggable.h: (WebCore::PageDebuggable::type const): * testing/Internals.cpp: (WebCore::InspectorStubFrontend::debuggableType const): Added. Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). Source/WebInspectorUI: `InspectorBackend.domains.${domain}` isn't a truly valid way to feature check, as it indicates what's supported by the WebKit framework underlying whatever's currently being inspected, not what the current inspection target supports. As an example, inspecting an iOS `JSContext` will still show `InspectorBackend.domains.DOM` as the `DOMAgent` is supported by WebKit, even though `JSContext`s have no concept of the DOM. In this example, however, `window.DOMAgent` would NOT exist, as the `availability` check for the `DOM` domain wouldn't pass, meaning that the agent never gets connected. In order to do proper feature checking, `InspectorBackend.domains` needs to be accurate depending on the debuggable type. Furthermore, each target underneath that debuggable needs to be able to "choose" what commands/events are supported based on that target's type. This patch modifies how InspectorBackendCommands.js ties into `InspectorBackend`. Rather than directly creating an `InspectorBackend.Agent` for each domain, we now create more of a "blueprint" of the domain, and wait to actually create an `InspectorBackend.Agent` until we have a `WI.Target` (and therefore an `InspectorBackend.Connection`). Each "concept" of the protocol now directly maps to an object. - InspectorBackend.Domain - InspectorBackend.Command - InspectorBackend.Event - InspectorBackend.Dispatcher When a `WI.Target` is created, it gets the list of `InspectorBackend.Domain` that support that `WI.Target`'s type (specified in the protocol JSON files) and generates an `InspectorBackend.Agent` for each, which in turn generates an `InspectorBackend.Callable` for each supported `InspectorBackend.Command` and instantiates `InspectorBackend.Dispatcher`. Activating a `InspectorBackend.Domain` means it's visible for `InspectorBackend` feature checking. This must be done this way for older ITML backends that will still appear as "JSContext" targets and therefore go through the "extra domains" path. Ideally, the process of registering a domain should be enough to activate it. <https://webkit.org/b/201150> Feature checking can now only be done via `hasDomain`, `hasCommand`, and `hasEvent` on `InspectorBackend` or a specific `WI.Target`, and there are different implications for each: - `InspectorBackend.hasDomain(DOM)` asks whether the `DOM` domain is supported by the current debuggable, but says nothing about whether any `WI.Target` support `DOM`. - `target.hasDomain("DOM")` asks whether the given `target` supports `DOM`, which is limited by `InspectorBackend.hasDomain("DOM")`. Now that `InspectorBackend.Agent` is only created by a `WI.Target`, it's no longer valid to write `window.DOMAgent`, as there is no "global" agent. All protocol logic _must_ go through a `WI.Target`. <https://webkit.org/b/201149> Debuggable Types: - JavaScript (JSC::JSGlobalObject) - Page (WebCore::Page) - ServiceWorker (WebCore::ServiceWorkerThreadProxy) - WebPage (WebKit::WebPageProxy) Target Types: - JavaScript (direct connection) - Page (multi-target connection to any Worker) - ServiceWorker (direct connection) - WebPage (multi-target connection to 1+ Page) - Worker (direct connection, only available for Page debuggables) * UserInterface/Base/DebuggableType.js: * UserInterface/Base/TargetType.js: Copied from Source/WebInspectorUI/UserInterface/Base/DebuggableType.js. * UserInterface/Protocol/Connection.js: * UserInterface/Protocol/InspectorBackend.js: * UserInterface/Protocol/ApplicationCacheObserver.js: * UserInterface/Protocol/CPUProfilerObserver.js: * UserInterface/Protocol/CSSObserver.js: * UserInterface/Protocol/CanvasObserver.js: * UserInterface/Protocol/ConsoleObserver.js: * UserInterface/Protocol/DOMObserver.js: * UserInterface/Protocol/DOMStorageObserver.js: * UserInterface/Protocol/DatabaseObserver.js: * UserInterface/Protocol/DebuggerObserver.js: * UserInterface/Protocol/HeapObserver.js: * UserInterface/Protocol/InspectorObserver.js: * UserInterface/Protocol/LayerTreeObserver.js: * UserInterface/Protocol/MemoryObserver.js: * UserInterface/Protocol/NetworkObserver.js: * UserInterface/Protocol/PageObserver.js: * UserInterface/Protocol/RuntimeObserver.js: * UserInterface/Protocol/ScriptProfilerObserver.js: * UserInterface/Protocol/TargetObserver.js: * UserInterface/Protocol/TimelineObserver.js: * UserInterface/Protocol/WorkerObserver.js: All observers now extend from `InspectorBackend.Dispatcher` and have a separate instance for each `InspectorBackend.Agent`, each having their own `_target`. * UserInterface/Protocol/Target.js: * UserInterface/Protocol/DirectBackendTarget.js: * UserInterface/Protocol/JavaScriptContextTarget.js: Removed. * UserInterface/Protocol/MultiplexingBackendTarget.js: * UserInterface/Protocol/PageTarget.js: * UserInterface/Protocol/WorkerTarget.js: Agents are now created per-target instead of copied from the "global" list. This means that agents can have a different set of commands/events depending on the associated target. * UserInterface/Base/Main.js: * UserInterface/Base/Utilities.js: * UserInterface/Controllers/AppController.js: * UserInterface/Controllers/AppControllerBase.js: * UserInterface/Controllers/ApplicationCacheManager.js: * UserInterface/Controllers/AuditManager.js: * UserInterface/Controllers/BreakpointPopoverController.js: * UserInterface/Controllers/CSSManager.js: * UserInterface/Controllers/CanvasManager.js: * UserInterface/Controllers/ConsoleManager.js: * UserInterface/Controllers/DOMDebuggerManager.js: * UserInterface/Controllers/DOMManager.js: * UserInterface/Controllers/DOMStorageManager.js: * UserInterface/Controllers/DatabaseManager.js: * UserInterface/Controllers/DebuggerManager.js: * UserInterface/Controllers/HeapManager.js: * UserInterface/Controllers/IndexedDBManager.js: * UserInterface/Controllers/JavaScriptLogViewController.js: * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: * UserInterface/Controllers/LayerTreeManager.js: * UserInterface/Controllers/MemoryManager.js: * UserInterface/Controllers/NetworkManager.js: * UserInterface/Controllers/RuntimeManager.js: * UserInterface/Controllers/TargetManager.js: * UserInterface/Controllers/TimelineManager.js: * UserInterface/Controllers/WorkerManager.js: * UserInterface/Main.html: * UserInterface/Models/AuditTestBase.js: * UserInterface/Models/AuditTestCase.js: * UserInterface/Models/AuditTestCaseResult.js: * UserInterface/Models/CPUInstrument.js: * UserInterface/Models/CPUTimelineRecord.js: * UserInterface/Models/CSSCompletions.js: * UserInterface/Models/CSSStyleSheet.js: * UserInterface/Models/Canvas.js: * UserInterface/Models/DOMNode.js: * UserInterface/Models/DOMNodeStyles.js: * UserInterface/Models/DOMStorageObject.js: * UserInterface/Models/DOMTree.js: * UserInterface/Models/DatabaseObject.js: * UserInterface/Models/FPSInstrument.js: * UserInterface/Models/GarbageCollection.js: * UserInterface/Models/HeapAllocationsInstrument.js: * UserInterface/Models/Instrument.js: * UserInterface/Models/MediaInstrument.js: * UserInterface/Models/MemoryInstrument.js: * UserInterface/Models/MemoryPressureEvent.js: * UserInterface/Models/MemoryTimelineRecord.js: * UserInterface/Models/Recording.js: * UserInterface/Models/Resource.js: * UserInterface/Models/ScriptInstrument.js: * UserInterface/Models/ScriptSyntaxTree.js: * UserInterface/Models/ScriptTimelineRecord.js: * UserInterface/Models/ShaderProgram.js: * UserInterface/Models/SourceMapResource.js: * UserInterface/Models/TimelineRecording.js: * UserInterface/Protocol/RemoteObject.js: * UserInterface/Test.html: * UserInterface/Test/FrontendTestHarness.js: * UserInterface/Test/Test.js: * UserInterface/Test/TestAppController.js: * UserInterface/Views/AuditNavigationSidebarPanel.js: * UserInterface/Views/AuditTabContentView.js: * UserInterface/Views/CanvasTabContentView.js: * UserInterface/Views/ContextMenuUtilities.js: * UserInterface/Views/CookieStorageContentView.js: * UserInterface/Views/DOMNodeDetailsSidebarPanel.js: * UserInterface/Views/DOMTreeContentView.js: * UserInterface/Views/ElementsTabContentView.js: * UserInterface/Views/IndexedDatabaseDetailsSidebarPanel.js: * UserInterface/Views/Layers3DContentView.js: * UserInterface/Views/LayersTabContentView.js: * UserInterface/Views/LayoutTimelineView.js: * UserInterface/Views/LogContentView.js: * UserInterface/Views/NetworkTabContentView.js: * UserInterface/Views/NetworkTableContentView.js: * UserInterface/Views/NetworkTimelineView.js: * UserInterface/Views/ObjectTreeView.js: * UserInterface/Views/QuickConsole.js: * UserInterface/Views/ResourceDetailsSidebarPanel.js: * UserInterface/Views/ScriptClusterTimelineView.js: * UserInterface/Views/ScriptDetailsTimelineView.js: * UserInterface/Views/ScriptTreeElement.js: * UserInterface/Views/SearchSidebarPanel.js: * UserInterface/Views/SearchTabContentView.js: * UserInterface/Views/SettingsTabContentView.js: * UserInterface/Views/SourceCodeTextEditor.js: * UserInterface/Views/SourcesNavigationSidebarPanel.js: * UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js: * UserInterface/Views/SpreadsheetStyleProperty.js: * UserInterface/Views/StorageTabContentView.js: * UserInterface/Views/TimelineRecordingContentView.js: * UserInterface/Views/TimelineTabContentView.js: * UserInterface/Views/Toolbar.js: * UserInterface/Views/WebSocketContentView.js: * UserInterface/Views/WorkerTreeElement.js: Replace all instances of `window.DomainAgent` with `target.DomainAgent`, where `target` is either derived from an associated model object or `WI.assumingMainTarget()`. Split the `WI.DebuggableType.Web` debuggable type into `WI.DebuggableType.Page` (WebCore::Page) and `WI.DebuggableType.WebPage` (WebKit::WebPageProxy). * UserInterface/Protocol/Legacy/*: * Versions/*: Update protocol files for older versions of iOS. * .eslintrc: * Localizations/en.lproj/localizedStrings.js: Source/WebKit: * WebProcess/WebPage/RemoteWebInspectorUI.h: (WebKit::WebInspectorUI::backendCommandsURL const): Added. (WebKit::WebInspectorUI::debuggableType const): Added. (WebKit::WebInspectorUI::backendCommandsURL): Deleted. (WebKit::WebInspectorUI::debuggableType): Deleted. * WebProcess/WebPage/WebInspectorUI.h: (WebKit::WebInspectorUI::backendCommandsURL const): Added. (WebKit::WebInspectorUI::debuggableType const): Added. * UIProcess/WebPageDebuggable.h: (WebKit::WebPageDebuggable::type const): * UIProcess/glib/RemoteInspectorClient.cpp: (WebKit::RemoteInspectorClient::RemoteInspectorClient): * UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.h: * UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm: (debuggableTypeString): Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). Source/WebKitLegacy/mac: * WebCoreSupport/WebInspectorClient.h: (WebInspectorFrontendClient::debuggableType const): Added. Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). Source/WebKitLegacy/win: * WebCoreSupport/WebInspectorClient.h: (WebInspectorFrontendClient::debuggableType const): Added. Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). LayoutTests: * inspector/canvas/requestShaderSource-webgl.html: * inspector/canvas/updateShader-webgl: * inspector/page/overrideSetting.html: * inspector/page/overrideSetting-ICECandidateFilteringEnabled.html: * inspector/page/overrideSetting-MockCaptureDevicesEnabled.html: * inspector/runtime/parse.html: Replace all instances of `DomainAgent.Enum` with `InspectorBackend.domains.Domain.Enum`. * inspector/audit/run.html: * inspector/audit/version.html: * inspector/recording/version.html: Use new `InspectorBackend` methods. * inspector/unit-tests/target-manager.html: * inspector/unit-tests/target-manager-expected.txt: * inspector/worker/console-basic.html: * inspector/worker/debugger-pause.html: * inspector/worker/debugger-scripts.html: * inspector/worker/debugger-shared-breakpoint.html: * inspector/worker/resources-in-worker.html: * inspector/worker/resources/dom-debugger-utilities.js: * inspector/worker/runtime-basic.html: * http/tests/inspector/worker/blob-script-with-cross-domain-imported-scripts.html: Replace `WI.Target.Type` with `WI.TargetType`. * inspector/dom/inspect.html: * inspector/dom/inspect-expected.txt: Rewrite test since faking events from the backend now requires a target. * inspector/unit-tests/set-utilities.html: * inspector/unit-tests/set-utilities-expected.txt: Add tests for `Set.prototype.addAll`. Canonical link: https://commits.webkit.org/216493@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251227 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-17 08:00:46 +00:00
InspectorTest.expectEqual(target.type, WI.TargetType.Worker, "Added Target should have Worker type.");
Web Inspector: Support `async test() { ... }` in Inspector Test Suites https://bugs.webkit.org/show_bug.cgi?id=178614 Patch by Joseph Pecoraro <pecoraro@apple.com> on 2017-10-20 Reviewed by Devin Rousso. Add the ability to have test functions be async functions. A successful async test function just needs to complete evaluation. To indicate failure it should throw an exception. suite.addTestCase({ name: "ExceptionOfNormal", async test() { InspectorTest.expectThat(...); } }); suite.addTestCase({ name: "ExampleOfRejection", async test() { let value = await SomeAgent.method(); if (value.error) throw "Exception"; ... } }); Using async test functions has the added benefit that a runtime exception inside of asynchronous test code will reject the current test case instead of timing out. For example... suite.addTestCase({ name: "ExampleOfRejectionThroughRuntimeException", async test() { let arr = []; arr.this.does.not.exist; } }); ... should will lead to a failure instead of a timeout. This should allow us to structure some common tests more naturally, like so: suite.addTestCase({ name: "ExampleOfNormalAsyncTest", async test() { InspectorTest.evaluateInPage(`...`); let event = await WI.Manager.awaitEvent(...); let resource = event.data.resource; InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); } }); * inspector/unit-tests/async-test-suite-expected.txt: * inspector/unit-tests/async-test-suite.html: * inspector/unit-tests/target-manager.html: Canonical link: https://commits.webkit.org/194811@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-21 06:52:47 +00:00
InspectorTest.expectNotNull(target.executionContext, "Added Target should have an ExecutionContext.");
InspectorTest.expectNotNull(target.RuntimeAgent, "Added Target should have a RuntimeAgent.");
InspectorTest.expectNotEqual(target.RuntimeAgent, RuntimeAgent, "Added Target RuntimeAgent should not be the global RuntimeAgent.");
dumpTargets();
Web Inspector: Include RuntimeAgent in Workers - evaluate in Worker context https://bugs.webkit.org/show_bug.cgi?id=163835 <rdar://problem/28901465> Reviewed by Brian Burg. Source/WebCore: Tests: inspector/unit-tests/target-manager.html inspector/worker/runtime-basic.html * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * inspector/InspectorAllInOne.cpp: New file. * inspector/InspectorWebAgentBase.h: (WebCore::WorkerAgentContext::WorkerAgentContext): New agent context creation struct for Workers. * inspector/WorkerInspectorController.cpp: (WebCore::WorkerInspectorController::WorkerInspectorController): Create a RuntimeAgent for Workers. * inspector/WorkerRuntimeAgent.cpp: Added. (WebCore::WorkerRuntimeAgent::WorkerRuntimeAgent): (WebCore::WorkerRuntimeAgent::didCreateFrontendAndBackend): (WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend): (WebCore::WorkerRuntimeAgent::injectedScriptForEval): * inspector/WorkerRuntimeAgent.h: Added. Workers currently only ever have a single execution context. Source/WebInspectorUI: This introduces the idea that the frontend may communication with multiple backend "Targets" which each have their own set of Agents. - WebInspector.Target - has its own list of Agents - has a InspectorBackend.Connection to communicate with the backend - WebInspector.mainTarget - always exists and represents the thing we are debugging (Page or JSContext) - WebInspector.targets / WebInspector.targetManager - management of all Targets - create new Targets for Workers This also slowly introduces the concept that Model objects may be tied to a specific Target: - WebInspector.RemoteObject - in order to evaluate JS and interact with this object we must know the target (Page or Worker) - when fetching PropertyDescriptors and other RemoteObjects we must continue to pass on the target Finally this makes the QuickConsole list Worker execution contexts in the context picker so that users can choose a Worker context and evaluate JavaScript in that context using the console. * Localizations/en.lproj/localizedStrings.js: * UserInterface/Main.html: * UserInterface/Base/Main.js: (WebInspector.loaded): * UserInterface/Test.html: * UserInterface/Test/Test.js: (WebInspector.loaded): New files, strings, and managers. New global WebInspector.mainTarget. New convenience WebInspector.targets. * UserInterface/Protocol/Target.js: Added. (WebInspector.Target): (WebInspector.Target.prototype.get RuntimeAgent): (WebInspector.Target.prototype.get name): (WebInspector.Target.prototype.get type): (WebInspector.Target.prototype.get connection): (WebInspector.Target.prototype.get executionContext): (WebInspector.Target.prototype.get displayName): (WebInspector.Target.prototype._intializeMainTarget): (WebInspector.Target.prototype._initializeNonMainTarget): Target has some basic properties. * UserInterface/Controllers/TargetManager.js: (WebInspector.TargetManager): (WebInspector.TargetManager.prototype.get targets): (WebInspector.TargetManager.prototype.addTarget): (WebInspector.TargetManager.prototype.removeTarget): Holds the list of Targets and events when created / removed. Each target with a RuntimeAgent has an ExecutionContext. * UserInterface/Controllers/WorkerManager.js: (WebInspector.WorkerManager): (WebInspector.WorkerManager.prototype.workerCreated): (WebInspector.WorkerManager.prototype.workerTerminated): (WebInspector.WorkerManager.prototype.dispatchMessageFromWorker): Create / remove / dispatch on a Worker Target. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass): (InspectorBackendClass.prototype.registerCommand): (InspectorBackendClass.prototype.dispatch): (InspectorBackendClass.prototype.runAfterPendingDispatches): (InspectorBackendClass.prototype._agentForDomain): Keep the original implementations and just dispatch to the main connection. (InspectorBackend.Agent): (InspectorBackend.Agent.prototype.get connection): (InspectorBackend.Agent.prototype.set connection): (InspectorBackend.Agent.prototype.get dispatcher): We will share Agent implementations but just give new "copies" a different connection and dispatcher. (InspectorBackend.Command): (InspectorBackend.Command.create): (InspectorBackend.Command.prototype.invoke): (InspectorBackend.Command.prototype.supports): We continue to have a single Command instance on the Agent. However instead of using the hardcoded Agent on the Instance when evaluated as a function it uses the `this` object which should be an agent. This way: target1.RuntimeAgent.evaluate - `this` is target1 and we use the connection for that target target2.RuntimeAgent.evaluate - `this` is target2 and we use the connection for that target Unfortunately this breaks `RuntimeAgent.evaluate.invoke`. Currently this is solved by providing an extra parameter. In the case where we need to invoke on a particular agent we must provide the agent. target.RuntimeAgent.evaluate.invoke({options}, target.RuntimeAgent) This is unfortunate but only needed in a handful of places right now. (InspectorBackendClass.prototype._sendCommandToBackendWithCallback): Deleted. (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise): Deleted. (InspectorBackendClass.prototype._sendMessageToBackend): Deleted. (InspectorBackendClass.prototype._dispatchResponse): Deleted. (InspectorBackendClass.prototype._dispatchResponseToCallback): Deleted. (InspectorBackendClass.prototype._dispatchResponseToPromise): Deleted. (InspectorBackendClass.prototype._dispatchEvent): Deleted. (InspectorBackendClass.prototype._flushPendingScripts): Deleted. (InspectorBackend.Agent.prototype.get currentDispatchState): Deleted. (InspectorBackend.Command.prototype.deliverFailure): Deleted. * UserInterface/Protocol/Connection.js: Added. (InspectorBackend.Connection): (InspectorBackend.Connection.prototype.get target): (InspectorBackend.Connection.prototype.set target): (InspectorBackend.Connection.prototype.dispatch): (InspectorBackend.Connection.prototype.runAfterPendingDispatches): (InspectorBackend.Connection.prototype.sendMessageToBackend): (InspectorBackend.Connection.prototype._dispatchResponse): (InspectorBackend.Connection.prototype._dispatchResponseToCallback): (InspectorBackend.Connection.prototype._dispatchResponseToPromise): (InspectorBackend.Connection.prototype._dispatchEvent): (InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback): (InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise): (InspectorBackend.Connection.prototype._sendMessageToBackend): (InspectorBackend.Connection.prototype._flushPendingScripts): This extracts the Connection details into its own class. Although we make it appear as though a Target has a list of Agents, we actually have the Connection hold the list of Agents. Instead of cloning the entire Agent we just create a new object extended from the original Agent instance. This allows us to keep the same interface but just change the connection / dispatcher properties within the Agent. (InspectorBackend.MainConnection): (InspectorBackend.MainConnection.prototype.sendMessageToBackend): (InspectorBackend.WorkerConnection): (InspectorBackend.WorkerConnection.sendMessageToBackend): Two different kinds of connections. One for the Main connection and one for Workers. Currently the list of agents we expose on a Worker Target/Connection is hardcoded. * UserInterface/Models/ExecutionContext.js: (WebInspector.ExecutionContext): (WebInspector.ExecutionContext.prototype.get target): We may now have ExecutionContexts that mean a Page, Frames, and Workers. To do this we include the (target, executionContextId) tuple in this object. With this we have everything we need to evaluate JavaScript. * UserInterface/Controllers/RuntimeManager.js: (WebInspector.RuntimeManager): (WebInspector.RuntimeManager.prototype.get activeExecutionContext): (WebInspector.RuntimeManager.prototype.set activeExecutionContext): (WebInspector.RuntimeManager.prototype.get defaultExecutionContextIdentifier): Deleted. (WebInspector.RuntimeManager.prototype.set defaultExecutionContextIdentifier): Deleted. Update from contextId to a full ExecutionContext object. (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow.evalCallback): (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow): (WebInspector.RuntimeManager.prototype.saveResult): (WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject): (WebInspector.RuntimeManager.prototype._frameExecutionContextsCleared): * UserInterface/Controllers/FrameResourceManager.js: (WebInspector.FrameResourceManager.prototype.executionContextCreated): * UserInterface/Controllers/JavaScriptLogViewController.js: (WebInspector.JavaScriptLogViewController.prototype.consolePromptShouldCommitText): * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: Anywhere that wants to use the "activeExecutionContext" must use the specific RuntimeAgent tied to that ExecutionContext's Target. * UserInterface/Models/PropertyDescriptor.js: (WebInspector.PropertyDescriptor.fromPayload): * UserInterface/Protocol/RemoteObject.js: (WebInspector.RemoteObject): (WebInspector.RemoteObject.createFakeRemoteObject): (WebInspector.RemoteObject.fromPrimitiveValue): (WebInspector.RemoteObject.fromPayload): (WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors): (WebInspector.RemoteObject.prototype.deprecatedGetDisplayableProperties): (WebInspector.RemoteObject.prototype.setPropertyValue): (WebInspector.RemoteObject.prototype.getCollectionEntries): (WebInspector.RemoteObject.prototype.releaseWeakCollectionEntries): (WebInspector.RemoteObject.prototype.callFunction): (WebInspector.RemoteObject.prototype.callFunctionJSON): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor.wrappedCallback): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor): (WebInspector.RemoteObject.prototype.release): (WebInspector.RemoteObject.prototype._getPropertyDescriptors): (WebInspector.RemoteObject.prototype._getPropertyDescriptorsResolver): (WebInspector.RemoteObject.prototype._deprecatedGetProperties): RemoteObject and related Model Objects now must be tied to a specific Target, because we need to know which Target it belongs to in order to interact with it further. * UserInterface/Views/QuickConsole.js: (WebInspector.QuickConsole): (WebInspector.QuickConsole.prototype.get selectedExecutionContext): (WebInspector.QuickConsole.prototype.set selectedExecutionContext): (WebInspector.QuickConsole.prototype._executionContextPathComponentsToDisplay): (WebInspector.QuickConsole.prototype._rebuildExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._framePageExecutionContextsChanged): (WebInspector.QuickConsole.prototype._frameExecutionContextsCleared): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): (WebInspector.QuickConsole.prototype._compareExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._insertOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._removeOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._insertExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._removeExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._targetAdded): (WebInspector.QuickConsole.prototype._targetRemoved): (WebInspector.QuickConsole.prototype._pathComponentSelected): (WebInspector.QuickConsole.prototype.get selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype.set selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype._defaultExecutionContextChanged): Deleted. Update the code from executionContextId to ExecutionContext objects. Update the picker with ExecutionContextPathComponent for Workers (new Targets). Generalize and cleanup the code to make it easier to follow. LayoutTests: * inspector/unit-tests/target-manager-expected.txt: Added. * inspector/unit-tests/target-manager.html: Added. Unit test for TargetManager and its events with Worker creation. * inspector/worker/resources/worker-1.js: * inspector/worker/runtime-basic-expected.txt: Added. * inspector/worker/runtime-basic.html: Added. Test comparing RuntimeAgent between Main target and Worker target. * inspector/runtime/change-execution-context-identifier-expected.txt: * inspector/runtime/change-execution-context-identifier.html: RuntimeManager has been updated to have a full ExecutionContext object containing a Target + ContextId instead of just a ContextId. * inspector/console/console-api-expected.txt: * inspector/console/console-api.html: * inspector/console/console-table-expected.txt: * inspector/console/console-table.html: * inspector/debugger/tail-deleted-frames-from-vm-entry.html: * inspector/debugger/tail-deleted-frames.html: * inspector/debugger/tail-recursion.html: * inspector/model/remote-object-expected.txt: * inspector/model/remote-object-weak-collection-expected.txt: * inspector/model/remote-object-weak-collection.html: * inspector/model/remote-object.html: * platform/mac/inspector/model/remote-object-expected.txt: Introduce a better JSON Filter for RemoteObject in more tests. It is important that we filter the _target, because otherwise JSON.stringify would throw an error about cycles. Canonical link: https://commits.webkit.org/181797@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208009 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-27 22:19:12 +00:00
}
});
suite.addTestCase({
name: "TargetManager.WorkerTarget.Remove",
description: "Creating a Worker should create a new Worker Target.",
Web Inspector: Support `async test() { ... }` in Inspector Test Suites https://bugs.webkit.org/show_bug.cgi?id=178614 Patch by Joseph Pecoraro <pecoraro@apple.com> on 2017-10-20 Reviewed by Devin Rousso. Add the ability to have test functions be async functions. A successful async test function just needs to complete evaluation. To indicate failure it should throw an exception. suite.addTestCase({ name: "ExceptionOfNormal", async test() { InspectorTest.expectThat(...); } }); suite.addTestCase({ name: "ExampleOfRejection", async test() { let value = await SomeAgent.method(); if (value.error) throw "Exception"; ... } }); Using async test functions has the added benefit that a runtime exception inside of asynchronous test code will reject the current test case instead of timing out. For example... suite.addTestCase({ name: "ExampleOfRejectionThroughRuntimeException", async test() { let arr = []; arr.this.does.not.exist; } }); ... should will lead to a failure instead of a timeout. This should allow us to structure some common tests more naturally, like so: suite.addTestCase({ name: "ExampleOfNormalAsyncTest", async test() { InspectorTest.evaluateInPage(`...`); let event = await WI.Manager.awaitEvent(...); let resource = event.data.resource; InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); } }); * inspector/unit-tests/async-test-suite-expected.txt: * inspector/unit-tests/async-test-suite.html: * inspector/unit-tests/target-manager.html: Canonical link: https://commits.webkit.org/194811@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-21 06:52:47 +00:00
async test() {
Web Inspector: Include RuntimeAgent in Workers - evaluate in Worker context https://bugs.webkit.org/show_bug.cgi?id=163835 <rdar://problem/28901465> Reviewed by Brian Burg. Source/WebCore: Tests: inspector/unit-tests/target-manager.html inspector/worker/runtime-basic.html * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * inspector/InspectorAllInOne.cpp: New file. * inspector/InspectorWebAgentBase.h: (WebCore::WorkerAgentContext::WorkerAgentContext): New agent context creation struct for Workers. * inspector/WorkerInspectorController.cpp: (WebCore::WorkerInspectorController::WorkerInspectorController): Create a RuntimeAgent for Workers. * inspector/WorkerRuntimeAgent.cpp: Added. (WebCore::WorkerRuntimeAgent::WorkerRuntimeAgent): (WebCore::WorkerRuntimeAgent::didCreateFrontendAndBackend): (WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend): (WebCore::WorkerRuntimeAgent::injectedScriptForEval): * inspector/WorkerRuntimeAgent.h: Added. Workers currently only ever have a single execution context. Source/WebInspectorUI: This introduces the idea that the frontend may communication with multiple backend "Targets" which each have their own set of Agents. - WebInspector.Target - has its own list of Agents - has a InspectorBackend.Connection to communicate with the backend - WebInspector.mainTarget - always exists and represents the thing we are debugging (Page or JSContext) - WebInspector.targets / WebInspector.targetManager - management of all Targets - create new Targets for Workers This also slowly introduces the concept that Model objects may be tied to a specific Target: - WebInspector.RemoteObject - in order to evaluate JS and interact with this object we must know the target (Page or Worker) - when fetching PropertyDescriptors and other RemoteObjects we must continue to pass on the target Finally this makes the QuickConsole list Worker execution contexts in the context picker so that users can choose a Worker context and evaluate JavaScript in that context using the console. * Localizations/en.lproj/localizedStrings.js: * UserInterface/Main.html: * UserInterface/Base/Main.js: (WebInspector.loaded): * UserInterface/Test.html: * UserInterface/Test/Test.js: (WebInspector.loaded): New files, strings, and managers. New global WebInspector.mainTarget. New convenience WebInspector.targets. * UserInterface/Protocol/Target.js: Added. (WebInspector.Target): (WebInspector.Target.prototype.get RuntimeAgent): (WebInspector.Target.prototype.get name): (WebInspector.Target.prototype.get type): (WebInspector.Target.prototype.get connection): (WebInspector.Target.prototype.get executionContext): (WebInspector.Target.prototype.get displayName): (WebInspector.Target.prototype._intializeMainTarget): (WebInspector.Target.prototype._initializeNonMainTarget): Target has some basic properties. * UserInterface/Controllers/TargetManager.js: (WebInspector.TargetManager): (WebInspector.TargetManager.prototype.get targets): (WebInspector.TargetManager.prototype.addTarget): (WebInspector.TargetManager.prototype.removeTarget): Holds the list of Targets and events when created / removed. Each target with a RuntimeAgent has an ExecutionContext. * UserInterface/Controllers/WorkerManager.js: (WebInspector.WorkerManager): (WebInspector.WorkerManager.prototype.workerCreated): (WebInspector.WorkerManager.prototype.workerTerminated): (WebInspector.WorkerManager.prototype.dispatchMessageFromWorker): Create / remove / dispatch on a Worker Target. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass): (InspectorBackendClass.prototype.registerCommand): (InspectorBackendClass.prototype.dispatch): (InspectorBackendClass.prototype.runAfterPendingDispatches): (InspectorBackendClass.prototype._agentForDomain): Keep the original implementations and just dispatch to the main connection. (InspectorBackend.Agent): (InspectorBackend.Agent.prototype.get connection): (InspectorBackend.Agent.prototype.set connection): (InspectorBackend.Agent.prototype.get dispatcher): We will share Agent implementations but just give new "copies" a different connection and dispatcher. (InspectorBackend.Command): (InspectorBackend.Command.create): (InspectorBackend.Command.prototype.invoke): (InspectorBackend.Command.prototype.supports): We continue to have a single Command instance on the Agent. However instead of using the hardcoded Agent on the Instance when evaluated as a function it uses the `this` object which should be an agent. This way: target1.RuntimeAgent.evaluate - `this` is target1 and we use the connection for that target target2.RuntimeAgent.evaluate - `this` is target2 and we use the connection for that target Unfortunately this breaks `RuntimeAgent.evaluate.invoke`. Currently this is solved by providing an extra parameter. In the case where we need to invoke on a particular agent we must provide the agent. target.RuntimeAgent.evaluate.invoke({options}, target.RuntimeAgent) This is unfortunate but only needed in a handful of places right now. (InspectorBackendClass.prototype._sendCommandToBackendWithCallback): Deleted. (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise): Deleted. (InspectorBackendClass.prototype._sendMessageToBackend): Deleted. (InspectorBackendClass.prototype._dispatchResponse): Deleted. (InspectorBackendClass.prototype._dispatchResponseToCallback): Deleted. (InspectorBackendClass.prototype._dispatchResponseToPromise): Deleted. (InspectorBackendClass.prototype._dispatchEvent): Deleted. (InspectorBackendClass.prototype._flushPendingScripts): Deleted. (InspectorBackend.Agent.prototype.get currentDispatchState): Deleted. (InspectorBackend.Command.prototype.deliverFailure): Deleted. * UserInterface/Protocol/Connection.js: Added. (InspectorBackend.Connection): (InspectorBackend.Connection.prototype.get target): (InspectorBackend.Connection.prototype.set target): (InspectorBackend.Connection.prototype.dispatch): (InspectorBackend.Connection.prototype.runAfterPendingDispatches): (InspectorBackend.Connection.prototype.sendMessageToBackend): (InspectorBackend.Connection.prototype._dispatchResponse): (InspectorBackend.Connection.prototype._dispatchResponseToCallback): (InspectorBackend.Connection.prototype._dispatchResponseToPromise): (InspectorBackend.Connection.prototype._dispatchEvent): (InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback): (InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise): (InspectorBackend.Connection.prototype._sendMessageToBackend): (InspectorBackend.Connection.prototype._flushPendingScripts): This extracts the Connection details into its own class. Although we make it appear as though a Target has a list of Agents, we actually have the Connection hold the list of Agents. Instead of cloning the entire Agent we just create a new object extended from the original Agent instance. This allows us to keep the same interface but just change the connection / dispatcher properties within the Agent. (InspectorBackend.MainConnection): (InspectorBackend.MainConnection.prototype.sendMessageToBackend): (InspectorBackend.WorkerConnection): (InspectorBackend.WorkerConnection.sendMessageToBackend): Two different kinds of connections. One for the Main connection and one for Workers. Currently the list of agents we expose on a Worker Target/Connection is hardcoded. * UserInterface/Models/ExecutionContext.js: (WebInspector.ExecutionContext): (WebInspector.ExecutionContext.prototype.get target): We may now have ExecutionContexts that mean a Page, Frames, and Workers. To do this we include the (target, executionContextId) tuple in this object. With this we have everything we need to evaluate JavaScript. * UserInterface/Controllers/RuntimeManager.js: (WebInspector.RuntimeManager): (WebInspector.RuntimeManager.prototype.get activeExecutionContext): (WebInspector.RuntimeManager.prototype.set activeExecutionContext): (WebInspector.RuntimeManager.prototype.get defaultExecutionContextIdentifier): Deleted. (WebInspector.RuntimeManager.prototype.set defaultExecutionContextIdentifier): Deleted. Update from contextId to a full ExecutionContext object. (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow.evalCallback): (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow): (WebInspector.RuntimeManager.prototype.saveResult): (WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject): (WebInspector.RuntimeManager.prototype._frameExecutionContextsCleared): * UserInterface/Controllers/FrameResourceManager.js: (WebInspector.FrameResourceManager.prototype.executionContextCreated): * UserInterface/Controllers/JavaScriptLogViewController.js: (WebInspector.JavaScriptLogViewController.prototype.consolePromptShouldCommitText): * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: Anywhere that wants to use the "activeExecutionContext" must use the specific RuntimeAgent tied to that ExecutionContext's Target. * UserInterface/Models/PropertyDescriptor.js: (WebInspector.PropertyDescriptor.fromPayload): * UserInterface/Protocol/RemoteObject.js: (WebInspector.RemoteObject): (WebInspector.RemoteObject.createFakeRemoteObject): (WebInspector.RemoteObject.fromPrimitiveValue): (WebInspector.RemoteObject.fromPayload): (WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors): (WebInspector.RemoteObject.prototype.deprecatedGetDisplayableProperties): (WebInspector.RemoteObject.prototype.setPropertyValue): (WebInspector.RemoteObject.prototype.getCollectionEntries): (WebInspector.RemoteObject.prototype.releaseWeakCollectionEntries): (WebInspector.RemoteObject.prototype.callFunction): (WebInspector.RemoteObject.prototype.callFunctionJSON): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor.wrappedCallback): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor): (WebInspector.RemoteObject.prototype.release): (WebInspector.RemoteObject.prototype._getPropertyDescriptors): (WebInspector.RemoteObject.prototype._getPropertyDescriptorsResolver): (WebInspector.RemoteObject.prototype._deprecatedGetProperties): RemoteObject and related Model Objects now must be tied to a specific Target, because we need to know which Target it belongs to in order to interact with it further. * UserInterface/Views/QuickConsole.js: (WebInspector.QuickConsole): (WebInspector.QuickConsole.prototype.get selectedExecutionContext): (WebInspector.QuickConsole.prototype.set selectedExecutionContext): (WebInspector.QuickConsole.prototype._executionContextPathComponentsToDisplay): (WebInspector.QuickConsole.prototype._rebuildExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._framePageExecutionContextsChanged): (WebInspector.QuickConsole.prototype._frameExecutionContextsCleared): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): (WebInspector.QuickConsole.prototype._compareExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._insertOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._removeOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._insertExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._removeExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._targetAdded): (WebInspector.QuickConsole.prototype._targetRemoved): (WebInspector.QuickConsole.prototype._pathComponentSelected): (WebInspector.QuickConsole.prototype.get selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype.set selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype._defaultExecutionContextChanged): Deleted. Update the code from executionContextId to ExecutionContext objects. Update the picker with ExecutionContextPathComponent for Workers (new Targets). Generalize and cleanup the code to make it easier to follow. LayoutTests: * inspector/unit-tests/target-manager-expected.txt: Added. * inspector/unit-tests/target-manager.html: Added. Unit test for TargetManager and its events with Worker creation. * inspector/worker/resources/worker-1.js: * inspector/worker/runtime-basic-expected.txt: Added. * inspector/worker/runtime-basic.html: Added. Test comparing RuntimeAgent between Main target and Worker target. * inspector/runtime/change-execution-context-identifier-expected.txt: * inspector/runtime/change-execution-context-identifier.html: RuntimeManager has been updated to have a full ExecutionContext object containing a Target + ContextId instead of just a ContextId. * inspector/console/console-api-expected.txt: * inspector/console/console-api.html: * inspector/console/console-table-expected.txt: * inspector/console/console-table.html: * inspector/debugger/tail-deleted-frames-from-vm-entry.html: * inspector/debugger/tail-deleted-frames.html: * inspector/debugger/tail-recursion.html: * inspector/model/remote-object-expected.txt: * inspector/model/remote-object-weak-collection-expected.txt: * inspector/model/remote-object-weak-collection.html: * inspector/model/remote-object.html: * platform/mac/inspector/model/remote-object-expected.txt: Introduce a better JSON Filter for RemoteObject in more tests. It is important that we filter the _target, because otherwise JSON.stringify would throw an error about cycles. Canonical link: https://commits.webkit.org/181797@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208009 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-27 22:19:12 +00:00
InspectorTest.evaluateInPage("terminateWorker()");
Web Inspector: Support `async test() { ... }` in Inspector Test Suites https://bugs.webkit.org/show_bug.cgi?id=178614 Patch by Joseph Pecoraro <pecoraro@apple.com> on 2017-10-20 Reviewed by Devin Rousso. Add the ability to have test functions be async functions. A successful async test function just needs to complete evaluation. To indicate failure it should throw an exception. suite.addTestCase({ name: "ExceptionOfNormal", async test() { InspectorTest.expectThat(...); } }); suite.addTestCase({ name: "ExampleOfRejection", async test() { let value = await SomeAgent.method(); if (value.error) throw "Exception"; ... } }); Using async test functions has the added benefit that a runtime exception inside of asynchronous test code will reject the current test case instead of timing out. For example... suite.addTestCase({ name: "ExampleOfRejectionThroughRuntimeException", async test() { let arr = []; arr.this.does.not.exist; } }); ... should will lead to a failure instead of a timeout. This should allow us to structure some common tests more naturally, like so: suite.addTestCase({ name: "ExampleOfNormalAsyncTest", async test() { InspectorTest.evaluateInPage(`...`); let event = await WI.Manager.awaitEvent(...); let resource = event.data.resource; InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); } }); * inspector/unit-tests/async-test-suite-expected.txt: * inspector/unit-tests/async-test-suite.html: * inspector/unit-tests/target-manager.html: Canonical link: https://commits.webkit.org/194811@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-21 06:52:47 +00:00
let event = await WI.targetManager.awaitEvent(WI.TargetManager.Event.TargetRemoved);
let target = event.data.target;
InspectorTest.assert(target instanceof WI.Target);
Web Inspector: rework frontend agent construction to allow commands/events to be controlled by the related target's type https://bugs.webkit.org/show_bug.cgi?id=200384 <rdar://problem/53850352> Reviewed by Joseph Pecoraro. Source/JavaScriptCore: * inspector/scripts/codegen/generate_js_backend_commands.py: (JSBackendCommandsGenerator.generate_domain): (JSBackendCommandsGenerator.generate_domain.generate_parameter_object): * inspector/scripts/codegen/models.py: (validate_target_types): Added. (Protocol.parse_domain): (Protocol.parse_command): (Protocol.parse_event): (Domain.__init__): (Domains): (Command.__init__): (Event.__init__): * inspector/protocol/ApplicationCache.json: * inspector/protocol/Audit.json: * inspector/protocol/CPUProfiler.json: * inspector/protocol/CSS.json: * inspector/protocol/Canvas.json: * inspector/protocol/Console.json: * inspector/protocol/DOM.json: * inspector/protocol/DOMDebugger.json: * inspector/protocol/DOMStorage.json: * inspector/protocol/Database.json: * inspector/protocol/Debugger.json: * inspector/protocol/Heap.json: * inspector/protocol/IndexedDB.json: * inspector/protocol/Inspector.json: * inspector/protocol/LayerTree.json: * inspector/protocol/Memory.json: * inspector/protocol/Network.json: * inspector/protocol/Page.json: * inspector/protocol/Recording.json: * inspector/protocol/Runtime.json: * inspector/protocol/ScriptProfiler.json: * inspector/protocol/Security.json: * inspector/protocol/ServiceWorker.json: * inspector/protocol/Target.json: * inspector/protocol/Timeline.json: * inspector/protocol/Worker.json: Add `debuggableTypes` and `targetTypes` arrays to domains/commands/events that are used when generating InspectorBackendCommands.js for more accurate compatibility checks. * inspector/InspectorTarget.h: * inspector/agents/InspectorTargetAgent.h: * inspector/agents/InspectorTargetAgent.cpp: (Inspector::targetTypeToProtocolType): (Inspector::InspectorTargetAgent::exists): Deleted. Remove `Target.exists` now that the frontend can do proper feature checking. * inspector/remote/RemoteControllableTarget.h: * inspector/remote/RemoteInspectionTarget.h: * inspector/remote/RemoteInspectorConstants.h: * inspector/remote/cocoa/RemoteInspectorCocoa.mm: (Inspector::RemoteInspector::listingForInspectionTarget const): * inspector/remote/glib/RemoteInspectorGlib.cpp: (Inspector::RemoteInspector::listingForInspectionTarget const): * inspector/remote/socket/RemoteInspectorSocket.cpp: (Inspector::RemoteInspector::listingForInspectionTarget const): Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). * inspector/scripts/tests/all/expected/definitions-with-mac-platform.json-result: * inspector/scripts/tests/generic/command-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/domain-availability.json: Removed. * inspector/scripts/tests/generic/domain-debuggableTypes.json: Added. * inspector/scripts/tests/generic/domain-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/domain-targetTypes.json: Added. * inspector/scripts/tests/generic/event-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/expected/command-targetType-matching-domain-debuggableType.json-result: Added. * inspector/scripts/tests/generic/expected/commands-with-async-attribute.json-result: * inspector/scripts/tests/generic/expected/commands-with-optional-call-return-parameters.json-result: * inspector/scripts/tests/generic/expected/domain-debuggableTypes.json-result: Added. * inspector/scripts/tests/generic/expected/domain-targetType-matching-domain-debuggableType.json-result: Added. * inspector/scripts/tests/generic/expected/domain-targetTypes.json-result: Added. * inspector/scripts/tests/generic/expected/domains-with-varying-command-sizes.json-result: * inspector/scripts/tests/generic/expected/enum-values.json-result: * inspector/scripts/tests/generic/expected/event-targetType-matching-domain-debuggableType.json-result: Added. * inspector/scripts/tests/generic/expected/events-with-optional-parameters.json-result: * inspector/scripts/tests/generic/expected/fail-on-command-targetType-matching-domain-debuggableType.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-command-targetTypes-type.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-command-targetTypes-value.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-availability-type.json-error: Removed. * inspector/scripts/tests/generic/expected/fail-on-domain-availability-value.json-error: Removed. * inspector/scripts/tests/generic/expected/fail-on-domain-availability.json-error: Removed. * inspector/scripts/tests/generic/expected/fail-on-domain-debuggableTypes-type.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-debuggableTypes-value.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-targetType-matching-domain-debuggableType.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-targetTypes-type.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-domain-targetTypes-value.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-event-targetType-matching-domain-debuggableType.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-event-targetTypes-type.json-error: Added. * inspector/scripts/tests/generic/expected/fail-on-event-targetTypes-value.json-error: Added. * inspector/scripts/tests/generic/expected/generate-domains-with-feature-guards.json-result: * inspector/scripts/tests/generic/expected/type-declaration-array-type.json-result: * inspector/scripts/tests/generic/expected/type-declaration-enum-type.json-result: * inspector/scripts/tests/generic/expected/type-declaration-object-type.json-result: * inspector/scripts/tests/generic/expected/type-requiring-runtime-casts.json-result: * inspector/scripts/tests/generic/expected/version.json-result: * inspector/scripts/tests/generic/fail-on-command-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/fail-on-command-targetTypes-type.json: Added. * inspector/scripts/tests/generic/fail-on-command-targetTypes-value.json: Added. * inspector/scripts/tests/generic/fail-on-domain-debuggableTypes-type.json: Added. * inspector/scripts/tests/generic/fail-on-domain-debuggableTypes-value.json: Added. * inspector/scripts/tests/generic/fail-on-domain-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/fail-on-domain-targetTypes-type.json: Added. * inspector/scripts/tests/generic/fail-on-domain-targetTypes-value.json: Added. * inspector/scripts/tests/generic/fail-on-event-targetType-matching-domain-debuggableType.json: Added. * inspector/scripts/tests/generic/fail-on-event-targetTypes-type.json: Added. * inspector/scripts/tests/generic/fail-on-event-targetTypes-value.json: Added. * inspector/scripts/tests/mac/expected/definitions-with-mac-platform.json-result: Update test results, as well as added new tests for `debuggableTypes` and `targetTypes`. Source/WebCore: * inspector/InspectorFrontendClient.h: (WebCore::InspectorFrontendClient::backendCommandsURL): Deleted. (WebCore::InspectorFrontendClient::debuggableType): Deleted. * inspector/InspectorFrontendClientLocal.h: * page/PageDebuggable.h: (WebCore::PageDebuggable::type const): * testing/Internals.cpp: (WebCore::InspectorStubFrontend::debuggableType const): Added. Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). Source/WebInspectorUI: `InspectorBackend.domains.${domain}` isn't a truly valid way to feature check, as it indicates what's supported by the WebKit framework underlying whatever's currently being inspected, not what the current inspection target supports. As an example, inspecting an iOS `JSContext` will still show `InspectorBackend.domains.DOM` as the `DOMAgent` is supported by WebKit, even though `JSContext`s have no concept of the DOM. In this example, however, `window.DOMAgent` would NOT exist, as the `availability` check for the `DOM` domain wouldn't pass, meaning that the agent never gets connected. In order to do proper feature checking, `InspectorBackend.domains` needs to be accurate depending on the debuggable type. Furthermore, each target underneath that debuggable needs to be able to "choose" what commands/events are supported based on that target's type. This patch modifies how InspectorBackendCommands.js ties into `InspectorBackend`. Rather than directly creating an `InspectorBackend.Agent` for each domain, we now create more of a "blueprint" of the domain, and wait to actually create an `InspectorBackend.Agent` until we have a `WI.Target` (and therefore an `InspectorBackend.Connection`). Each "concept" of the protocol now directly maps to an object. - InspectorBackend.Domain - InspectorBackend.Command - InspectorBackend.Event - InspectorBackend.Dispatcher When a `WI.Target` is created, it gets the list of `InspectorBackend.Domain` that support that `WI.Target`'s type (specified in the protocol JSON files) and generates an `InspectorBackend.Agent` for each, which in turn generates an `InspectorBackend.Callable` for each supported `InspectorBackend.Command` and instantiates `InspectorBackend.Dispatcher`. Activating a `InspectorBackend.Domain` means it's visible for `InspectorBackend` feature checking. This must be done this way for older ITML backends that will still appear as "JSContext" targets and therefore go through the "extra domains" path. Ideally, the process of registering a domain should be enough to activate it. <https://webkit.org/b/201150> Feature checking can now only be done via `hasDomain`, `hasCommand`, and `hasEvent` on `InspectorBackend` or a specific `WI.Target`, and there are different implications for each: - `InspectorBackend.hasDomain(DOM)` asks whether the `DOM` domain is supported by the current debuggable, but says nothing about whether any `WI.Target` support `DOM`. - `target.hasDomain("DOM")` asks whether the given `target` supports `DOM`, which is limited by `InspectorBackend.hasDomain("DOM")`. Now that `InspectorBackend.Agent` is only created by a `WI.Target`, it's no longer valid to write `window.DOMAgent`, as there is no "global" agent. All protocol logic _must_ go through a `WI.Target`. <https://webkit.org/b/201149> Debuggable Types: - JavaScript (JSC::JSGlobalObject) - Page (WebCore::Page) - ServiceWorker (WebCore::ServiceWorkerThreadProxy) - WebPage (WebKit::WebPageProxy) Target Types: - JavaScript (direct connection) - Page (multi-target connection to any Worker) - ServiceWorker (direct connection) - WebPage (multi-target connection to 1+ Page) - Worker (direct connection, only available for Page debuggables) * UserInterface/Base/DebuggableType.js: * UserInterface/Base/TargetType.js: Copied from Source/WebInspectorUI/UserInterface/Base/DebuggableType.js. * UserInterface/Protocol/Connection.js: * UserInterface/Protocol/InspectorBackend.js: * UserInterface/Protocol/ApplicationCacheObserver.js: * UserInterface/Protocol/CPUProfilerObserver.js: * UserInterface/Protocol/CSSObserver.js: * UserInterface/Protocol/CanvasObserver.js: * UserInterface/Protocol/ConsoleObserver.js: * UserInterface/Protocol/DOMObserver.js: * UserInterface/Protocol/DOMStorageObserver.js: * UserInterface/Protocol/DatabaseObserver.js: * UserInterface/Protocol/DebuggerObserver.js: * UserInterface/Protocol/HeapObserver.js: * UserInterface/Protocol/InspectorObserver.js: * UserInterface/Protocol/LayerTreeObserver.js: * UserInterface/Protocol/MemoryObserver.js: * UserInterface/Protocol/NetworkObserver.js: * UserInterface/Protocol/PageObserver.js: * UserInterface/Protocol/RuntimeObserver.js: * UserInterface/Protocol/ScriptProfilerObserver.js: * UserInterface/Protocol/TargetObserver.js: * UserInterface/Protocol/TimelineObserver.js: * UserInterface/Protocol/WorkerObserver.js: All observers now extend from `InspectorBackend.Dispatcher` and have a separate instance for each `InspectorBackend.Agent`, each having their own `_target`. * UserInterface/Protocol/Target.js: * UserInterface/Protocol/DirectBackendTarget.js: * UserInterface/Protocol/JavaScriptContextTarget.js: Removed. * UserInterface/Protocol/MultiplexingBackendTarget.js: * UserInterface/Protocol/PageTarget.js: * UserInterface/Protocol/WorkerTarget.js: Agents are now created per-target instead of copied from the "global" list. This means that agents can have a different set of commands/events depending on the associated target. * UserInterface/Base/Main.js: * UserInterface/Base/Utilities.js: * UserInterface/Controllers/AppController.js: * UserInterface/Controllers/AppControllerBase.js: * UserInterface/Controllers/ApplicationCacheManager.js: * UserInterface/Controllers/AuditManager.js: * UserInterface/Controllers/BreakpointPopoverController.js: * UserInterface/Controllers/CSSManager.js: * UserInterface/Controllers/CanvasManager.js: * UserInterface/Controllers/ConsoleManager.js: * UserInterface/Controllers/DOMDebuggerManager.js: * UserInterface/Controllers/DOMManager.js: * UserInterface/Controllers/DOMStorageManager.js: * UserInterface/Controllers/DatabaseManager.js: * UserInterface/Controllers/DebuggerManager.js: * UserInterface/Controllers/HeapManager.js: * UserInterface/Controllers/IndexedDBManager.js: * UserInterface/Controllers/JavaScriptLogViewController.js: * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: * UserInterface/Controllers/LayerTreeManager.js: * UserInterface/Controllers/MemoryManager.js: * UserInterface/Controllers/NetworkManager.js: * UserInterface/Controllers/RuntimeManager.js: * UserInterface/Controllers/TargetManager.js: * UserInterface/Controllers/TimelineManager.js: * UserInterface/Controllers/WorkerManager.js: * UserInterface/Main.html: * UserInterface/Models/AuditTestBase.js: * UserInterface/Models/AuditTestCase.js: * UserInterface/Models/AuditTestCaseResult.js: * UserInterface/Models/CPUInstrument.js: * UserInterface/Models/CPUTimelineRecord.js: * UserInterface/Models/CSSCompletions.js: * UserInterface/Models/CSSStyleSheet.js: * UserInterface/Models/Canvas.js: * UserInterface/Models/DOMNode.js: * UserInterface/Models/DOMNodeStyles.js: * UserInterface/Models/DOMStorageObject.js: * UserInterface/Models/DOMTree.js: * UserInterface/Models/DatabaseObject.js: * UserInterface/Models/FPSInstrument.js: * UserInterface/Models/GarbageCollection.js: * UserInterface/Models/HeapAllocationsInstrument.js: * UserInterface/Models/Instrument.js: * UserInterface/Models/MediaInstrument.js: * UserInterface/Models/MemoryInstrument.js: * UserInterface/Models/MemoryPressureEvent.js: * UserInterface/Models/MemoryTimelineRecord.js: * UserInterface/Models/Recording.js: * UserInterface/Models/Resource.js: * UserInterface/Models/ScriptInstrument.js: * UserInterface/Models/ScriptSyntaxTree.js: * UserInterface/Models/ScriptTimelineRecord.js: * UserInterface/Models/ShaderProgram.js: * UserInterface/Models/SourceMapResource.js: * UserInterface/Models/TimelineRecording.js: * UserInterface/Protocol/RemoteObject.js: * UserInterface/Test.html: * UserInterface/Test/FrontendTestHarness.js: * UserInterface/Test/Test.js: * UserInterface/Test/TestAppController.js: * UserInterface/Views/AuditNavigationSidebarPanel.js: * UserInterface/Views/AuditTabContentView.js: * UserInterface/Views/CanvasTabContentView.js: * UserInterface/Views/ContextMenuUtilities.js: * UserInterface/Views/CookieStorageContentView.js: * UserInterface/Views/DOMNodeDetailsSidebarPanel.js: * UserInterface/Views/DOMTreeContentView.js: * UserInterface/Views/ElementsTabContentView.js: * UserInterface/Views/IndexedDatabaseDetailsSidebarPanel.js: * UserInterface/Views/Layers3DContentView.js: * UserInterface/Views/LayersTabContentView.js: * UserInterface/Views/LayoutTimelineView.js: * UserInterface/Views/LogContentView.js: * UserInterface/Views/NetworkTabContentView.js: * UserInterface/Views/NetworkTableContentView.js: * UserInterface/Views/NetworkTimelineView.js: * UserInterface/Views/ObjectTreeView.js: * UserInterface/Views/QuickConsole.js: * UserInterface/Views/ResourceDetailsSidebarPanel.js: * UserInterface/Views/ScriptClusterTimelineView.js: * UserInterface/Views/ScriptDetailsTimelineView.js: * UserInterface/Views/ScriptTreeElement.js: * UserInterface/Views/SearchSidebarPanel.js: * UserInterface/Views/SearchTabContentView.js: * UserInterface/Views/SettingsTabContentView.js: * UserInterface/Views/SourceCodeTextEditor.js: * UserInterface/Views/SourcesNavigationSidebarPanel.js: * UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js: * UserInterface/Views/SpreadsheetStyleProperty.js: * UserInterface/Views/StorageTabContentView.js: * UserInterface/Views/TimelineRecordingContentView.js: * UserInterface/Views/TimelineTabContentView.js: * UserInterface/Views/Toolbar.js: * UserInterface/Views/WebSocketContentView.js: * UserInterface/Views/WorkerTreeElement.js: Replace all instances of `window.DomainAgent` with `target.DomainAgent`, where `target` is either derived from an associated model object or `WI.assumingMainTarget()`. Split the `WI.DebuggableType.Web` debuggable type into `WI.DebuggableType.Page` (WebCore::Page) and `WI.DebuggableType.WebPage` (WebKit::WebPageProxy). * UserInterface/Protocol/Legacy/*: * Versions/*: Update protocol files for older versions of iOS. * .eslintrc: * Localizations/en.lproj/localizedStrings.js: Source/WebKit: * WebProcess/WebPage/RemoteWebInspectorUI.h: (WebKit::WebInspectorUI::backendCommandsURL const): Added. (WebKit::WebInspectorUI::debuggableType const): Added. (WebKit::WebInspectorUI::backendCommandsURL): Deleted. (WebKit::WebInspectorUI::debuggableType): Deleted. * WebProcess/WebPage/WebInspectorUI.h: (WebKit::WebInspectorUI::backendCommandsURL const): Added. (WebKit::WebInspectorUI::debuggableType const): Added. * UIProcess/WebPageDebuggable.h: (WebKit::WebPageDebuggable::type const): * UIProcess/glib/RemoteInspectorClient.cpp: (WebKit::RemoteInspectorClient::RemoteInspectorClient): * UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.h: * UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm: (debuggableTypeString): Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). Source/WebKitLegacy/mac: * WebCoreSupport/WebInspectorClient.h: (WebInspectorFrontendClient::debuggableType const): Added. Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). Source/WebKitLegacy/win: * WebCoreSupport/WebInspectorClient.h: (WebInspectorFrontendClient::debuggableType const): Added. Split the `Web` debuggable type into `Page` (WebCore::Page) and `WebPage` (WebKit::WebPageProxy). LayoutTests: * inspector/canvas/requestShaderSource-webgl.html: * inspector/canvas/updateShader-webgl: * inspector/page/overrideSetting.html: * inspector/page/overrideSetting-ICECandidateFilteringEnabled.html: * inspector/page/overrideSetting-MockCaptureDevicesEnabled.html: * inspector/runtime/parse.html: Replace all instances of `DomainAgent.Enum` with `InspectorBackend.domains.Domain.Enum`. * inspector/audit/run.html: * inspector/audit/version.html: * inspector/recording/version.html: Use new `InspectorBackend` methods. * inspector/unit-tests/target-manager.html: * inspector/unit-tests/target-manager-expected.txt: * inspector/worker/console-basic.html: * inspector/worker/debugger-pause.html: * inspector/worker/debugger-scripts.html: * inspector/worker/debugger-shared-breakpoint.html: * inspector/worker/resources-in-worker.html: * inspector/worker/resources/dom-debugger-utilities.js: * inspector/worker/runtime-basic.html: * http/tests/inspector/worker/blob-script-with-cross-domain-imported-scripts.html: Replace `WI.Target.Type` with `WI.TargetType`. * inspector/dom/inspect.html: * inspector/dom/inspect-expected.txt: Rewrite test since faking events from the backend now requires a target. * inspector/unit-tests/set-utilities.html: * inspector/unit-tests/set-utilities-expected.txt: Add tests for `Set.prototype.addAll`. Canonical link: https://commits.webkit.org/216493@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251227 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2019-10-17 08:00:46 +00:00
InspectorTest.expectEqual(target.type, WI.TargetType.Worker, "Removed Target should have Worker type.");
Web Inspector: Support `async test() { ... }` in Inspector Test Suites https://bugs.webkit.org/show_bug.cgi?id=178614 Patch by Joseph Pecoraro <pecoraro@apple.com> on 2017-10-20 Reviewed by Devin Rousso. Add the ability to have test functions be async functions. A successful async test function just needs to complete evaluation. To indicate failure it should throw an exception. suite.addTestCase({ name: "ExceptionOfNormal", async test() { InspectorTest.expectThat(...); } }); suite.addTestCase({ name: "ExampleOfRejection", async test() { let value = await SomeAgent.method(); if (value.error) throw "Exception"; ... } }); Using async test functions has the added benefit that a runtime exception inside of asynchronous test code will reject the current test case instead of timing out. For example... suite.addTestCase({ name: "ExampleOfRejectionThroughRuntimeException", async test() { let arr = []; arr.this.does.not.exist; } }); ... should will lead to a failure instead of a timeout. This should allow us to structure some common tests more naturally, like so: suite.addTestCase({ name: "ExampleOfNormalAsyncTest", async test() { InspectorTest.evaluateInPage(`...`); let event = await WI.Manager.awaitEvent(...); let resource = event.data.resource; InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); InspectorTest.expectEqual(...); } }); * inspector/unit-tests/async-test-suite-expected.txt: * inspector/unit-tests/async-test-suite.html: * inspector/unit-tests/target-manager.html: Canonical link: https://commits.webkit.org/194811@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223809 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-10-21 06:52:47 +00:00
dumpTargets();
Web Inspector: Include RuntimeAgent in Workers - evaluate in Worker context https://bugs.webkit.org/show_bug.cgi?id=163835 <rdar://problem/28901465> Reviewed by Brian Burg. Source/WebCore: Tests: inspector/unit-tests/target-manager.html inspector/worker/runtime-basic.html * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * inspector/InspectorAllInOne.cpp: New file. * inspector/InspectorWebAgentBase.h: (WebCore::WorkerAgentContext::WorkerAgentContext): New agent context creation struct for Workers. * inspector/WorkerInspectorController.cpp: (WebCore::WorkerInspectorController::WorkerInspectorController): Create a RuntimeAgent for Workers. * inspector/WorkerRuntimeAgent.cpp: Added. (WebCore::WorkerRuntimeAgent::WorkerRuntimeAgent): (WebCore::WorkerRuntimeAgent::didCreateFrontendAndBackend): (WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend): (WebCore::WorkerRuntimeAgent::injectedScriptForEval): * inspector/WorkerRuntimeAgent.h: Added. Workers currently only ever have a single execution context. Source/WebInspectorUI: This introduces the idea that the frontend may communication with multiple backend "Targets" which each have their own set of Agents. - WebInspector.Target - has its own list of Agents - has a InspectorBackend.Connection to communicate with the backend - WebInspector.mainTarget - always exists and represents the thing we are debugging (Page or JSContext) - WebInspector.targets / WebInspector.targetManager - management of all Targets - create new Targets for Workers This also slowly introduces the concept that Model objects may be tied to a specific Target: - WebInspector.RemoteObject - in order to evaluate JS and interact with this object we must know the target (Page or Worker) - when fetching PropertyDescriptors and other RemoteObjects we must continue to pass on the target Finally this makes the QuickConsole list Worker execution contexts in the context picker so that users can choose a Worker context and evaluate JavaScript in that context using the console. * Localizations/en.lproj/localizedStrings.js: * UserInterface/Main.html: * UserInterface/Base/Main.js: (WebInspector.loaded): * UserInterface/Test.html: * UserInterface/Test/Test.js: (WebInspector.loaded): New files, strings, and managers. New global WebInspector.mainTarget. New convenience WebInspector.targets. * UserInterface/Protocol/Target.js: Added. (WebInspector.Target): (WebInspector.Target.prototype.get RuntimeAgent): (WebInspector.Target.prototype.get name): (WebInspector.Target.prototype.get type): (WebInspector.Target.prototype.get connection): (WebInspector.Target.prototype.get executionContext): (WebInspector.Target.prototype.get displayName): (WebInspector.Target.prototype._intializeMainTarget): (WebInspector.Target.prototype._initializeNonMainTarget): Target has some basic properties. * UserInterface/Controllers/TargetManager.js: (WebInspector.TargetManager): (WebInspector.TargetManager.prototype.get targets): (WebInspector.TargetManager.prototype.addTarget): (WebInspector.TargetManager.prototype.removeTarget): Holds the list of Targets and events when created / removed. Each target with a RuntimeAgent has an ExecutionContext. * UserInterface/Controllers/WorkerManager.js: (WebInspector.WorkerManager): (WebInspector.WorkerManager.prototype.workerCreated): (WebInspector.WorkerManager.prototype.workerTerminated): (WebInspector.WorkerManager.prototype.dispatchMessageFromWorker): Create / remove / dispatch on a Worker Target. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass): (InspectorBackendClass.prototype.registerCommand): (InspectorBackendClass.prototype.dispatch): (InspectorBackendClass.prototype.runAfterPendingDispatches): (InspectorBackendClass.prototype._agentForDomain): Keep the original implementations and just dispatch to the main connection. (InspectorBackend.Agent): (InspectorBackend.Agent.prototype.get connection): (InspectorBackend.Agent.prototype.set connection): (InspectorBackend.Agent.prototype.get dispatcher): We will share Agent implementations but just give new "copies" a different connection and dispatcher. (InspectorBackend.Command): (InspectorBackend.Command.create): (InspectorBackend.Command.prototype.invoke): (InspectorBackend.Command.prototype.supports): We continue to have a single Command instance on the Agent. However instead of using the hardcoded Agent on the Instance when evaluated as a function it uses the `this` object which should be an agent. This way: target1.RuntimeAgent.evaluate - `this` is target1 and we use the connection for that target target2.RuntimeAgent.evaluate - `this` is target2 and we use the connection for that target Unfortunately this breaks `RuntimeAgent.evaluate.invoke`. Currently this is solved by providing an extra parameter. In the case where we need to invoke on a particular agent we must provide the agent. target.RuntimeAgent.evaluate.invoke({options}, target.RuntimeAgent) This is unfortunate but only needed in a handful of places right now. (InspectorBackendClass.prototype._sendCommandToBackendWithCallback): Deleted. (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise): Deleted. (InspectorBackendClass.prototype._sendMessageToBackend): Deleted. (InspectorBackendClass.prototype._dispatchResponse): Deleted. (InspectorBackendClass.prototype._dispatchResponseToCallback): Deleted. (InspectorBackendClass.prototype._dispatchResponseToPromise): Deleted. (InspectorBackendClass.prototype._dispatchEvent): Deleted. (InspectorBackendClass.prototype._flushPendingScripts): Deleted. (InspectorBackend.Agent.prototype.get currentDispatchState): Deleted. (InspectorBackend.Command.prototype.deliverFailure): Deleted. * UserInterface/Protocol/Connection.js: Added. (InspectorBackend.Connection): (InspectorBackend.Connection.prototype.get target): (InspectorBackend.Connection.prototype.set target): (InspectorBackend.Connection.prototype.dispatch): (InspectorBackend.Connection.prototype.runAfterPendingDispatches): (InspectorBackend.Connection.prototype.sendMessageToBackend): (InspectorBackend.Connection.prototype._dispatchResponse): (InspectorBackend.Connection.prototype._dispatchResponseToCallback): (InspectorBackend.Connection.prototype._dispatchResponseToPromise): (InspectorBackend.Connection.prototype._dispatchEvent): (InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback): (InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise): (InspectorBackend.Connection.prototype._sendMessageToBackend): (InspectorBackend.Connection.prototype._flushPendingScripts): This extracts the Connection details into its own class. Although we make it appear as though a Target has a list of Agents, we actually have the Connection hold the list of Agents. Instead of cloning the entire Agent we just create a new object extended from the original Agent instance. This allows us to keep the same interface but just change the connection / dispatcher properties within the Agent. (InspectorBackend.MainConnection): (InspectorBackend.MainConnection.prototype.sendMessageToBackend): (InspectorBackend.WorkerConnection): (InspectorBackend.WorkerConnection.sendMessageToBackend): Two different kinds of connections. One for the Main connection and one for Workers. Currently the list of agents we expose on a Worker Target/Connection is hardcoded. * UserInterface/Models/ExecutionContext.js: (WebInspector.ExecutionContext): (WebInspector.ExecutionContext.prototype.get target): We may now have ExecutionContexts that mean a Page, Frames, and Workers. To do this we include the (target, executionContextId) tuple in this object. With this we have everything we need to evaluate JavaScript. * UserInterface/Controllers/RuntimeManager.js: (WebInspector.RuntimeManager): (WebInspector.RuntimeManager.prototype.get activeExecutionContext): (WebInspector.RuntimeManager.prototype.set activeExecutionContext): (WebInspector.RuntimeManager.prototype.get defaultExecutionContextIdentifier): Deleted. (WebInspector.RuntimeManager.prototype.set defaultExecutionContextIdentifier): Deleted. Update from contextId to a full ExecutionContext object. (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow.evalCallback): (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow): (WebInspector.RuntimeManager.prototype.saveResult): (WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject): (WebInspector.RuntimeManager.prototype._frameExecutionContextsCleared): * UserInterface/Controllers/FrameResourceManager.js: (WebInspector.FrameResourceManager.prototype.executionContextCreated): * UserInterface/Controllers/JavaScriptLogViewController.js: (WebInspector.JavaScriptLogViewController.prototype.consolePromptShouldCommitText): * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: Anywhere that wants to use the "activeExecutionContext" must use the specific RuntimeAgent tied to that ExecutionContext's Target. * UserInterface/Models/PropertyDescriptor.js: (WebInspector.PropertyDescriptor.fromPayload): * UserInterface/Protocol/RemoteObject.js: (WebInspector.RemoteObject): (WebInspector.RemoteObject.createFakeRemoteObject): (WebInspector.RemoteObject.fromPrimitiveValue): (WebInspector.RemoteObject.fromPayload): (WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors): (WebInspector.RemoteObject.prototype.deprecatedGetDisplayableProperties): (WebInspector.RemoteObject.prototype.setPropertyValue): (WebInspector.RemoteObject.prototype.getCollectionEntries): (WebInspector.RemoteObject.prototype.releaseWeakCollectionEntries): (WebInspector.RemoteObject.prototype.callFunction): (WebInspector.RemoteObject.prototype.callFunctionJSON): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor.wrappedCallback): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor): (WebInspector.RemoteObject.prototype.release): (WebInspector.RemoteObject.prototype._getPropertyDescriptors): (WebInspector.RemoteObject.prototype._getPropertyDescriptorsResolver): (WebInspector.RemoteObject.prototype._deprecatedGetProperties): RemoteObject and related Model Objects now must be tied to a specific Target, because we need to know which Target it belongs to in order to interact with it further. * UserInterface/Views/QuickConsole.js: (WebInspector.QuickConsole): (WebInspector.QuickConsole.prototype.get selectedExecutionContext): (WebInspector.QuickConsole.prototype.set selectedExecutionContext): (WebInspector.QuickConsole.prototype._executionContextPathComponentsToDisplay): (WebInspector.QuickConsole.prototype._rebuildExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._framePageExecutionContextsChanged): (WebInspector.QuickConsole.prototype._frameExecutionContextsCleared): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): (WebInspector.QuickConsole.prototype._compareExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._insertOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._removeOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._insertExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._removeExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._targetAdded): (WebInspector.QuickConsole.prototype._targetRemoved): (WebInspector.QuickConsole.prototype._pathComponentSelected): (WebInspector.QuickConsole.prototype.get selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype.set selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype._defaultExecutionContextChanged): Deleted. Update the code from executionContextId to ExecutionContext objects. Update the picker with ExecutionContextPathComponent for Workers (new Targets). Generalize and cleanup the code to make it easier to follow. LayoutTests: * inspector/unit-tests/target-manager-expected.txt: Added. * inspector/unit-tests/target-manager.html: Added. Unit test for TargetManager and its events with Worker creation. * inspector/worker/resources/worker-1.js: * inspector/worker/runtime-basic-expected.txt: Added. * inspector/worker/runtime-basic.html: Added. Test comparing RuntimeAgent between Main target and Worker target. * inspector/runtime/change-execution-context-identifier-expected.txt: * inspector/runtime/change-execution-context-identifier.html: RuntimeManager has been updated to have a full ExecutionContext object containing a Target + ContextId instead of just a ContextId. * inspector/console/console-api-expected.txt: * inspector/console/console-api.html: * inspector/console/console-table-expected.txt: * inspector/console/console-table.html: * inspector/debugger/tail-deleted-frames-from-vm-entry.html: * inspector/debugger/tail-deleted-frames.html: * inspector/debugger/tail-recursion.html: * inspector/model/remote-object-expected.txt: * inspector/model/remote-object-weak-collection-expected.txt: * inspector/model/remote-object-weak-collection.html: * inspector/model/remote-object.html: * platform/mac/inspector/model/remote-object-expected.txt: Introduce a better JSON Filter for RemoteObject in more tests. It is important that we filter the _target, because otherwise JSON.stringify would throw an error about cycles. Canonical link: https://commits.webkit.org/181797@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208009 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-27 22:19:12 +00:00
}
});
suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Test for TargetManager and other global WI.Target objects.</p>
Web Inspector: Include RuntimeAgent in Workers - evaluate in Worker context https://bugs.webkit.org/show_bug.cgi?id=163835 <rdar://problem/28901465> Reviewed by Brian Burg. Source/WebCore: Tests: inspector/unit-tests/target-manager.html inspector/worker/runtime-basic.html * CMakeLists.txt: * WebCore.xcodeproj/project.pbxproj: * inspector/InspectorAllInOne.cpp: New file. * inspector/InspectorWebAgentBase.h: (WebCore::WorkerAgentContext::WorkerAgentContext): New agent context creation struct for Workers. * inspector/WorkerInspectorController.cpp: (WebCore::WorkerInspectorController::WorkerInspectorController): Create a RuntimeAgent for Workers. * inspector/WorkerRuntimeAgent.cpp: Added. (WebCore::WorkerRuntimeAgent::WorkerRuntimeAgent): (WebCore::WorkerRuntimeAgent::didCreateFrontendAndBackend): (WebCore::WorkerRuntimeAgent::willDestroyFrontendAndBackend): (WebCore::WorkerRuntimeAgent::injectedScriptForEval): * inspector/WorkerRuntimeAgent.h: Added. Workers currently only ever have a single execution context. Source/WebInspectorUI: This introduces the idea that the frontend may communication with multiple backend "Targets" which each have their own set of Agents. - WebInspector.Target - has its own list of Agents - has a InspectorBackend.Connection to communicate with the backend - WebInspector.mainTarget - always exists and represents the thing we are debugging (Page or JSContext) - WebInspector.targets / WebInspector.targetManager - management of all Targets - create new Targets for Workers This also slowly introduces the concept that Model objects may be tied to a specific Target: - WebInspector.RemoteObject - in order to evaluate JS and interact with this object we must know the target (Page or Worker) - when fetching PropertyDescriptors and other RemoteObjects we must continue to pass on the target Finally this makes the QuickConsole list Worker execution contexts in the context picker so that users can choose a Worker context and evaluate JavaScript in that context using the console. * Localizations/en.lproj/localizedStrings.js: * UserInterface/Main.html: * UserInterface/Base/Main.js: (WebInspector.loaded): * UserInterface/Test.html: * UserInterface/Test/Test.js: (WebInspector.loaded): New files, strings, and managers. New global WebInspector.mainTarget. New convenience WebInspector.targets. * UserInterface/Protocol/Target.js: Added. (WebInspector.Target): (WebInspector.Target.prototype.get RuntimeAgent): (WebInspector.Target.prototype.get name): (WebInspector.Target.prototype.get type): (WebInspector.Target.prototype.get connection): (WebInspector.Target.prototype.get executionContext): (WebInspector.Target.prototype.get displayName): (WebInspector.Target.prototype._intializeMainTarget): (WebInspector.Target.prototype._initializeNonMainTarget): Target has some basic properties. * UserInterface/Controllers/TargetManager.js: (WebInspector.TargetManager): (WebInspector.TargetManager.prototype.get targets): (WebInspector.TargetManager.prototype.addTarget): (WebInspector.TargetManager.prototype.removeTarget): Holds the list of Targets and events when created / removed. Each target with a RuntimeAgent has an ExecutionContext. * UserInterface/Controllers/WorkerManager.js: (WebInspector.WorkerManager): (WebInspector.WorkerManager.prototype.workerCreated): (WebInspector.WorkerManager.prototype.workerTerminated): (WebInspector.WorkerManager.prototype.dispatchMessageFromWorker): Create / remove / dispatch on a Worker Target. * UserInterface/Protocol/InspectorBackend.js: (InspectorBackendClass): (InspectorBackendClass.prototype.registerCommand): (InspectorBackendClass.prototype.dispatch): (InspectorBackendClass.prototype.runAfterPendingDispatches): (InspectorBackendClass.prototype._agentForDomain): Keep the original implementations and just dispatch to the main connection. (InspectorBackend.Agent): (InspectorBackend.Agent.prototype.get connection): (InspectorBackend.Agent.prototype.set connection): (InspectorBackend.Agent.prototype.get dispatcher): We will share Agent implementations but just give new "copies" a different connection and dispatcher. (InspectorBackend.Command): (InspectorBackend.Command.create): (InspectorBackend.Command.prototype.invoke): (InspectorBackend.Command.prototype.supports): We continue to have a single Command instance on the Agent. However instead of using the hardcoded Agent on the Instance when evaluated as a function it uses the `this` object which should be an agent. This way: target1.RuntimeAgent.evaluate - `this` is target1 and we use the connection for that target target2.RuntimeAgent.evaluate - `this` is target2 and we use the connection for that target Unfortunately this breaks `RuntimeAgent.evaluate.invoke`. Currently this is solved by providing an extra parameter. In the case where we need to invoke on a particular agent we must provide the agent. target.RuntimeAgent.evaluate.invoke({options}, target.RuntimeAgent) This is unfortunate but only needed in a handful of places right now. (InspectorBackendClass.prototype._sendCommandToBackendWithCallback): Deleted. (InspectorBackendClass.prototype._sendCommandToBackendExpectingPromise): Deleted. (InspectorBackendClass.prototype._sendMessageToBackend): Deleted. (InspectorBackendClass.prototype._dispatchResponse): Deleted. (InspectorBackendClass.prototype._dispatchResponseToCallback): Deleted. (InspectorBackendClass.prototype._dispatchResponseToPromise): Deleted. (InspectorBackendClass.prototype._dispatchEvent): Deleted. (InspectorBackendClass.prototype._flushPendingScripts): Deleted. (InspectorBackend.Agent.prototype.get currentDispatchState): Deleted. (InspectorBackend.Command.prototype.deliverFailure): Deleted. * UserInterface/Protocol/Connection.js: Added. (InspectorBackend.Connection): (InspectorBackend.Connection.prototype.get target): (InspectorBackend.Connection.prototype.set target): (InspectorBackend.Connection.prototype.dispatch): (InspectorBackend.Connection.prototype.runAfterPendingDispatches): (InspectorBackend.Connection.prototype.sendMessageToBackend): (InspectorBackend.Connection.prototype._dispatchResponse): (InspectorBackend.Connection.prototype._dispatchResponseToCallback): (InspectorBackend.Connection.prototype._dispatchResponseToPromise): (InspectorBackend.Connection.prototype._dispatchEvent): (InspectorBackend.Connection.prototype._sendCommandToBackendWithCallback): (InspectorBackend.Connection.prototype._sendCommandToBackendExpectingPromise): (InspectorBackend.Connection.prototype._sendMessageToBackend): (InspectorBackend.Connection.prototype._flushPendingScripts): This extracts the Connection details into its own class. Although we make it appear as though a Target has a list of Agents, we actually have the Connection hold the list of Agents. Instead of cloning the entire Agent we just create a new object extended from the original Agent instance. This allows us to keep the same interface but just change the connection / dispatcher properties within the Agent. (InspectorBackend.MainConnection): (InspectorBackend.MainConnection.prototype.sendMessageToBackend): (InspectorBackend.WorkerConnection): (InspectorBackend.WorkerConnection.sendMessageToBackend): Two different kinds of connections. One for the Main connection and one for Workers. Currently the list of agents we expose on a Worker Target/Connection is hardcoded. * UserInterface/Models/ExecutionContext.js: (WebInspector.ExecutionContext): (WebInspector.ExecutionContext.prototype.get target): We may now have ExecutionContexts that mean a Page, Frames, and Workers. To do this we include the (target, executionContextId) tuple in this object. With this we have everything we need to evaluate JavaScript. * UserInterface/Controllers/RuntimeManager.js: (WebInspector.RuntimeManager): (WebInspector.RuntimeManager.prototype.get activeExecutionContext): (WebInspector.RuntimeManager.prototype.set activeExecutionContext): (WebInspector.RuntimeManager.prototype.get defaultExecutionContextIdentifier): Deleted. (WebInspector.RuntimeManager.prototype.set defaultExecutionContextIdentifier): Deleted. Update from contextId to a full ExecutionContext object. (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow.evalCallback): (WebInspector.RuntimeManager.prototype.evaluateInInspectedWindow): (WebInspector.RuntimeManager.prototype.saveResult): (WebInspector.RuntimeManager.prototype.getPropertiesForRemoteObject): (WebInspector.RuntimeManager.prototype._frameExecutionContextsCleared): * UserInterface/Controllers/FrameResourceManager.js: (WebInspector.FrameResourceManager.prototype.executionContextCreated): * UserInterface/Controllers/JavaScriptLogViewController.js: (WebInspector.JavaScriptLogViewController.prototype.consolePromptShouldCommitText): * UserInterface/Controllers/JavaScriptRuntimeCompletionProvider.js: Anywhere that wants to use the "activeExecutionContext" must use the specific RuntimeAgent tied to that ExecutionContext's Target. * UserInterface/Models/PropertyDescriptor.js: (WebInspector.PropertyDescriptor.fromPayload): * UserInterface/Protocol/RemoteObject.js: (WebInspector.RemoteObject): (WebInspector.RemoteObject.createFakeRemoteObject): (WebInspector.RemoteObject.fromPrimitiveValue): (WebInspector.RemoteObject.fromPayload): (WebInspector.RemoteObject.prototype.getDisplayablePropertyDescriptors): (WebInspector.RemoteObject.prototype.deprecatedGetDisplayableProperties): (WebInspector.RemoteObject.prototype.setPropertyValue): (WebInspector.RemoteObject.prototype.getCollectionEntries): (WebInspector.RemoteObject.prototype.releaseWeakCollectionEntries): (WebInspector.RemoteObject.prototype.callFunction): (WebInspector.RemoteObject.prototype.callFunctionJSON): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor.wrappedCallback): (WebInspector.RemoteObject.prototype.getOwnPropertyDescriptor): (WebInspector.RemoteObject.prototype.release): (WebInspector.RemoteObject.prototype._getPropertyDescriptors): (WebInspector.RemoteObject.prototype._getPropertyDescriptorsResolver): (WebInspector.RemoteObject.prototype._deprecatedGetProperties): RemoteObject and related Model Objects now must be tied to a specific Target, because we need to know which Target it belongs to in order to interact with it further. * UserInterface/Views/QuickConsole.js: (WebInspector.QuickConsole): (WebInspector.QuickConsole.prototype.get selectedExecutionContext): (WebInspector.QuickConsole.prototype.set selectedExecutionContext): (WebInspector.QuickConsole.prototype._executionContextPathComponentsToDisplay): (WebInspector.QuickConsole.prototype._rebuildExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._framePageExecutionContextsChanged): (WebInspector.QuickConsole.prototype._frameExecutionContextsCleared): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._createExecutionContextPathComponentFromFrame): (WebInspector.QuickConsole.prototype._compareExecutionContextPathComponents): (WebInspector.QuickConsole.prototype._insertOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._removeOtherExecutionContextPathComponent): (WebInspector.QuickConsole.prototype._insertExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._removeExecutionContextPathComponentForFrame): (WebInspector.QuickConsole.prototype._targetAdded): (WebInspector.QuickConsole.prototype._targetRemoved): (WebInspector.QuickConsole.prototype._pathComponentSelected): (WebInspector.QuickConsole.prototype.get selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype.set selectedExecutionContextIdentifier): Deleted. (WebInspector.QuickConsole.prototype._defaultExecutionContextChanged): Deleted. Update the code from executionContextId to ExecutionContext objects. Update the picker with ExecutionContextPathComponent for Workers (new Targets). Generalize and cleanup the code to make it easier to follow. LayoutTests: * inspector/unit-tests/target-manager-expected.txt: Added. * inspector/unit-tests/target-manager.html: Added. Unit test for TargetManager and its events with Worker creation. * inspector/worker/resources/worker-1.js: * inspector/worker/runtime-basic-expected.txt: Added. * inspector/worker/runtime-basic.html: Added. Test comparing RuntimeAgent between Main target and Worker target. * inspector/runtime/change-execution-context-identifier-expected.txt: * inspector/runtime/change-execution-context-identifier.html: RuntimeManager has been updated to have a full ExecutionContext object containing a Target + ContextId instead of just a ContextId. * inspector/console/console-api-expected.txt: * inspector/console/console-api.html: * inspector/console/console-table-expected.txt: * inspector/console/console-table.html: * inspector/debugger/tail-deleted-frames-from-vm-entry.html: * inspector/debugger/tail-deleted-frames.html: * inspector/debugger/tail-recursion.html: * inspector/model/remote-object-expected.txt: * inspector/model/remote-object-weak-collection-expected.txt: * inspector/model/remote-object-weak-collection.html: * inspector/model/remote-object.html: * platform/mac/inspector/model/remote-object-expected.txt: Introduce a better JSON Filter for RemoteObject in more tests. It is important that we filter the _target, because otherwise JSON.stringify would throw an error about cycles. Canonical link: https://commits.webkit.org/181797@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208009 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-27 22:19:12 +00:00
</body>
</html>