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") {
"chrome/device_manager.h",
"chrome/device_metrics.cc",
"chrome/device_metrics.h",
"chrome/devtools_client.cc",
"chrome/devtools_client.h",
"chrome/devtools_client_impl.cc",
"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 {
// Set the owning WebViewImpl, if any.
virtual void SetOwner(WebViewImpl* owner) = 0;
virtual DevToolsClient* GetRootClient() = 0;
virtual bool IsMainPage();
};
#endif // CHROME_TEST_CHROMEDRIVER_CHROME_DEVTOOLS_CLIENT_H_
......@@ -339,7 +339,7 @@ DevToolsClientImpl::ResponseInfo::ResponseInfo(const std::string& method)
DevToolsClientImpl::ResponseInfo::~ResponseInfo() {}
DevToolsClientImpl* DevToolsClientImpl::GetRootClient() {
DevToolsClient* DevToolsClientImpl::GetRootClient() {
return parent_ ? parent_ : this;
}
......@@ -370,7 +370,8 @@ Status DevToolsClientImpl::SendCommandInternal(
VLOG(1) << "DevTools WebSocket Command: " << method << " (id=" << command_id
<< ") " << id_ << " " << FormatValueForDisplay(params);
}
SyncWebSocket* socket = GetRootClient()->socket_.get();
SyncWebSocket* socket =
static_cast<DevToolsClientImpl*>(GetRootClient())->socket_.get();
if (!socket->Send(message)) {
return Status(kDisconnected, "unable to send message to renderer");
}
......
......@@ -121,7 +121,7 @@ class DevToolsClientImpl : public DevToolsClient {
Status HandleReceivedEvents() override;
void SetDetached() override;
void SetOwner(WebViewImpl* owner) override;
DevToolsClientImpl* GetRootClient();
DevToolsClient* GetRootClient() override;
private:
enum ResponseState {
......
......@@ -219,8 +219,9 @@ Status NavigationTracker::OnConnected(DevToolsClient* client) {
Status NavigationTracker::OnEvent(DevToolsClient* client,
const std::string& method,
const base::DictionaryValue& params) {
if (method == "Page.loadEventFired" ||
(is_eager_ && method == "Page.domContentEventFired")) {
if (client->IsMainPage() &&
(method == "Page.loadEventFired" ||
(is_eager_ && method == "Page.domContentEventFired"))) {
frame_to_state_map_[top_frame_id_] = kNotLoading;
return UpdateCurrentLoadingState();
} else if (method == "Page.frameAttached") {
......
......@@ -95,3 +95,7 @@ Status StubDevToolsClient::HandleReceivedEvents() {
void StubDevToolsClient::SetDetached() {}
void StubDevToolsClient::SetOwner(WebViewImpl* owner) {}
DevToolsClient* StubDevToolsClient::GetRootClient() {
return this;
}
......@@ -60,6 +60,7 @@ class StubDevToolsClient : public DevToolsClient {
Status HandleReceivedEvents() override;
void SetDetached() override;
void SetOwner(WebViewImpl* owner) override;
DevToolsClient* GetRootClient() override;
protected:
const std::string id_;
......
......@@ -205,7 +205,7 @@ WebViewImpl* WebViewImpl::CreateChild(const std::string& session_id,
// sends/receives over the socket, and all child sessions are considered
// its children (one level deep at most).
DevToolsClientImpl* root_client =
static_cast<DevToolsClientImpl*>(client_.get())->GetRootClient();
static_cast<DevToolsClientImpl*>(client_.get()->GetRootClient());
std::unique_ptr<DevToolsClient> child_client(
std::make_unique<DevToolsClientImpl>(root_client, session_id));
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