Commit 0ebee667 authored by Shengfa Lin's avatar Shengfa Lin Committed by Commit Bot

[chromedriver] Navigation completes prematurely if OOPIF loads before

main page

Chrome has recent behavior change that it sends out load event fired
for Out of Process Iframe(OOPIF). When ChromeDriver received it, it assumed that it's for the
main page causing navigation to complete prematurely.

The fix is to check the load event fired come from main page.

Bug: chromedriver:3594
Change-Id: Icdc589ec6733c28e549b9110ea225fe7df00ce01
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2402323Reviewed-by: default avatarJohn Chen <johnchen@chromium.org>
Commit-Queue: Shengfa Lin <shengfa@google.com>
Cr-Commit-Position: refs/heads/master@{#805953}
parent 3d68961e
...@@ -81,6 +81,7 @@ source_set("automation_client_lib") { ...@@ -81,6 +81,7 @@ source_set("automation_client_lib") {
"chrome/device_manager.h", "chrome/device_manager.h",
"chrome/device_metrics.cc", "chrome/device_metrics.cc",
"chrome/device_metrics.h", "chrome/device_metrics.h",
"chrome/devtools_client.cc",
"chrome/devtools_client.h", "chrome/devtools_client.h",
"chrome/devtools_client_impl.cc", "chrome/devtools_client_impl.cc",
"chrome/devtools_client_impl.h", "chrome/devtools_client_impl.h",
......
// Copyright (c) 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/test/chromedriver/chrome/devtools_client.h"
bool DevToolsClient::IsMainPage() {
return GetRootClient() == this;
}
...@@ -87,6 +87,10 @@ class DevToolsClient { ...@@ -87,6 +87,10 @@ class DevToolsClient {
// Set the owning WebViewImpl, if any. // Set the owning WebViewImpl, if any.
virtual void SetOwner(WebViewImpl* owner) = 0; virtual void SetOwner(WebViewImpl* owner) = 0;
virtual DevToolsClient* GetRootClient() = 0;
virtual bool IsMainPage();
}; };
#endif // CHROME_TEST_CHROMEDRIVER_CHROME_DEVTOOLS_CLIENT_H_ #endif // CHROME_TEST_CHROMEDRIVER_CHROME_DEVTOOLS_CLIENT_H_
...@@ -339,7 +339,7 @@ DevToolsClientImpl::ResponseInfo::ResponseInfo(const std::string& method) ...@@ -339,7 +339,7 @@ DevToolsClientImpl::ResponseInfo::ResponseInfo(const std::string& method)
DevToolsClientImpl::ResponseInfo::~ResponseInfo() {} DevToolsClientImpl::ResponseInfo::~ResponseInfo() {}
DevToolsClientImpl* DevToolsClientImpl::GetRootClient() { DevToolsClient* DevToolsClientImpl::GetRootClient() {
return parent_ ? parent_ : this; return parent_ ? parent_ : this;
} }
...@@ -370,7 +370,8 @@ Status DevToolsClientImpl::SendCommandInternal( ...@@ -370,7 +370,8 @@ Status DevToolsClientImpl::SendCommandInternal(
VLOG(1) << "DevTools WebSocket Command: " << method << " (id=" << command_id VLOG(1) << "DevTools WebSocket Command: " << method << " (id=" << command_id
<< ") " << id_ << " " << FormatValueForDisplay(params); << ") " << id_ << " " << FormatValueForDisplay(params);
} }
SyncWebSocket* socket = GetRootClient()->socket_.get(); SyncWebSocket* socket =
static_cast<DevToolsClientImpl*>(GetRootClient())->socket_.get();
if (!socket->Send(message)) { if (!socket->Send(message)) {
return Status(kDisconnected, "unable to send message to renderer"); return Status(kDisconnected, "unable to send message to renderer");
} }
......
...@@ -121,7 +121,7 @@ class DevToolsClientImpl : public DevToolsClient { ...@@ -121,7 +121,7 @@ class DevToolsClientImpl : public DevToolsClient {
Status HandleReceivedEvents() override; Status HandleReceivedEvents() override;
void SetDetached() override; void SetDetached() override;
void SetOwner(WebViewImpl* owner) override; void SetOwner(WebViewImpl* owner) override;
DevToolsClientImpl* GetRootClient(); DevToolsClient* GetRootClient() override;
private: private:
enum ResponseState { enum ResponseState {
......
...@@ -219,8 +219,9 @@ Status NavigationTracker::OnConnected(DevToolsClient* client) { ...@@ -219,8 +219,9 @@ Status NavigationTracker::OnConnected(DevToolsClient* client) {
Status NavigationTracker::OnEvent(DevToolsClient* client, Status NavigationTracker::OnEvent(DevToolsClient* client,
const std::string& method, const std::string& method,
const base::DictionaryValue& params) { const base::DictionaryValue& params) {
if (method == "Page.loadEventFired" || if (client->IsMainPage() &&
(is_eager_ && method == "Page.domContentEventFired")) { (method == "Page.loadEventFired" ||
(is_eager_ && method == "Page.domContentEventFired"))) {
frame_to_state_map_[top_frame_id_] = kNotLoading; frame_to_state_map_[top_frame_id_] = kNotLoading;
return UpdateCurrentLoadingState(); return UpdateCurrentLoadingState();
} else if (method == "Page.frameAttached") { } else if (method == "Page.frameAttached") {
......
...@@ -95,3 +95,7 @@ Status StubDevToolsClient::HandleReceivedEvents() { ...@@ -95,3 +95,7 @@ Status StubDevToolsClient::HandleReceivedEvents() {
void StubDevToolsClient::SetDetached() {} void StubDevToolsClient::SetDetached() {}
void StubDevToolsClient::SetOwner(WebViewImpl* owner) {} void StubDevToolsClient::SetOwner(WebViewImpl* owner) {}
DevToolsClient* StubDevToolsClient::GetRootClient() {
return this;
}
...@@ -60,6 +60,7 @@ class StubDevToolsClient : public DevToolsClient { ...@@ -60,6 +60,7 @@ class StubDevToolsClient : public DevToolsClient {
Status HandleReceivedEvents() override; Status HandleReceivedEvents() override;
void SetDetached() override; void SetDetached() override;
void SetOwner(WebViewImpl* owner) override; void SetOwner(WebViewImpl* owner) override;
DevToolsClient* GetRootClient() override;
protected: protected:
const std::string id_; const std::string id_;
......
...@@ -205,7 +205,7 @@ WebViewImpl* WebViewImpl::CreateChild(const std::string& session_id, ...@@ -205,7 +205,7 @@ WebViewImpl* WebViewImpl::CreateChild(const std::string& session_id,
// sends/receives over the socket, and all child sessions are considered // sends/receives over the socket, and all child sessions are considered
// its children (one level deep at most). // its children (one level deep at most).
DevToolsClientImpl* root_client = DevToolsClientImpl* root_client =
static_cast<DevToolsClientImpl*>(client_.get())->GetRootClient(); static_cast<DevToolsClientImpl*>(client_.get()->GetRootClient());
std::unique_ptr<DevToolsClient> child_client( std::unique_ptr<DevToolsClient> child_client(
std::make_unique<DevToolsClientImpl>(root_client, session_id)); std::make_unique<DevToolsClientImpl>(root_client, session_id));
WebViewImpl* child = new WebViewImpl( WebViewImpl* child = new WebViewImpl(
......
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