0

Portals: Add devtools console test

Add a basic test for the devtools console working correctly with
portals. For this test to work correctly, I also had to fix an issue
where the document's load event was being sent before the portal's
load event.

Bug: 929356
Change-Id: I61c26edc4078553cfce73e3095b78f3cb25f42fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1800479
Commit-Queue: Adithya Srinivasan <adithyas@chromium.org>
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Lucas Gadani <lfg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#698532}
This commit is contained in:
Adithya Srinivasan
2019-09-20 17:33:11 +00:00
committed by Commit Bot
parent 9877361000
commit bd1d82167d
7 changed files with 76 additions and 10 deletions
content/browser/portal
third_party/blink
public
mojom
renderer
core
web_tests

@ -189,7 +189,9 @@ RenderFrameProxyHost* Portal::CreateProxyAndAttachPortal() {
return proxy_host;
}
void Portal::Navigate(const GURL& url, blink::mojom::ReferrerPtr referrer) {
void Portal::Navigate(const GURL& url,
blink::mojom::ReferrerPtr referrer,
NavigateCallback callback) {
if (!url.SchemeIsHTTPOrHTTPS()) {
mojo::ReportBadMessage("Portal::Navigate tried to use non-HTTP protocol.");
binding_->Close(); // Also deletes |this|.
@ -212,6 +214,8 @@ void Portal::Navigate(const GURL& url, blink::mojom::ReferrerPtr referrer) {
owner_render_frame_host_->GetSiteInstance(),
mojo::ConvertTo<Referrer>(referrer), ui::PAGE_TRANSITION_LINK, false,
download_policy, "GET", nullptr, "", nullptr, false);
std::move(callback).Run();
}
namespace {

@ -68,7 +68,9 @@ class CONTENT_EXPORT Portal : public blink::mojom::Portal,
RenderFrameProxyHost* CreateProxyAndAttachPortal();
// blink::mojom::Portal implementation.
void Navigate(const GURL& url, blink::mojom::ReferrerPtr referrer) override;
void Navigate(const GURL& url,
blink::mojom::ReferrerPtr referrer,
NavigateCallback callback) override;
void Activate(blink::TransferableMessage data,
ActivateCallback callback) override;
void PostMessageToGuest(

@ -66,13 +66,15 @@ class PortalInterceptorForTesting final
portal_->Activate(std::move(data), std::move(callback));
}
void Navigate(const GURL& url, blink::mojom::ReferrerPtr referrer) override {
void Navigate(const GURL& url,
blink::mojom::ReferrerPtr referrer,
NavigateCallback callback) override {
if (navigate_callback_) {
navigate_callback_.Run(url, std::move(referrer));
navigate_callback_.Run(url, std::move(referrer), std::move(callback));
return;
}
portal_->Navigate(url, std::move(referrer));
portal_->Navigate(url, std::move(referrer), std::move(callback));
}
void WaitForActivate() {
@ -89,7 +91,8 @@ class PortalInterceptorForTesting final
WebContents* GetPortalContents() { return portal_->GetPortalContents(); }
// IPC callbacks
base::RepeatingCallback<void(const GURL&, blink::mojom::ReferrerPtr)>
base::RepeatingCallback<
void(const GURL&, blink::mojom::ReferrerPtr, NavigateCallback)>
navigate_callback_;
private:
@ -762,9 +765,10 @@ IN_PROC_BROWSER_TEST_F(PortalBrowserTest, NavigateToChrome) {
// Try to navigate to chrome://settings and wait for the process to die.
portal_interceptor->navigate_callback_ = base::BindRepeating(
[](Portal* portal, const GURL& url, blink::mojom::ReferrerPtr referrer) {
[](Portal* portal, const GURL& url, blink::mojom::ReferrerPtr referrer,
blink::mojom::Portal::NavigateCallback callback) {
GURL chrome_url("chrome://settings");
portal->Navigate(chrome_url, std::move(referrer));
portal->Navigate(chrome_url, std::move(referrer), std::move(callback));
},
portal);
RenderProcessHostKillWaiter kill_waiter(main_frame->GetProcess());

@ -16,7 +16,7 @@ import "url/mojom/origin.mojom";
// (content::Portal). It is 1:1 with PortalClient (defined below).
interface Portal {
// Navigates the portal to |url|.
Navigate(url.mojom.Url url, Referrer referrer);
Navigate(url.mojom.Url url, Referrer referrer) => ();
// When a portal is activated, it'll replace the current tab with the portal.
Activate(TransferableMessage data) => (bool was_adopted);

@ -7,6 +7,7 @@
#include "third_party/blink/public/mojom/referrer.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/document_shutdown_observer.h"
#include "third_party/blink/renderer/core/dom/increment_load_event_delay_count.h"
#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/core/html/portal/document_portals.h"
#include "third_party/blink/renderer/core/html/portal/html_portal_element.h"
@ -101,7 +102,20 @@ void PortalContents::Navigate(
auto mojo_referrer = mojom::blink::Referrer::New(
KURL(NullURL(), referrer.referrer), referrer.referrer_policy);
remote_portal_->Navigate(url, std::move(mojo_referrer));
// There is a brief window of time between when Navigate is called and its
// callback is run, during which the Portal's content frame is not marked as
// loading. We use IncrementLoadEventDelayCount to block its document's load
// event in this time window. Once it goes out of scope,
// IncrementLoadEventDelayCount will call Document::CheckCompleted and fire
// load events if necessary.
std::unique_ptr<IncrementLoadEventDelayCount>
increment_load_event_delay_count =
std::make_unique<IncrementLoadEventDelayCount>(GetDocument());
remote_portal_->Navigate(
url, std::move(mojo_referrer),
WTF::Bind([](std::unique_ptr<IncrementLoadEventDelayCount>
increment_load_event_delay_count) {},
std::move(increment_load_event_delay_count)));
}
void PortalContents::Destroy() {

@ -0,0 +1,8 @@
Tests that the console works correctly with portals
Running: testMainConsole
!!window.portalHost = false
Running: testPortalConsole
!!window.portalHost = true

@ -0,0 +1,34 @@
// Copyright 2019 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.
(async function() {
TestRunner.addResult(`Tests that the console works correctly with portals`);
await TestRunner.loadModule('console_test_runner');
await TestRunner.showPanel('console');
await TestRunner.navigatePromise('resources/portal_host.html');
async function setContextLabel(target, label) {
var runtimeModel = target.model(SDK.RuntimeModel);
await TestRunner.waitForExecutionContext(runtimeModel);
runtimeModel.executionContexts()[0].setLabel(label);
}
var targets = SDK.targetManager.targets();
TestRunner.assertEquals(2, targets.length);
TestRunner.runTestSuite([
async function testMainConsole(next) {
ConsoleTestRunner.selectMainExecutionContext();
ConsoleTestRunner.evaluateInConsoleAndDump("!!window.portalHost", next);
},
async function testPortalConsole() {
await setContextLabel(targets[1], "portal");
ConsoleTestRunner.changeExecutionContext("portal");
ConsoleTestRunner.evaluateInConsoleAndDump("!!window.portalHost",
TestRunner.completeTest, true);
}
]);
})();