app_process_apitest.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_apitest.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_process_manager.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/profile.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/ui_test_utils.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/mock_host_resolver.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AppApiTest : public ExtensionApiTest {
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetUpCommandLine(CommandLine* command_line) {
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionApiTest::SetUpCommandLine(command_line);
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    command_line->AppendSwitch(switches::kEnableApps);
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Simulates a page calling window.open on an URL, and waits for the navigation.
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void WindowOpenHelper(Browser* browser,
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             RenderViewHost* opener_host, const GURL& url) {
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool result = false;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::ExecuteJavaScriptAndExtractBool(
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      opener_host, L"",
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"window.open('" + UTF8ToWide(url.spec()) + L"');"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"window.domAutomationController.send(true);",
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &result);
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(result);
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now the current tab should be the new tab.
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* newtab = browser->GetSelectedTabContents();
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!newtab->controller().GetLastCommittedEntry() ||
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      newtab->controller().GetLastCommittedEntry()->url() != url)
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_test_utils::WaitForNavigation(&newtab->controller());
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(url, newtab->controller().GetLastCommittedEntry()->url());
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Simulates a page navigating itself to an URL, and waits for the navigation.
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void NavigateTabHelper(TabContents* contents, const GURL& url) {
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool result = false;
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::ExecuteJavaScriptAndExtractBool(
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents->render_view_host(), L"",
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"window.addEventListener('unload', function() {"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"    window.domAutomationController.send(true);"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"}, false);"
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"window.location = '" + UTF8ToWide(url.spec()) + L"';",
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &result);
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(result);
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!contents->controller().GetLastCommittedEntry() ||
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents->controller().GetLastCommittedEntry()->url() != url)
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_test_utils::WaitForNavigation(&contents->controller());
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(url, contents->controller().GetLastCommittedEntry()->url());
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(AppApiTest, AppProcess) {
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  host_resolver()->AddRule("*", "127.0.0.1");
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(StartHTTPServer());
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(RunExtensionTest("app_process")) << message_;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension* extension = GetSingleLoadedExtension();
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionHost* host = browser()->profile()->GetExtensionProcessManager()->
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetBackgroundHostForExtension(extension);
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(host);
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The extension should have opened 3 new tabs. Including the original blank
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // tab, we now have 4 tabs. Two should be part of the extension app, and
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // grouped in the extension process.
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(4, browser()->tab_count());
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(host->render_process_host(),
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(1)->render_view_host()->process());
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(host->render_process_host(),
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(2)->render_view_host()->process());
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(host->render_process_host(),
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(3)->render_view_host()->process());
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now let's do the same using window.open. The same should happen.
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL base_url("http://localhost:1337/files/extensions/api_test/app_process/");
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WindowOpenHelper(browser(), host->render_view_host(),
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   base_url.Resolve("path1/empty.html"));
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WindowOpenHelper(browser(), host->render_view_host(),
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   base_url.Resolve("path2/empty.html"));
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WindowOpenHelper(browser(), host->render_view_host(),
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   base_url.Resolve("path3/empty.html"));
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(7, browser()->tab_count());
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(host->render_process_host(),
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(4)->render_view_host()->process());
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(host->render_process_host(),
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(5)->render_view_host()->process());
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(host->render_process_host(),
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(6)->render_view_host()->process());
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now let's have these pages navigate, into or out of the extension web
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // extent. They should switch processes.
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL& app_url(base_url.Resolve("path1/empty.html"));
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL& non_app_url(base_url.Resolve("path3/empty.html"));
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigateTabHelper(browser()->GetTabContentsAt(1), non_app_url);
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigateTabHelper(browser()->GetTabContentsAt(3), app_url);
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(host->render_process_host(),
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(1)->render_view_host()->process());
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(host->render_process_host(),
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(3)->render_view_host()->process());
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate the non-app tab into the browse extent. It should not enter the
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // app process.
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigate the app tab into the browse extent. It should stay in the app
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // process.
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL& browse_url(base_url.Resolve("path4/empty.html"));
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigateTabHelper(browser()->GetTabContentsAt(1), browse_url);
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigateTabHelper(browser()->GetTabContentsAt(3), browse_url);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(host->render_process_host(),
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(1)->render_view_host()->process());
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(host->render_process_host(),
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            browser()->GetTabContentsAt(3)->render_view_host()->process());
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
123