Skip to content

Commit

Permalink
Adding more webview browser tests to app_shell_browsertests.
Browse files Browse the repository at this point in the history
This CL includes the following tests:
- WebViewAPITest.AcceptTouchEvents
- WebViewAPITest.EmbedderVisibilityChanged
- WebViewAPITest.GuestVisibilityChanged
- WebViewAPITest.ReloadEmbedder

BUG=352293

Review URL: https://codereview.chromium.org/639693005

Cr-Commit-Position: refs/heads/master@{#299243}
  • Loading branch information
hanxi authored and Commit bot committed Oct 11, 2014
1 parent 67387c7 commit fcd89ae
Show file tree
Hide file tree
Showing 12 changed files with 368 additions and 4 deletions.
137 changes: 134 additions & 3 deletions extensions/browser/guest_view/web_view/web_view_apitest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/api/test/test_api.h"
#include "extensions/browser/app_window/app_window.h"
Expand Down Expand Up @@ -71,6 +72,30 @@ static scoped_ptr<net::test_server::HttpResponse> UserAgentResponseHandler(
return http_response.PassAs<net::test_server::HttpResponse>();
}

class WebContentsHiddenObserver : public content::WebContentsObserver {
public:
WebContentsHiddenObserver(content::WebContents* web_contents,
const base::Closure& hidden_callback)
: WebContentsObserver(web_contents),
hidden_callback_(hidden_callback),
hidden_observed_(false) {
}

// WebContentsObserver.
virtual void WasHidden() OVERRIDE {
hidden_observed_ = true;
hidden_callback_.Run();
}

bool hidden_observed() { return hidden_observed_; }

private:
base::Closure hidden_callback_;
bool hidden_observed_;

DISALLOW_COPY_AND_ASSIGN(WebContentsHiddenObserver);
};

// Handles |request| by serving a redirect response.
scoped_ptr<net::test_server::HttpResponse> RedirectResponseHandler(
const std::string& path,
Expand Down Expand Up @@ -121,10 +146,14 @@ void WebViewAPITest::LaunchApp(const std::string& app_location) {
ExtensionTestMessageListener launch_listener("LAUNCHED", false);
ASSERT_TRUE(launch_listener.WaitUntilSatisfied());

embedder_web_contents_ = GetFirstAppWindowWebContents();
}

content::WebContents* WebViewAPITest::GetFirstAppWindowWebContents() {
const AppWindowRegistry::AppWindowList& app_window_list =
AppWindowRegistry::Get(browser_context_)->app_windows();
DCHECK(app_window_list.size() == 1);
embedder_web_contents_ = (*app_window_list.begin())->web_contents();
return (*app_window_list.begin())->web_contents();
}

void WebViewAPITest::RunTest(const std::string& test_name,
Expand Down Expand Up @@ -196,19 +225,122 @@ void WebViewAPITest::TearDownOnMainThread() {
AppShellTest::TearDownOnMainThread();
}

void WebViewAPITest::SendMessageToEmbedder(const std::string& message) {
EXPECT_TRUE(
content::ExecuteScript(
GetEmbedderWebContents(),
base::StringPrintf("onAppCommand('%s');", message.c_str())));
}

content::WebContents* WebViewAPITest::GetEmbedderWebContents() {
if (!embedder_web_contents_)
embedder_web_contents_ = GetFirstAppWindowWebContents();
return embedder_web_contents_;
}

TestGuestViewManager* WebViewAPITest::GetGuestViewManager() {
return static_cast<TestGuestViewManager*>(
TestGuestViewManager::FromBrowserContext(
ShellContentBrowserClient::Get()->GetBrowserContext()));
}

void WebViewAPITest::SendMessageToGuestAndWait(
const std::string& message,
const std::string& wait_message) {
scoped_ptr<ExtensionTestMessageListener> listener;
if (!wait_message.empty())
listener.reset(new ExtensionTestMessageListener(wait_message, false));

EXPECT_TRUE(
content::ExecuteScript(
GetGuestWebContents(),
base::StringPrintf("onAppCommand('%s');", message.c_str())));

if (listener)
ASSERT_TRUE(listener->WaitUntilSatisfied());
}

void WebViewDPIAPITest::SetUp() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor,
base::StringPrintf("%f", scale()));
WebViewAPITest::SetUp();
}

content::WebContents* WebViewAPITest::GetGuestWebContents() {
return GetGuestViewManager()->WaitForSingleGuestCreated();
}

IN_PROC_BROWSER_TEST_F(WebViewAPITest, AcceptTouchEvents) {
LaunchApp("web_view/accept_touch_events");

content::RenderViewHost* embedder_rvh =
GetEmbedderWebContents()->GetRenderViewHost();

bool embedder_has_touch_handler =
content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
EXPECT_FALSE(embedder_has_touch_handler);

SendMessageToGuestAndWait("install-touch-handler", "installed-touch-handler");

// Note that we need to wait for the installed/registered touch handler to
// appear in browser process before querying |embedder_rvh|.
// In practice, since we do a roundrtip from browser process to guest and
// back, this is sufficient.
embedder_has_touch_handler =
content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
EXPECT_TRUE(embedder_has_touch_handler);

SendMessageToGuestAndWait("uninstall-touch-handler",
"uninstalled-touch-handler");
// Same as the note above about waiting.
embedder_has_touch_handler =
content::RenderViewHostTester::HasTouchEventHandler(embedder_rvh);
EXPECT_FALSE(embedder_has_touch_handler);
}

// This test verifies that hiding the embedder also hides the guest.
IN_PROC_BROWSER_TEST_F(WebViewAPITest, EmbedderVisibilityChanged) {
LaunchApp("web_view/visibility_changed");

scoped_refptr<content::MessageLoopRunner> loop_runner(
new content::MessageLoopRunner);
WebContentsHiddenObserver observer(GetGuestWebContents(),
loop_runner->QuitClosure());

// Handled in web_view/visibility_changed/main.js
SendMessageToEmbedder("hide-embedder");
if (!observer.hidden_observed())
loop_runner->Run();
}

// This test verifies that hiding the guest triggers WebContents::WasHidden().
IN_PROC_BROWSER_TEST_F(WebViewAPITest, GuestVisibilityChanged) {
LaunchApp("web_view/visibility_changed");

scoped_refptr<content::MessageLoopRunner> loop_runner(
new content::MessageLoopRunner);
WebContentsHiddenObserver observer(GetGuestWebContents(),
loop_runner->QuitClosure());

// Handled in web_view/visibility_changed/main.js
SendMessageToEmbedder("hide-guest");
if (!observer.hidden_observed())
loop_runner->Run();
}

// This test verifies that reloading the embedder reloads the guest (and doest
// not crash).
IN_PROC_BROWSER_TEST_F(WebViewAPITest, ReloadEmbedder) {
// Just load a guest from other test, we do not want to add a separate
// app for this test.
LaunchApp("web_view/visibility_changed");

ExtensionTestMessageListener launched_again_listener("LAUNCHED", false);
embedder_web_contents_->GetController().Reload(false);
ASSERT_TRUE(launched_again_listener.WaitUntilSatisfied());
}

IN_PROC_BROWSER_TEST_F(WebViewAPITest, TestAllowTransparencyAttribute) {
RunTest("testAllowTransparencyAttribute", "web_view/apitest");
}
Expand Down Expand Up @@ -476,8 +608,7 @@ IN_PROC_BROWSER_TEST_F(WebViewAPITest, TestRemoveWebviewOnExit) {
EXPECT_TRUE(content::ExecuteScript(embedder_web_contents_,
"runTest('testRemoveWebviewOnExit')"));

content::WebContents* guest_web_contents =
GetGuestViewManager()->WaitForSingleGuestCreated();
content::WebContents* guest_web_contents = GetGuestWebContents();
EXPECT_TRUE(guest_web_contents->GetRenderProcessHost()->IsIsolatedGuest());
ASSERT_TRUE(guest_loaded_listener.WaitUntilSatisfied());

Expand Down
11 changes: 10 additions & 1 deletion extensions/browser/guest_view/web_view/web_view_apitest.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,28 @@ class WebViewAPITest : public AppShellTest {
void StartTestServer();
void StopTestServer();

content::WebContents* GetEmbedderWebContents();

// Returns the GuestViewManager singleton.
TestGuestViewManager* GetGuestViewManager();

content::WebContents* GetGuestWebContents();
void SendMessageToGuestAndWait(const std::string& message,
const std::string& wait_message);
void SendMessageToEmbedder(const std::string& message);

// content::BrowserTestBase implementation.
virtual void RunTestOnMainThreadLoop() override;
virtual void SetUpCommandLine(base::CommandLine* command_line) override;
virtual void SetUpOnMainThread() override;
virtual void TearDownOnMainThread() override;

protected:
content::WebContents* embedder_web_contents_;
TestGuestViewManagerFactory factory_;
base::DictionaryValue test_config_;

private:
content::WebContents* GetFirstAppWindowWebContents();
};

class WebViewDPIAPITest : public WebViewAPITest {
Expand Down
15 changes: 15 additions & 0 deletions extensions/test/data/web_view/accept_touch_events/guest.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<!--
* Copyright 2014 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.
-->
<html>
<head>
<script type="text/javascript" src="guest.js"></script>
</head>
<body>
Test guest.
<div id="touch-div"></div>
</body>
</html>
51 changes: 51 additions & 0 deletions extensions/test/data/web_view/accept_touch_events/guest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2014 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.

var LOG = function(msg) {
window.console.log(msg);
};

var touchDiv;
var embedder;

function init() {
touchDiv = document.createElement('div');
touchDiv.innerText = 'With touch';
document.body.appendChild(touchDiv);
}

function handler() {}

function onAppCommand(command) {
LOG('onAppCommand, command = ' + command);
switch (command) {
case 'install-touch-handler':
touchDiv.addEventListener('touchstart', handler);
sendMessageToEmbedder('installed-touch-handler');
break;
case 'uninstall-touch-handler':
touchDiv.removeEventListener('touchstart', handler);
sendMessageToEmbedder('uninstalled-touch-handler');
break;
}
};

function sendMessageToEmbedder(message) {
if (!embedder) {
LOG('no embedder channel to send postMessage');
return;
}

embedder.postMessage(JSON.stringify([message]), '*');
}

window.addEventListener('message', function(e) {
embedder = e.source;
var data = JSON.parse(e.data);
if (data[0] == 'connect') {
sendMessageToEmbedder('connected');
}
});

window.onload = init;
12 changes: 12 additions & 0 deletions extensions/test/data/web_view/accept_touch_events/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<!--
* Copyright 2014 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.
-->
<html>
<body>
<div id="webview-tag-container"></div>
<script src="main.js"></script>
</body>
</html>
43 changes: 43 additions & 0 deletions extensions/test/data/web_view/accept_touch_events/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2014 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.

var LOG = function(msg) {
window.console.log(msg);
};

var startTest = function() {
var webview = document.querySelector('webview');
var onLoadStop = function(e) {
webview.contentWindow.postMessage(JSON.stringify(['connect']),'*');
};

webview.addEventListener('loadstop', onLoadStop);
webview.addEventListener('consolemessage', function(e) {
LOG('g: ' + e.message);
});
webview.partition = 'partition1';
webview.src = 'guest.html';
};

window.addEventListener('message', function(e) {
var data = JSON.parse(e.data);
LOG('data: ' + data);
switch (data[0]) {
case 'connected':
chrome.test.sendMessage('LAUNCHED');
break;
case 'installed-touch-handler':
case 'uninstalled-touch-handler':
chrome.test.sendMessage(data[0]);
break;
}
});

chrome.test.getConfig(function(config) {
var guestURL = 'data:text/html,<html><body>foo</body></html>';
document.querySelector('#webview-tag-container').innerHTML =
'<webview style="width: 10px; height: 10px; margin: 0; padding: 0;"' +
'></webview>';
startTest();
});
23 changes: 23 additions & 0 deletions extensions/test/data/web_view/accept_touch_events/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "<webview> touch handler registration test.",
"version": "1",
"permissions": [
"webview"
],
"app": {
"background": {
"scripts": ["test.js"]
}
},
"webview": {
"partitions": [
{
"name": "partition1",
"accessible_resources": [
"guest.js",
"guest.html"
]
}
]
}
}
7 changes: 7 additions & 0 deletions extensions/test/data/web_view/accept_touch_events/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright 2014 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.

chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('main.html', {}, function () {});
});
12 changes: 12 additions & 0 deletions extensions/test/data/web_view/visibility_changed/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<!--
* Copyright 2014 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.
-->
<html>
<body>
<div id="webview-tag-container"></div>
<script src="main.js"></script>
</body>
</html>
Loading

0 comments on commit fcd89ae

Please sign in to comment.