Commit 2a47c1c9 authored by Yury Semikhatsky's avatar Yury Semikhatsky Committed by Commit Bot

DevTools: allow auto-attaching to page targets

Target.setAutoAttach on the top level Target handler now allows
attaching to all new pages. Top level TargetHandler will attach
to each main frame as soon as it is created (right after sending
targetCreated event). All subsequent navigations will be throttled
until Runtime.runIfWaitingForDebugger is received.

Experimental parameter 'windowOpen' is removed in favour of the
new more generic functionality.

Bug: 1051687
Change-Id: Ia9b58133b97999383cd44016f8d3041f71b5d3d1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2042302
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: default avatarAndrey Kosyakov <caseq@chromium.org>
Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Auto-Submit: Yury Semikhatsky <yurys@chromium.org>
Cr-Commit-Position: refs/heads/master@{#741363}
parent bff00c7a
...@@ -190,14 +190,23 @@ void OnSignedExchangeCertificateRequestCompleted( ...@@ -190,14 +190,23 @@ void OnSignedExchangeCertificateRequestCompleted(
protocol::Network::ResourceTypeEnum::Other, status); protocol::Network::ResourceTypeEnum::Other, status);
} }
void CreateThrottlesForAgentHost(
DevToolsAgentHostImpl* agent_host,
NavigationHandle* navigation_handle,
std::vector<std::unique_ptr<NavigationThrottle>>* result) {
for (auto* target_handler :
protocol::TargetHandler::ForAgentHost(agent_host)) {
std::unique_ptr<NavigationThrottle> throttle =
target_handler->CreateThrottleForNavigation(navigation_handle);
if (throttle)
result->push_back(std::move(throttle));
}
}
std::vector<std::unique_ptr<NavigationThrottle>> CreateNavigationThrottles( std::vector<std::unique_ptr<NavigationThrottle>> CreateNavigationThrottles(
NavigationHandle* navigation_handle) { NavigationHandle* navigation_handle) {
std::vector<std::unique_ptr<NavigationThrottle>> result;
FrameTreeNode* frame_tree_node = FrameTreeNode* frame_tree_node =
NavigationRequest::From(navigation_handle)->frame_tree_node(); NavigationRequest::From(navigation_handle)->frame_tree_node();
DevToolsAgentHostImpl* agent_host =
RenderFrameDevToolsAgentHost::GetFor(frame_tree_node);
FrameTreeNode* parent = frame_tree_node->parent(); FrameTreeNode* parent = frame_tree_node->parent();
if (!parent) { if (!parent) {
if (WebContentsImpl::FromFrameTreeNode(frame_tree_node)->IsPortal() && if (WebContentsImpl::FromFrameTreeNode(frame_tree_node)->IsPortal() &&
...@@ -207,22 +216,19 @@ std::vector<std::unique_ptr<NavigationThrottle>> CreateNavigationThrottles( ...@@ -207,22 +216,19 @@ std::vector<std::unique_ptr<NavigationThrottle>> CreateNavigationThrottles(
->GetOuterWebContents() ->GetOuterWebContents()
->GetFrameTree() ->GetFrameTree()
->root(); ->root();
} else {
parent = frame_tree_node->original_opener();
} }
} }
if (!parent)
return result; std::vector<std::unique_ptr<NavigationThrottle>> result;
if (parent) {
agent_host = RenderFrameDevToolsAgentHost::GetFor(parent); DevToolsAgentHostImpl* agent_host =
if (agent_host) { RenderFrameDevToolsAgentHost::GetFor(parent);
for (auto* target_handler : if (agent_host)
protocol::TargetHandler::ForAgentHost(agent_host)) { CreateThrottlesForAgentHost(agent_host, navigation_handle, &result);
std::unique_ptr<NavigationThrottle> throttle = } else {
target_handler->CreateThrottleForNavigation(navigation_handle); for (auto* browser_agent_host : BrowserDevToolsAgentHost::Instances())
if (throttle) CreateThrottlesForAgentHost(browser_agent_host, navigation_handle,
result.push_back(std::move(throttle)); &result);
}
} }
return result; return result;
......
...@@ -92,6 +92,10 @@ void DevToolsSession::SetRuntimeResumeCallback( ...@@ -92,6 +92,10 @@ void DevToolsSession::SetRuntimeResumeCallback(
runtime_resume_ = std::move(runtime_resume); runtime_resume_ = std::move(runtime_resume);
} }
bool DevToolsSession::IsWaitingForDebuggerOnStart() const {
return !runtime_resume_.is_null();
}
void DevToolsSession::Dispose() { void DevToolsSession::Dispose() {
dispatcher_.reset(); dispatcher_.reset();
for (auto& pair : handlers_) for (auto& pair : handlers_)
......
...@@ -44,6 +44,7 @@ class DevToolsSession : public protocol::FrontendChannel, ...@@ -44,6 +44,7 @@ class DevToolsSession : public protocol::FrontendChannel,
void SetAgentHost(DevToolsAgentHostImpl* agent_host); void SetAgentHost(DevToolsAgentHostImpl* agent_host);
void SetRuntimeResumeCallback(base::OnceClosure runtime_resume); void SetRuntimeResumeCallback(base::OnceClosure runtime_resume);
bool IsWaitingForDebuggerOnStart() const;
void Dispose(); void Dispose();
// content::DevToolsAgentHostClientChannel implementation. // content::DevToolsAgentHostClientChannel implementation.
......
...@@ -119,11 +119,9 @@ base::flat_set<GURL> GetFrameUrls(RenderFrameHostImpl* render_frame_host) { ...@@ -119,11 +119,9 @@ base::flat_set<GURL> GetFrameUrls(RenderFrameHostImpl* render_frame_host) {
} // namespace } // namespace
TargetAutoAttacher::TargetAutoAttacher( TargetAutoAttacher::TargetAutoAttacher(
AttachCallback attach_callback, Delegate* delegate,
DetachCallback detach_callback,
DevToolsRendererChannel* renderer_channel) DevToolsRendererChannel* renderer_channel)
: attach_callback_(attach_callback), : delegate_(delegate),
detach_callback_(detach_callback),
renderer_channel_(renderer_channel), renderer_channel_(renderer_channel),
render_frame_host_(nullptr), render_frame_host_(nullptr),
auto_attach_(false), auto_attach_(false),
...@@ -206,6 +204,13 @@ bool TargetAutoAttacher::ShouldThrottleFramesNavigation() { ...@@ -206,6 +204,13 @@ bool TargetAutoAttacher::ShouldThrottleFramesNavigation() {
return auto_attach_; return auto_attach_;
} }
void TargetAutoAttacher::AttachToAgentHost(DevToolsAgentHost* host) {
scoped_refptr<DevToolsAgentHost> agent_host(host);
DCHECK(auto_attached_hosts_.find(agent_host) == auto_attached_hosts_.end());
delegate_->AutoAttach(agent_host.get(), wait_for_debugger_on_start_);
auto_attached_hosts_.insert(agent_host);
}
DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame( DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame(
NavigationRequest* navigation_request) { NavigationRequest* navigation_request) {
if (!ShouldThrottleFramesNavigation()) if (!ShouldThrottleFramesNavigation())
...@@ -223,20 +228,6 @@ DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame( ...@@ -223,20 +228,6 @@ DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame(
scoped_refptr<DevToolsAgentHost> agent_host = scoped_refptr<DevToolsAgentHost> agent_host =
RenderFrameDevToolsAgentHost::FindForDangling(frame_tree_node); RenderFrameDevToolsAgentHost::FindForDangling(frame_tree_node);
// Process the window.open auto-attaches for new targets.
if (frame_tree_node->original_opener()) {
if (!agent_host) {
agent_host =
RenderFrameDevToolsAgentHost::CreateForCrossProcessNavigation(
navigation_request);
}
if (auto_attached_hosts_.find(agent_host) != auto_attached_hosts_.end())
return nullptr;
attach_callback_.Run(agent_host.get(), wait_for_debugger_on_start_);
auto_attached_hosts_.insert(agent_host);
return wait_for_debugger_on_start_ ? agent_host.get() : nullptr;
}
bool old_cross_process = !!agent_host; bool old_cross_process = !!agent_host;
bool is_portal_main_frame = bool is_portal_main_frame =
frame_tree_node->IsMainFrame() && frame_tree_node->IsMainFrame() &&
...@@ -251,8 +242,7 @@ DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame( ...@@ -251,8 +242,7 @@ DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame(
if (new_cross_process) { if (new_cross_process) {
agent_host = RenderFrameDevToolsAgentHost::CreateForCrossProcessNavigation( agent_host = RenderFrameDevToolsAgentHost::CreateForCrossProcessNavigation(
navigation_request); navigation_request);
attach_callback_.Run(agent_host.get(), wait_for_debugger_on_start_); AttachToAgentHost(agent_host.get());
auto_attached_hosts_.insert(agent_host);
return wait_for_debugger_on_start_ ? agent_host.get() : nullptr; return wait_for_debugger_on_start_ ? agent_host.get() : nullptr;
} }
...@@ -263,7 +253,7 @@ DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame( ...@@ -263,7 +253,7 @@ DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame(
if (it == auto_attached_hosts_.end()) if (it == auto_attached_hosts_.end())
return nullptr; return nullptr;
auto_attached_hosts_.erase(it); auto_attached_hosts_.erase(it);
detach_callback_.Run(agent_host.get()); delegate_->AutoDetach(agent_host.get());
return nullptr; return nullptr;
} }
...@@ -291,12 +281,12 @@ void TargetAutoAttacher::ReattachTargetsOfType(const Hosts& new_hosts, ...@@ -291,12 +281,12 @@ void TargetAutoAttacher::ReattachTargetsOfType(const Hosts& new_hosts,
for (auto& host : old_hosts) { for (auto& host : old_hosts) {
if (host->GetType() == type && new_hosts.find(host) == new_hosts.end()) { if (host->GetType() == type && new_hosts.find(host) == new_hosts.end()) {
auto_attached_hosts_.erase(host); auto_attached_hosts_.erase(host);
detach_callback_.Run(host.get()); delegate_->AutoDetach(host.get());
} }
} }
for (auto& host : new_hosts) { for (auto& host : new_hosts) {
if (old_hosts.find(host) == old_hosts.end()) { if (old_hosts.find(host) == old_hosts.end()) {
attach_callback_.Run(host.get(), waiting_for_debugger); delegate_->AutoAttach(host.get(), waiting_for_debugger);
auto_attached_hosts_.insert(host); auto_attached_hosts_.insert(host);
} }
} }
...@@ -371,7 +361,7 @@ void TargetAutoAttacher::WorkerDestroyed(ServiceWorkerDevToolsAgentHost* host) { ...@@ -371,7 +361,7 @@ void TargetAutoAttacher::WorkerDestroyed(ServiceWorkerDevToolsAgentHost* host) {
void TargetAutoAttacher::ChildWorkerCreated(DevToolsAgentHostImpl* agent_host, void TargetAutoAttacher::ChildWorkerCreated(DevToolsAgentHostImpl* agent_host,
bool waiting_for_debugger) { bool waiting_for_debugger) {
attach_callback_.Run(agent_host, waiting_for_debugger); delegate_->AutoAttach(agent_host, waiting_for_debugger);
auto_attached_hosts_.insert(scoped_refptr<DevToolsAgentHost>(agent_host)); auto_attached_hosts_.insert(scoped_refptr<DevToolsAgentHost>(agent_host));
} }
......
...@@ -20,13 +20,17 @@ namespace protocol { ...@@ -20,13 +20,17 @@ namespace protocol {
class TargetAutoAttacher : public ServiceWorkerDevToolsManager::Observer { class TargetAutoAttacher : public ServiceWorkerDevToolsManager::Observer {
public: public:
// Second parameter is |waiting_for_debugger|, returns whether it succeeded. class Delegate {
using AttachCallback = public:
base::RepeatingCallback<void(DevToolsAgentHost*, bool)>; virtual void AutoAttach(DevToolsAgentHost* host,
using DetachCallback = base::RepeatingCallback<void(DevToolsAgentHost*)>; bool waiting_for_debugger) = 0;
virtual void AutoDetach(DevToolsAgentHost* host) = 0;
TargetAutoAttacher(AttachCallback attach_callback, protected:
DetachCallback detach_callback, virtual ~Delegate() = default;
};
TargetAutoAttacher(Delegate* delegate,
DevToolsRendererChannel* renderer_channel); DevToolsRendererChannel* renderer_channel);
~TargetAutoAttacher() override; ~TargetAutoAttacher() override;
...@@ -40,6 +44,7 @@ class TargetAutoAttacher : public ServiceWorkerDevToolsManager::Observer { ...@@ -40,6 +44,7 @@ class TargetAutoAttacher : public ServiceWorkerDevToolsManager::Observer {
void AgentHostClosed(DevToolsAgentHost* host); void AgentHostClosed(DevToolsAgentHost* host);
bool ShouldThrottleFramesNavigation(); bool ShouldThrottleFramesNavigation();
void AttachToAgentHost(DevToolsAgentHost* host);
DevToolsAgentHost* AutoAttachToFrame(NavigationRequest* navigation_request); DevToolsAgentHost* AutoAttachToFrame(NavigationRequest* navigation_request);
void ChildWorkerCreated(DevToolsAgentHostImpl* agent_host, void ChildWorkerCreated(DevToolsAgentHostImpl* agent_host,
bool waiting_for_debugger); bool waiting_for_debugger);
...@@ -61,8 +66,7 @@ class TargetAutoAttacher : public ServiceWorkerDevToolsManager::Observer { ...@@ -61,8 +66,7 @@ class TargetAutoAttacher : public ServiceWorkerDevToolsManager::Observer {
void UpdateFrames(); void UpdateFrames();
AttachCallback attach_callback_; Delegate* delegate_;
DetachCallback detach_callback_;
DevToolsRendererChannel* renderer_channel_; DevToolsRendererChannel* renderer_channel_;
RenderFrameHostImpl* render_frame_host_; RenderFrameHostImpl* render_frame_host_;
......
...@@ -28,7 +28,8 @@ namespace protocol { ...@@ -28,7 +28,8 @@ namespace protocol {
class TargetHandler : public DevToolsDomainHandler, class TargetHandler : public DevToolsDomainHandler,
public Target::Backend, public Target::Backend,
public DevToolsAgentHostObserver { public DevToolsAgentHostObserver,
public TargetAutoAttacher::Delegate {
public: public:
enum class AccessMode { enum class AccessMode {
// Only setAutoAttach is supported. Any non-related target are not // Only setAutoAttach is supported. Any non-related target are not
...@@ -63,7 +64,6 @@ class TargetHandler : public DevToolsDomainHandler, ...@@ -63,7 +64,6 @@ class TargetHandler : public DevToolsDomainHandler,
void SetAutoAttach(bool auto_attach, void SetAutoAttach(bool auto_attach,
bool wait_for_debugger_on_start, bool wait_for_debugger_on_start,
Maybe<bool> flatten, Maybe<bool> flatten,
Maybe<bool> window_open,
std::unique_ptr<SetAutoAttachCallback> callback) override; std::unique_ptr<SetAutoAttachCallback> callback) override;
Response SetRemoteLocations( Response SetRemoteLocations(
std::unique_ptr<protocol::Array<Target::RemoteLocation>>) override; std::unique_ptr<protocol::Array<Target::RemoteLocation>>) override;
...@@ -106,9 +106,12 @@ class TargetHandler : public DevToolsDomainHandler, ...@@ -106,9 +106,12 @@ class TargetHandler : public DevToolsDomainHandler,
private: private:
class Session; class Session;
class Throttle; class Throttle;
class MainFrameThrottle;
// TargetAutoAttacher::Delegate implementation.
void AutoAttach(DevToolsAgentHost* host, bool waiting_for_debugger) override;
void AutoDetach(DevToolsAgentHost* host) override;
void AutoAttach(DevToolsAgentHost* host, bool waiting_for_debugger);
void AutoDetach(DevToolsAgentHost* host);
Response FindSession(Maybe<std::string> session_id, Response FindSession(Maybe<std::string> session_id,
Maybe<std::string> target_id, Maybe<std::string> target_id,
Session** session); Session** session);
...@@ -116,8 +119,8 @@ class TargetHandler : public DevToolsDomainHandler, ...@@ -116,8 +119,8 @@ class TargetHandler : public DevToolsDomainHandler,
void SetAutoAttachInternal(bool auto_attach, void SetAutoAttachInternal(bool auto_attach,
bool wait_for_debugger_on_start, bool wait_for_debugger_on_start,
bool flatten, bool flatten,
bool window_open,
base::OnceClosure callback); base::OnceClosure callback);
void UpdateAgentHostObserver();
// DevToolsAgentHostObserver implementation. // DevToolsAgentHostObserver implementation.
bool ShouldForceDevToolsAgentHostCreation() override; bool ShouldForceDevToolsAgentHostCreation() override;
...@@ -132,8 +135,8 @@ class TargetHandler : public DevToolsDomainHandler, ...@@ -132,8 +135,8 @@ class TargetHandler : public DevToolsDomainHandler,
std::unique_ptr<Target::Frontend> frontend_; std::unique_ptr<Target::Frontend> frontend_;
TargetAutoAttacher auto_attacher_; TargetAutoAttacher auto_attacher_;
bool flatten_auto_attach_ = false; bool flatten_auto_attach_ = false;
bool attach_to_window_open_ = false;
bool discover_; bool discover_;
bool observing_agent_hosts_ = false;
std::map<std::string, std::unique_ptr<Session>> attached_sessions_; std::map<std::string, std::unique_ptr<Session>> attached_sessions_;
std::map<DevToolsAgentHost*, Session*> auto_attached_sessions_; std::map<DevToolsAgentHost*, Session*> auto_attached_sessions_;
std::set<DevToolsAgentHost*> reported_hosts_; std::set<DevToolsAgentHost*> reported_hosts_;
......
...@@ -245,6 +245,12 @@ RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost( ...@@ -245,6 +245,12 @@ RenderFrameDevToolsAgentHost::RenderFrameDevToolsAgentHost(
SetFrameTreeNode(frame_tree_node); SetFrameTreeNode(frame_tree_node);
ChangeFrameHostAndObservedProcess(frame_host); ChangeFrameHostAndObservedProcess(frame_host);
render_frame_alive_ = frame_host_ && frame_host_->IsRenderFrameLive(); render_frame_alive_ = frame_host_ && frame_host_->IsRenderFrameLive();
if (frame_tree_node->parent()) {
render_frame_crashed_ = !render_frame_alive_;
} else {
WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host);
render_frame_crashed_ = web_contents && web_contents->IsCrashed();
}
AddRef(); // Balanced in DestroyOnRenderFrameGone. AddRef(); // Balanced in DestroyOnRenderFrameGone.
NotifyCreated(); NotifyCreated();
} }
...@@ -441,12 +447,8 @@ void RenderFrameDevToolsAgentHost::DidFinishNavigation( ...@@ -441,12 +447,8 @@ void RenderFrameDevToolsAgentHost::DidFinishNavigation(
void RenderFrameDevToolsAgentHost::UpdateFrameHost( void RenderFrameDevToolsAgentHost::UpdateFrameHost(
RenderFrameHostImpl* frame_host) { RenderFrameHostImpl* frame_host) {
if (frame_host == frame_host_) { if (frame_host == frame_host_) {
if (frame_host && !render_frame_alive_) { if (frame_host && !render_frame_alive_)
render_frame_alive_ = true; UpdateFrameAlive();
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetReloadedAfterCrash();
UpdateRendererChannel(IsAttached());
}
return; return;
} }
...@@ -469,13 +471,7 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost( ...@@ -469,13 +471,7 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost(
if (!restricted_sessions.empty()) if (!restricted_sessions.empty())
ForceDetachRestrictedSessions(restricted_sessions); ForceDetachRestrictedSessions(restricted_sessions);
if (!render_frame_alive_) { UpdateFrameAlive();
render_frame_alive_ = true;
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetReloadedAfterCrash();
}
UpdateRendererChannel(IsAttached());
} }
void RenderFrameDevToolsAgentHost::DidStartNavigation( void RenderFrameDevToolsAgentHost::DidStartNavigation(
...@@ -558,6 +554,16 @@ void RenderFrameDevToolsAgentHost::ChangeFrameHostAndObservedProcess( ...@@ -558,6 +554,16 @@ void RenderFrameDevToolsAgentHost::ChangeFrameHostAndObservedProcess(
frame_host_->GetProcess()->AddObserver(this); frame_host_->GetProcess()->AddObserver(this);
} }
void RenderFrameDevToolsAgentHost::UpdateFrameAlive() {
render_frame_alive_ = frame_host_ && frame_host_->IsRenderFrameLive();
if (render_frame_alive_ && render_frame_crashed_) {
render_frame_crashed_ = false;
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetReloadedAfterCrash();
}
UpdateRendererChannel(IsAttached());
}
void RenderFrameDevToolsAgentHost::RenderProcessExited( void RenderFrameDevToolsAgentHost::RenderProcessExited(
RenderProcessHost* host, RenderProcessHost* host,
const ChildProcessTerminationInfo& info) { const ChildProcessTerminationInfo& info) {
...@@ -575,6 +581,7 @@ void RenderFrameDevToolsAgentHost::RenderProcessExited( ...@@ -575,6 +581,7 @@ void RenderFrameDevToolsAgentHost::RenderProcessExited(
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this)) for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetCrashed(); inspector->TargetCrashed();
NotifyCrashed(info.status); NotifyCrashed(info.status);
render_frame_crashed_ = true;
break; break;
default: default:
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this)) for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
......
...@@ -139,6 +139,7 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost ...@@ -139,6 +139,7 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
void UpdateFrameHost(RenderFrameHostImpl* frame_host); void UpdateFrameHost(RenderFrameHostImpl* frame_host);
void SetFrameTreeNode(FrameTreeNode* frame_tree_node); void SetFrameTreeNode(FrameTreeNode* frame_tree_node);
void ChangeFrameHostAndObservedProcess(RenderFrameHostImpl* frame_host); void ChangeFrameHostAndObservedProcess(RenderFrameHostImpl* frame_host);
void UpdateFrameAlive();
bool ShouldAllowSession(DevToolsSession* session); bool ShouldAllowSession(DevToolsSession* session);
...@@ -159,6 +160,7 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost ...@@ -159,6 +160,7 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
RenderFrameHostImpl* frame_host_ = nullptr; RenderFrameHostImpl* frame_host_ = nullptr;
base::flat_set<NavigationRequest*> navigation_requests_; base::flat_set<NavigationRequest*> navigation_requests_;
bool render_frame_alive_ = false; bool render_frame_alive_ = false;
bool render_frame_crashed_ = false;
// The FrameTreeNode associated with this agent. // The FrameTreeNode associated with this agent.
FrameTreeNode* frame_tree_node_; FrameTreeNode* frame_tree_node_;
......
...@@ -6833,8 +6833,6 @@ domain Target ...@@ -6833,8 +6833,6 @@ domain Target
# We plan to make this the default, deprecate non-flattened mode, # We plan to make this the default, deprecate non-flattened mode,
# and eventually retire it. See crbug.com/991325. # and eventually retire it. See crbug.com/991325.
optional boolean flatten optional boolean flatten
# Auto-attach to the targets created via window.open from current target.
experimental optional boolean windowOpen
# Controls whether to discover available targets and notify via # Controls whether to discover available targets and notify via
# `targetCreated/targetInfoChanged/targetDestroyed` events. # `targetCreated/targetInfoChanged/targetDestroyed` events.
......
Tests that browser.Target.setAutoAttach() attaches to new about:blank page.
Created new page from another session
Auto-attached to the new page: {
method : Target.attachedToTarget
params : {
sessionId : <string>
targetInfo : {
attached : true
browserContextId : <string>
targetId : <string>
title :
type : page
url :
}
waitingForDebugger : true
}
}
Resumed
Received new target info: {
method : Target.targetInfoChanged
params : {
targetInfo : {
attached : true
browserContextId : <string>
targetId : <string>
title : about:blank#newpage
type : page
url : about:blank#newpage
}
}
}
(async function(testRunner) {
var {page, session, dp} = await testRunner.startBlank(
`Tests that browser.Target.setAutoAttach() attaches to new about:blank page.`);
const target = testRunner.browserP().Target;
await target.setDiscoverTargets({discover: true});
await target.setAutoAttach(
{autoAttach: true, waitForDebuggerOnStart: true, flatten: true});
const response = await target.attachToBrowserTarget();
const newBrowserSession = new TestRunner.Session(testRunner, response.result.sessionId);
newBrowserSession.protocol.Target.createTarget({url: 'about:blank#newpage'});
testRunner.log('Created new page from another session');
const attachedEvent = await target.onceAttachedToTarget();
testRunner.log(attachedEvent, 'Auto-attached to the new page: ');
// Navigate elsewhere and test that the request will be paused.
const newSession = new TestRunner.Session(testRunner, attachedEvent.params.sessionId);
const logSpuriousEvent = event => testRunner.log(event, 'FAIL: received spurious event while paused ');
target.onTargetInfoChanged(logSpuriousEvent);
newSession.navigate(testRunner.url('../resources/test-page.html?newpage'));
// Do a roundtrip to the browser to wait for some time when
// TargetInfoChanged could come.
await target.getTargets();
target.offTargetInfoChanged(logSpuriousEvent);
const [infoChangedEvent] = await Promise.all([
target.onceTargetInfoChanged(),
newSession.protocol.Runtime.runIfWaitingForDebugger()
]);
testRunner.log('Resumed');
testRunner.log(infoChangedEvent, 'Received new target info: ');
await newBrowserSession.disconnect();
testRunner.completeTest();
})
Tests that browser.Target.setAutoAttach() supports only flatten protocol.
Tried to auto-attach with not fatten protocol{
error : {
code : -32602
message : Only flatten protocol is supported with browser level auto-attach
}
id : <number>
}
(async function(testRunner) {
var {page, session, dp} = await testRunner.startBlank(
`Tests that browser.Target.setAutoAttach() supports only flatten protocol.`);
const target = testRunner.browserP().Target;
const response = await target.setAutoAttach(
{autoAttach: true, waitForDebuggerOnStart: true, flatten: false});
testRunner.log(response, 'Tried to auto-attach with not fatten protocol');
testRunner.completeTest();
})
Tests that browser.Target.setAutoAttach() attaches to new page targets.
Attached to the new page: {
method : Target.attachedToTarget
params : {
sessionId : <string>
targetInfo : {
attached : true
browserContextId : <string>
targetId : <string>
title :
type : page
url :
}
waitingForDebugger : true
}
}
Resumed
New page location: {
id : <number>
result : {
result : {
type : string
value : http://127.0.0.1:8000/inspector-protocol/resources/test-page.html?newpage
}
}
sessionId : <string>
}
(async function(testRunner) {
var {page, session, dp} = await testRunner.startBlank(
`Tests that browser.Target.setAutoAttach() attaches to new page targets.`);
const target = testRunner.browserP().Target;
await target.setDiscoverTargets({discover: true});
await target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true, flatten: true});
const response = await target.attachToBrowserTarget();
const newBrowserSession =
new TestRunner.Session(testRunner, response.result.sessionId);
const newUrl = testRunner.url('../resources/test-page.html?newpage');
newBrowserSession.protocol.Target.createTarget({url: newUrl});
const attachedEvent = await target.onceAttachedToTarget();
testRunner.log(attachedEvent, 'Attached to the new page: ');
const newSession = new TestRunner.Session(testRunner, attachedEvent.params.sessionId);
newSession.protocol.Inspector.onTargetReloadedAfterCrash(
event => testRunner.log(event, 'FAIL: received spurious event '));
await newSession.protocol.Runtime.runIfWaitingForDebugger();
testRunner.log('Resumed\n\n');
const path = await newSession.protocol.Runtime.evaluate({expression: 'location.href'});
testRunner.log(path, 'New page location: ');
await newBrowserSession.disconnect();
testRunner.completeTest();
})
Tests that Target.setAutoAttach(windowOpen=true) attaches to window.open targets. Tests that browser.Target.setAutoAttach() attaches to window.open targets.
Opened the window Opened the window
Attached to window Attached to window, waitingForDebugger=true
Resumed popup window
Popup window URL changed to http://127.0.0.1:8000/inspector-protocol/resources/inspector-protocol-page.html
Navigated the window Navigated the window
Target info changed Target info changed, new URL is http://127.0.0.1:8000/inspector-protocol/resources/test-page.html
Closed the window Closed the window
Detached from window Detached from window
(async function(testRunner) { (async function(testRunner) {
var {page, session, dp} = await testRunner.startBlank( var {page, session, dp} = await testRunner.startBlank(
`Tests that Target.setAutoAttach(windowOpen=true) attaches to window.open targets.`); `Tests that browser.Target.setAutoAttach() attaches to window.open targets.`);
await dp.Target.setDiscoverTargets({discover: true}); const target = testRunner.browserP().Target;
await target.setDiscoverTargets({discover: true});
await target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true, flatten: true});
await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true, flatten: true, windowOpen: true});
const attachedPromise = dp.Target.onceAttachedToTarget();
session.evaluate(` session.evaluate(`
window.myWindow = window.open('../resources/inspector-protocol-page.html'); undefined; window.myWindow = window.open('../resources/inspector-protocol-page.html'); undefined;
`); `);
testRunner.log('Opened the window'); testRunner.log('Opened the window');
await attachedPromise; const attachedEvent = await target.onceAttachedToTarget();
testRunner.log('Attached to window'); testRunner.log('Attached to window, waitingForDebugger=' + attachedEvent.params.waitingForDebugger);
const popupSession = new TestRunner.Session(testRunner, attachedEvent.params.sessionId);
const changedPromise = target.onceTargetInfoChanged();
await popupSession.protocol.Runtime.runIfWaitingForDebugger();
testRunner.log('Resumed popup window');
const changeEvent = await changedPromise;
testRunner.log('Popup window URL changed to ' + changeEvent.params.targetInfo.url);
const changedPromise = dp.Target.onceTargetInfoChanged(); const secondChangedPromise = target.onceTargetInfoChanged();
session.evaluate(` session.evaluate(`
window.myWindow.location.assign('../resources/inspector-protocol-page.html?foo'); undefined; window.myWindow.location.assign('../resources/test-page.html'); undefined;
`); `);
testRunner.log('Navigated the window'); testRunner.log('Navigated the window');
await changedPromise; const secondChangeEvent = await secondChangedPromise;
testRunner.log('Target info changed'); testRunner.log('Target info changed, new URL is ' + secondChangeEvent.params.targetInfo.url);
const detachedPromise = dp.Target.onceDetachedFromTarget(); const detachedPromise = target.onceDetachedFromTarget();
session.evaluate(` session.evaluate(`
window.myWindow.close(); undefined; window.myWindow.close(); undefined;
`); `);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment