Commit 5fc3b9d0 authored by Dmitry Gozman's avatar Dmitry Gozman Committed by Commit Bot

[DevTools] Implement waitForDebugger for OOPIFs

Using NavigationThrottle for this. Since during throttling
the navigation has not committed yet, we have to create
agent host for soon-to-be-committed frame in advance.

Bug: 750901
Change-Id: I88dbd982481b88eeec36209b6bf3ad7f74863200
Reviewed-on: https://chromium-review.googlesource.com/818076Reviewed-by: default avatarPavel Feldman <pfeldman@chromium.org>
Commit-Queue: Dmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523835}
parent 73f23ca8
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "content/browser/download/download_manager_impl.h" #include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/download_task_runner.h" #include "content/browser/download/download_task_runner.h"
#include "content/browser/frame_host/interstitial_page_impl.h" #include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_agent_host.h"
...@@ -2011,7 +2012,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsProtocolTest, TargetNoDiscovery) { ...@@ -2011,7 +2012,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessDevToolsProtocolTest, TargetNoDiscovery) {
Attach(); Attach();
command_params.reset(new base::DictionaryValue()); command_params.reset(new base::DictionaryValue());
command_params->SetBoolean("autoAttach", true); command_params->SetBoolean("autoAttach", true);
command_params->SetBoolean("waitForDebuggerOnStart", true); command_params->SetBoolean("waitForDebuggerOnStart", false);
SendCommand("Target.setAutoAttach", std::move(command_params), true); SendCommand("Target.setAutoAttach", std::move(command_params), true);
EXPECT_TRUE(notifications_.empty()); EXPECT_TRUE(notifications_.empty());
command_params.reset(new base::DictionaryValue()); command_params.reset(new base::DictionaryValue());
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "content/browser/devtools/service_worker_devtools_agent_host.h" #include "content/browser/devtools/service_worker_devtools_agent_host.h"
#include "content/browser/frame_host/frame_tree.h" #include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h"
namespace content { namespace content {
...@@ -138,6 +139,29 @@ void TargetAutoAttacher::AgentHostClosed(DevToolsAgentHost* host) { ...@@ -138,6 +139,29 @@ void TargetAutoAttacher::AgentHostClosed(DevToolsAgentHost* host) {
auto_attached_hosts_.erase(base::WrapRefCounted(host)); auto_attached_hosts_.erase(base::WrapRefCounted(host));
} }
bool TargetAutoAttacher::ShouldThrottleFramesNavigation() {
return auto_attach_ && attach_to_frames_ && wait_for_debugger_on_start_;
}
DevToolsAgentHost* TargetAutoAttacher::AutoAttachToFrame(
NavigationHandle* navigation_handle) {
if (!ShouldThrottleFramesNavigation())
return nullptr;
bool cross_process =
navigation_handle->GetRenderFrameHost()->IsCrossProcessSubframe();
if (!cross_process)
return nullptr;
scoped_refptr<DevToolsAgentHost> agent_host =
RenderFrameDevToolsAgentHost::GetOrCreateForDangling(
static_cast<NavigationHandleImpl*>(navigation_handle)
->frame_tree_node());
if (auto_attached_hosts_.find(agent_host) != auto_attached_hosts_.end())
return nullptr;
attach_callback_.Run(agent_host.get(), true /* waiting_for_debugger */);
auto_attached_hosts_.insert(agent_host);
return agent_host.get();
}
void TargetAutoAttacher::ReattachServiceWorkers(bool waiting_for_debugger) { void TargetAutoAttacher::ReattachServiceWorkers(bool waiting_for_debugger) {
if (!auto_attach_) if (!auto_attach_)
return; return;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
namespace content { namespace content {
class NavigationHandle;
class RenderFrameHostImpl; class RenderFrameHostImpl;
namespace protocol { namespace protocol {
...@@ -33,6 +34,9 @@ class TargetAutoAttacher : public ServiceWorkerDevToolsManager::Observer { ...@@ -33,6 +34,9 @@ class TargetAutoAttacher : public ServiceWorkerDevToolsManager::Observer {
void UpdateFrames(); void UpdateFrames();
void AgentHostClosed(DevToolsAgentHost* host); void AgentHostClosed(DevToolsAgentHost* host);
bool ShouldThrottleFramesNavigation();
DevToolsAgentHost* AutoAttachToFrame(NavigationHandle* navigation_handle);
private: private:
using Hosts = base::flat_set<scoped_refptr<DevToolsAgentHost>>; using Hosts = base::flat_set<scoped_refptr<DevToolsAgentHost>>;
......
...@@ -4,16 +4,22 @@ ...@@ -4,16 +4,22 @@
#include "content/browser/devtools/protocol/target_handler.h" #include "content/browser/devtools/protocol/target_handler.h"
#include "base/json/json_reader.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/values.h"
#include "content/browser/devtools/devtools_manager.h" #include "content/browser/devtools/devtools_manager.h"
#include "content/browser/devtools/devtools_session.h" #include "content/browser/devtools/devtools_session.h"
#include "content/public/browser/devtools_agent_host_client.h" #include "content/public/browser/devtools_agent_host_client.h"
#include "content/public/browser/navigation_throttle.h"
namespace content { namespace content {
namespace protocol { namespace protocol {
namespace { namespace {
static const char kMethod[] = "method";
static const char kResumeMethod[] = "Runtime.runIfWaitingForDebugger";
std::unique_ptr<Target::TargetInfo> CreateInfo(DevToolsAgentHost* host) { std::unique_ptr<Target::TargetInfo> CreateInfo(DevToolsAgentHost* host) {
std::unique_ptr<Target::TargetInfo> target_info = std::unique_ptr<Target::TargetInfo> target_info =
Target::TargetInfo::Create() Target::TargetInfo::Create()
...@@ -30,6 +36,24 @@ std::unique_ptr<Target::TargetInfo> CreateInfo(DevToolsAgentHost* host) { ...@@ -30,6 +36,24 @@ std::unique_ptr<Target::TargetInfo> CreateInfo(DevToolsAgentHost* host) {
} // namespace } // namespace
// Throttle is owned externally by the navigation subsystem.
class TargetHandler::Throttle : public content::NavigationThrottle {
public:
Throttle(base::WeakPtr<protocol::TargetHandler> target_handler,
content::NavigationHandle* navigation_handle);
~Throttle() override;
void Clear();
// content::NavigationThrottle implementation:
NavigationThrottle::ThrottleCheckResult WillProcessResponse() override;
const char* GetNameForLogging() override;
private:
base::WeakPtr<protocol::TargetHandler> target_handler_;
scoped_refptr<DevToolsAgentHost> agent_host_;
DISALLOW_COPY_AND_ASSIGN(Throttle);
};
class TargetHandler::Session : public DevToolsAgentHostClient { class TargetHandler::Session : public DevToolsAgentHostClient {
public: public:
static std::string Attach(TargetHandler* handler, static std::string Attach(TargetHandler* handler,
...@@ -61,7 +85,21 @@ class TargetHandler::Session : public DevToolsAgentHostClient { ...@@ -61,7 +85,21 @@ class TargetHandler::Session : public DevToolsAgentHostClient {
handler_->attached_sessions_.erase(id_); handler_->attached_sessions_.erase(id_);
} }
void SetThrottle(Throttle* throttle) { throttle_ = throttle; }
void SendMessageToAgentHost(const std::string& message) { void SendMessageToAgentHost(const std::string& message) {
if (throttle_) {
bool resuming = false;
std::unique_ptr<base::Value> value = base::JSONReader::Read(message);
if (value && value->is_dict()) {
base::Value* method = value->FindKey(kMethod);
resuming = method && method->is_string() &&
method->GetString() == kResumeMethod;
}
if (resuming)
throttle_->Clear();
}
agent_host_->DispatchProtocolMessage(this, message); agent_host_->DispatchProtocolMessage(this, message);
} }
...@@ -91,16 +129,63 @@ class TargetHandler::Session : public DevToolsAgentHostClient { ...@@ -91,16 +129,63 @@ class TargetHandler::Session : public DevToolsAgentHostClient {
TargetHandler* handler_; TargetHandler* handler_;
scoped_refptr<DevToolsAgentHost> agent_host_; scoped_refptr<DevToolsAgentHost> agent_host_;
std::string id_; std::string id_;
Throttle* throttle_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(Session); DISALLOW_COPY_AND_ASSIGN(Session);
}; };
TargetHandler::Throttle::Throttle(
base::WeakPtr<protocol::TargetHandler> target_handler,
content::NavigationHandle* navigation_handle)
: content::NavigationThrottle(navigation_handle),
target_handler_(target_handler) {
target_handler->throttles_.insert(this);
}
TargetHandler::Throttle::~Throttle() {
if (target_handler_)
target_handler_->throttles_.erase(this);
}
NavigationThrottle::ThrottleCheckResult
TargetHandler::Throttle::WillProcessResponse() {
if (!target_handler_)
return PROCEED;
agent_host_ =
target_handler_->auto_attacher_.AutoAttachToFrame(navigation_handle());
if (!agent_host_.get())
return PROCEED;
target_handler_->auto_attached_sessions_[agent_host_.get()]->SetThrottle(
this);
return DEFER;
}
const char* TargetHandler::Throttle::GetNameForLogging() {
return "DevToolsTargetNavigationThrottle";
}
void TargetHandler::Throttle::Clear() {
bool deferred = agent_host_.get();
if (target_handler_ && deferred) {
auto it = target_handler_->auto_attached_sessions_.find(agent_host_.get());
if (it != target_handler_->auto_attached_sessions_.end())
it->second->SetThrottle(nullptr);
}
agent_host_ = nullptr;
if (target_handler_)
target_handler_->throttles_.erase(this);
target_handler_.reset();
if (deferred)
Resume();
}
TargetHandler::TargetHandler() TargetHandler::TargetHandler()
: DevToolsDomainHandler(Target::Metainfo::domainName), : DevToolsDomainHandler(Target::Metainfo::domainName),
auto_attacher_( auto_attacher_(
base::Bind(&TargetHandler::AutoAttach, base::Unretained(this)), base::Bind(&TargetHandler::AutoAttach, base::Unretained(this)),
base::Bind(&TargetHandler::AutoDetach, base::Unretained(this))), base::Bind(&TargetHandler::AutoDetach, base::Unretained(this))),
discover_(false) {} discover_(false),
weak_factory_(this) {}
TargetHandler::~TargetHandler() { TargetHandler::~TargetHandler() {
} }
...@@ -138,6 +223,21 @@ void TargetHandler::RenderFrameHostChanged() { ...@@ -138,6 +223,21 @@ void TargetHandler::RenderFrameHostChanged() {
auto_attacher_.UpdateFrames(); auto_attacher_.UpdateFrames();
} }
std::unique_ptr<NavigationThrottle> TargetHandler::CreateThrottleForNavigation(
NavigationHandle* navigation_handle) {
if (!auto_attacher_.ShouldThrottleFramesNavigation())
return nullptr;
return std::make_unique<Throttle>(weak_factory_.GetWeakPtr(),
navigation_handle);
}
void TargetHandler::ClearThrottles() {
base::flat_set<Throttle*> copy(throttles_);
for (Throttle* throttle : copy)
throttle->Clear();
throttles_.clear();
}
void TargetHandler::AutoAttach(DevToolsAgentHost* host, void TargetHandler::AutoAttach(DevToolsAgentHost* host,
bool waiting_for_debugger) { bool waiting_for_debugger) {
std::string session_id = Session::Attach(this, host, waiting_for_debugger); std::string session_id = Session::Attach(this, host, waiting_for_debugger);
...@@ -204,11 +304,15 @@ Response TargetHandler::SetDiscoverTargets(bool discover) { ...@@ -204,11 +304,15 @@ Response TargetHandler::SetDiscoverTargets(bool discover) {
Response TargetHandler::SetAutoAttach( Response TargetHandler::SetAutoAttach(
bool auto_attach, bool wait_for_debugger_on_start) { bool auto_attach, bool wait_for_debugger_on_start) {
auto_attacher_.SetAutoAttach(auto_attach, wait_for_debugger_on_start); auto_attacher_.SetAutoAttach(auto_attach, wait_for_debugger_on_start);
if (!auto_attacher_.ShouldThrottleFramesNavigation())
ClearThrottles();
return Response::FallThrough(); return Response::FallThrough();
} }
Response TargetHandler::SetAttachToFrames(bool value) { Response TargetHandler::SetAttachToFrames(bool value) {
auto_attacher_.SetAttachToFrames(value); auto_attacher_.SetAttachToFrames(value);
if (!auto_attacher_.ShouldThrottleFramesNavigation())
ClearThrottles();
return Response::OK(); return Response::OK();
} }
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <map> #include <map>
#include <set> #include <set>
#include "base/containers/flat_set.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_domain_handler.h" #include "content/browser/devtools/protocol/devtools_domain_handler.h"
#include "content/browser/devtools/protocol/target.h" #include "content/browser/devtools/protocol/target.h"
#include "content/browser/devtools/protocol/target_auto_attacher.h" #include "content/browser/devtools/protocol/target_auto_attacher.h"
...@@ -16,6 +18,8 @@ ...@@ -16,6 +18,8 @@
namespace content { namespace content {
class DevToolsAgentHostImpl; class DevToolsAgentHostImpl;
class NavigationHandle;
class NavigationThrottle;
class RenderFrameHostImpl; class RenderFrameHostImpl;
namespace protocol { namespace protocol {
...@@ -36,6 +40,8 @@ class TargetHandler : public DevToolsDomainHandler, ...@@ -36,6 +40,8 @@ class TargetHandler : public DevToolsDomainHandler,
void DidCommitNavigation(); void DidCommitNavigation();
void RenderFrameHostChanged(); void RenderFrameHostChanged();
std::unique_ptr<NavigationThrottle> CreateThrottleForNavigation(
NavigationHandle* navigation_handle);
// Domain implementation. // Domain implementation.
Response SetDiscoverTargets(bool discover) override; Response SetDiscoverTargets(bool discover) override;
...@@ -72,6 +78,7 @@ class TargetHandler : public DevToolsDomainHandler, ...@@ -72,6 +78,7 @@ class TargetHandler : public DevToolsDomainHandler,
private: private:
class Session; class Session;
class Throttle;
void AutoAttach(DevToolsAgentHost* host, bool waiting_for_debugger); void AutoAttach(DevToolsAgentHost* host, bool waiting_for_debugger);
void AutoDetach(DevToolsAgentHost* host); void AutoDetach(DevToolsAgentHost* host);
...@@ -79,6 +86,7 @@ class TargetHandler : public DevToolsDomainHandler, ...@@ -79,6 +86,7 @@ class TargetHandler : public DevToolsDomainHandler,
Maybe<std::string> target_id, Maybe<std::string> target_id,
Session** session, Session** session,
bool fall_through); bool fall_through);
void ClearThrottles();
// DevToolsAgentHostObserver implementation. // DevToolsAgentHostObserver implementation.
bool ShouldForceDevToolsAgentHostCreation() override; bool ShouldForceDevToolsAgentHostCreation() override;
...@@ -95,6 +103,8 @@ class TargetHandler : public DevToolsDomainHandler, ...@@ -95,6 +103,8 @@ class TargetHandler : public DevToolsDomainHandler,
std::map<DevToolsAgentHost*, Session*> auto_attached_sessions_; std::map<DevToolsAgentHost*, Session*> auto_attached_sessions_;
std::set<DevToolsAgentHost*> reported_hosts_; std::set<DevToolsAgentHost*> reported_hosts_;
int last_session_id_ = 0; int last_session_id_ = 0;
base::flat_set<Throttle*> throttles_;
base::WeakPtrFactory<TargetHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(TargetHandler); DISALLOW_COPY_AND_ASSIGN(TargetHandler);
}; };
......
...@@ -81,7 +81,7 @@ bool ShouldCreateDevToolsForHost(RenderFrameHost* rfh) { ...@@ -81,7 +81,7 @@ bool ShouldCreateDevToolsForHost(RenderFrameHost* rfh) {
} }
bool ShouldCreateDevToolsForNode(FrameTreeNode* ftn) { bool ShouldCreateDevToolsForNode(FrameTreeNode* ftn) {
return ShouldCreateDevToolsForHost(ftn->current_frame_host()); return !ftn->parent() || ftn->current_frame_host()->IsCrossProcessSubframe();
} }
FrameTreeNode* GetFrameTreeNodeAncestor(FrameTreeNode* frame_tree_node) { FrameTreeNode* GetFrameTreeNodeAncestor(FrameTreeNode* frame_tree_node) {
...@@ -360,6 +360,21 @@ scoped_refptr<DevToolsAgentHost> RenderFrameDevToolsAgentHost::GetOrCreateFor( ...@@ -360,6 +360,21 @@ scoped_refptr<DevToolsAgentHost> RenderFrameDevToolsAgentHost::GetOrCreateFor(
return result; return result;
} }
// static
scoped_refptr<DevToolsAgentHost>
RenderFrameDevToolsAgentHost::GetOrCreateForDangling(
FrameTreeNode* frame_tree_node) {
// Note that this method does not use FrameTreeNode::current_frame_host(),
// since it is used while the frame host may not be set as current yet,
// for example right before commit time.
// So the caller must be sure that passed frame will indeed be a correct
// devtools target (see ShouldCreateDevToolsForNode above).
RenderFrameDevToolsAgentHost* result = FindAgentHost(frame_tree_node);
if (!result)
result = new RenderFrameDevToolsAgentHost(frame_tree_node);
return result;
}
// static // static
bool DevToolsAgentHost::HasFor(WebContents* web_contents) { bool DevToolsAgentHost::HasFor(WebContents* web_contents) {
FrameTreeNode* node = FrameTreeNode* node =
...@@ -432,21 +447,43 @@ void RenderFrameDevToolsAgentHost::OnResetNavigationRequest( ...@@ -432,21 +447,43 @@ void RenderFrameDevToolsAgentHost::OnResetNavigationRequest(
} }
// static // static
std::unique_ptr<NavigationThrottle> std::vector<std::unique_ptr<NavigationThrottle>>
RenderFrameDevToolsAgentHost::CreateThrottleForNavigation( RenderFrameDevToolsAgentHost::CreateNavigationThrottles(
NavigationHandle* navigation_handle) { NavigationHandle* navigation_handle) {
RenderFrameDevToolsAgentHost* agent_host = FindAgentHost( std::vector<std::unique_ptr<NavigationThrottle>> result;
static_cast<NavigationHandleImpl*>(navigation_handle)->frame_tree_node()); FrameTreeNode* frame_tree_node =
if (!agent_host) static_cast<NavigationHandleImpl*>(navigation_handle)->frame_tree_node();
return nullptr;
for (auto* network_handler : // Interception might throttle navigations in inspected frames.
protocol::NetworkHandler::ForAgentHost(agent_host)) { RenderFrameDevToolsAgentHost* agent_host = FindAgentHost(frame_tree_node);
std::unique_ptr<NavigationThrottle> throttle = if (agent_host) {
network_handler->CreateThrottleForNavigation(navigation_handle); for (auto* network_handler :
if (throttle) protocol::NetworkHandler::ForAgentHost(agent_host)) {
return throttle; std::unique_ptr<NavigationThrottle> throttle =
network_handler->CreateThrottleForNavigation(navigation_handle);
if (throttle)
result.push_back(std::move(throttle));
}
} }
return nullptr;
agent_host = nullptr;
if (frame_tree_node->parent()) {
// Target domain of the parent frame's DevTools may want to pause
// this frame to do some setup.
agent_host =
FindAgentHost(GetFrameTreeNodeAncestor(frame_tree_node->parent()));
}
if (agent_host) {
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));
}
}
return result;
} }
// static // static
......
...@@ -51,14 +51,20 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost ...@@ -51,14 +51,20 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
static scoped_refptr<DevToolsAgentHost> GetOrCreateFor( static scoped_refptr<DevToolsAgentHost> GetOrCreateFor(
FrameTreeNode* frame_tree_node); FrameTreeNode* frame_tree_node);
// This method does not climb up to the suitable parent frame,
// so only use it when we are sure the frame will be a local root.
// Prefer GetOrCreateFor instead.
static scoped_refptr<DevToolsAgentHost> GetOrCreateForDangling(
FrameTreeNode* frame_tree_node);
static void OnCancelPendingNavigation(RenderFrameHost* pending, static void OnCancelPendingNavigation(RenderFrameHost* pending,
RenderFrameHost* current); RenderFrameHost* current);
static void OnBeforeNavigation(RenderFrameHost* current, static void OnBeforeNavigation(RenderFrameHost* current,
RenderFrameHost* pending); RenderFrameHost* pending);
static void OnResetNavigationRequest(NavigationRequest* navigation_request); static void OnResetNavigationRequest(NavigationRequest* navigation_request);
static std::unique_ptr<NavigationThrottle> CreateThrottleForNavigation( static std::vector<std::unique_ptr<NavigationThrottle>>
NavigationHandle* navigation_handle); CreateNavigationThrottles(NavigationHandle* navigation_handle);
static bool IsNetworkHandlerEnabled(FrameTreeNode* frame_tree_node); static bool IsNetworkHandlerEnabled(FrameTreeNode* frame_tree_node);
static void AppendDevToolsHeaders(FrameTreeNode* frame_tree_node, static void AppendDevToolsHeaders(FrameTreeNode* frame_tree_node,
net::HttpRequestHeaders* headers); net::HttpRequestHeaders* headers);
......
...@@ -1322,7 +1322,10 @@ void NavigationHandleImpl::RegisterNavigationThrottles() { ...@@ -1322,7 +1322,10 @@ void NavigationHandleImpl::RegisterNavigationThrottles() {
AddThrottle( AddThrottle(
MixedContentNavigationThrottle::CreateThrottleForNavigation(this)); MixedContentNavigationThrottle::CreateThrottleForNavigation(this));
AddThrottle(RenderFrameDevToolsAgentHost::CreateThrottleForNavigation(this)); for (auto& throttle :
RenderFrameDevToolsAgentHost::CreateNavigationThrottles(this)) {
AddThrottle(std::move(throttle));
}
// Insert all testing NavigationThrottles last. // Insert all testing NavigationThrottles last.
throttles_.insert(throttles_.end(), throttles_.insert(throttles_.end(),
......
Tests that waitForDebuggerOnStart works with out-of-process iframes.
sessionId matches: true
User-Agent = test
(async function(testRunner) {
var {page, session, dp} = await testRunner.startBlank(
`Tests that waitForDebuggerOnStart works with out-of-process iframes.`);
await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: true});
await dp.Target.setAttachToFrames({value: true});
await dp.Page.enable();
session.evaluate(`
var iframe = document.createElement('iframe');
iframe.src = 'http://devtools.oopif.test:8000/inspector-protocol/target/resources/test-page.html';
document.body.appendChild(iframe);
`);
var sessionId = (await dp.Target.onceAttachedToTarget()).params.sessionId;
await dp.Target.sendMessageToTarget({
sessionId: sessionId,
message: JSON.stringify({id: 1, method: 'Network.enable'})
});
await dp.Target.sendMessageToTarget({
sessionId: sessionId,
message: JSON.stringify({id: 2, method: 'Network.setUserAgentOverride', params: {userAgent: 'test'}})
});
dp.Target.sendMessageToTarget({
sessionId: sessionId,
message: JSON.stringify({id: 3, method: 'Runtime.runIfWaitingForDebugger'})
});
dp.Target.onReceivedMessageFromTarget(event => {
var message = JSON.parse(event.params.message);
if (message.method === 'Network.requestWillBeSent') {
testRunner.log('sessionId matches: ' + (sessionId === event.params.sessionId));
testRunner.log(`User-Agent = ${message.params.request.headers['User-Agent']}`);
testRunner.completeTest();
}
});
})
...@@ -276,7 +276,7 @@ NetworkLog.NetworkLog = class extends Common.Object { ...@@ -276,7 +276,7 @@ NetworkLog.NetworkLog = class extends Common.Object {
_onMainFrameNavigated(event) { _onMainFrameNavigated(event) {
var mainFrame = /** @type {!SDK.ResourceTreeFrame} */ (event.data); var mainFrame = /** @type {!SDK.ResourceTreeFrame} */ (event.data);
var manager = mainFrame.resourceTreeModel().target().model(SDK.NetworkManager); var manager = mainFrame.resourceTreeModel().target().model(SDK.NetworkManager);
if (!manager) if (!manager || mainFrame.resourceTreeModel().target().parentTarget())
return; return;
var oldManagerRequests = this._requests.filter(request => SDK.NetworkManager.forRequest(request) === manager); var oldManagerRequests = this._requests.filter(request => SDK.NetworkManager.forRequest(request) === manager);
......
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