blob: 389c23a0575383bb251eb8cbbc3281617509f3ca [file] [log] [blame]
[email protected]f2fe87c2012-04-24 17:53:491// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]a964e112011-04-14 21:52:512// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string>
6
7#include "base/command_line.h"
8#include "base/json/json_reader.h"
[email protected]0ef01962011-06-14 08:33:379#include "base/memory/scoped_ptr.h"
[email protected]3ea1b182013-02-08 22:38:4110#include "base/strings/string_number_conversions.h"
[email protected]a964e112011-04-14 21:52:5111#include "base/values.h"
12#include "chrome/browser/extensions/extension_browsertest.h"
[email protected]f2fe87c2012-04-24 17:53:4913#include "chrome/browser/extensions/extension_service.h"
14#include "chrome/browser/profiles/profile.h"
[email protected]a964e112011-04-14 21:52:5115#include "chrome/browser/ui/browser.h"
[email protected]47ae23372013-01-29 01:50:4816#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]af44e7fb2011-07-29 18:32:3217#include "chrome/test/base/ui_test_utils.h"
[email protected]4ca15302012-01-03 05:53:2018#include "content/public/browser/web_contents.h"
[email protected]7d478cb2012-07-24 17:19:4219#include "content/public/test/browser_test_utils.h"
[email protected]e4452d32013-11-15 23:07:4120#include "extensions/common/extension.h"
[email protected]d42c11152013-08-22 19:36:3221#include "extensions/common/manifest.h"
[email protected]f2cb3cf2013-03-21 01:40:5322#include "net/dns/mock_host_resolver.h"
nickfa2254b2015-08-07 23:27:2923#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]a6483d22013-07-03 22:11:0024#include "url/gurl.h"
[email protected]a964e112011-04-14 21:52:5125
[email protected]1c321ee2012-05-21 03:02:3426using extensions::Extension;
27
[email protected]a964e112011-04-14 21:52:5128class ChromeAppAPITest : public ExtensionBrowserTest {
[email protected]80675fc2011-06-21 02:05:4929 protected:
[email protected]b27c3622014-03-22 00:26:5530 bool IsAppInstalledInMainFrame() {
31 return IsAppInstalledInFrame(
32 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
33 }
34 bool IsAppInstalledInIFrame() {
35 return IsAppInstalledInFrame(GetIFrame());
36 }
37 bool IsAppInstalledInFrame(content::RenderFrameHost* frame) {
[email protected]06bc5d92013-01-02 22:44:1338 const char kGetAppIsInstalled[] =
39 "window.domAutomationController.send(window.chrome.app.isInstalled);";
[email protected]80675fc2011-06-21 02:05:4940 bool result;
[email protected]b27c3622014-03-22 00:26:5541 CHECK(content::ExecuteScriptAndExtractBool(frame,
42 kGetAppIsInstalled,
43 &result));
[email protected]f2fe87c2012-04-24 17:53:4944 return result;
45 }
46
[email protected]b27c3622014-03-22 00:26:5547 std::string InstallStateInMainFrame() {
48 return InstallStateInFrame(
49 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
50 }
51 std::string InstallStateInIFrame() {
52 return InstallStateInFrame(GetIFrame());
53 }
54 std::string InstallStateInFrame(content::RenderFrameHost* frame) {
[email protected]06bc5d92013-01-02 22:44:1355 const char kGetAppInstallState[] =
56 "window.chrome.app.installState("
57 " function(s) { window.domAutomationController.send(s); });";
[email protected]f2fe87c2012-04-24 17:53:4958 std::string result;
[email protected]b27c3622014-03-22 00:26:5559 CHECK(content::ExecuteScriptAndExtractString(frame,
60 kGetAppInstallState,
61 &result));
[email protected]f2fe87c2012-04-24 17:53:4962 return result;
63 }
64
[email protected]b27c3622014-03-22 00:26:5565 std::string RunningStateInMainFrame() {
66 return RunningStateInFrame(
67 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame());
68 }
69 std::string RunningStateInIFrame() {
70 return RunningStateInFrame(GetIFrame());
71 }
72 std::string RunningStateInFrame(content::RenderFrameHost* frame) {
[email protected]06bc5d92013-01-02 22:44:1373 const char kGetAppRunningState[] =
74 "window.domAutomationController.send("
75 " window.chrome.app.runningState());";
[email protected]f2fe87c2012-04-24 17:53:4976 std::string result;
[email protected]b27c3622014-03-22 00:26:5577 CHECK(content::ExecuteScriptAndExtractString(frame,
78 kGetAppRunningState,
79 &result));
[email protected]80675fc2011-06-21 02:05:4980 return result;
81 }
82
[email protected]a964e112011-04-14 21:52:5183 private:
[email protected]b27c3622014-03-22 00:26:5584 content::RenderFrameHost* GetIFrame() {
85 return content::FrameMatchingPredicate(
86 browser()->tab_strip_model()->GetActiveWebContents(),
87 base::Bind(&content::FrameIsChildOfMainFrame));
88 }
[email protected]a964e112011-04-14 21:52:5189};
90
nickfa2254b2015-08-07 23:27:2991IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, IsInstalled) {
92 host_resolver()->AddRule("*", "127.0.0.1");
93 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
94 GURL app_url =
95 embedded_test_server()->GetURL("app.com", "/extensions/test_file.html");
96 GURL non_app_url = embedded_test_server()->GetURL(
97 "nonapp.com", "/extensions/test_file.html");
[email protected]a964e112011-04-14 21:52:5198
[email protected]80675fc2011-06-21 02:05:4999 // Before the app is installed, app.com does not think that it is installed
100 ui_test_utils::NavigateToURL(browser(), app_url);
[email protected]b27c3622014-03-22 00:26:55101 EXPECT_FALSE(IsAppInstalledInMainFrame());
[email protected]a964e112011-04-14 21:52:51102
103 // Load an app which includes app.com in its extent.
104 const Extension* extension = LoadExtension(
105 test_data_dir_.AppendASCII("app_dot_com_app"));
106 ASSERT_TRUE(extension);
107
[email protected]80675fc2011-06-21 02:05:49108 // Even after the app is installed, the existing app.com tab is not in an
109 // app process, so chrome.app.isInstalled should return false.
[email protected]b27c3622014-03-22 00:26:55110 EXPECT_FALSE(IsAppInstalledInMainFrame());
[email protected]a964e112011-04-14 21:52:51111
112 // Test that a non-app page has chrome.app.isInstalled = false.
113 ui_test_utils::NavigateToURL(browser(), non_app_url);
[email protected]b27c3622014-03-22 00:26:55114 EXPECT_FALSE(IsAppInstalledInMainFrame());
[email protected]a964e112011-04-14 21:52:51115
116 // Test that a non-app page returns null for chrome.app.getDetails().
[email protected]06bc5d92013-01-02 22:44:13117 const char kGetAppDetails[] =
118 "window.domAutomationController.send("
119 " JSON.stringify(window.chrome.app.getDetails()));";
[email protected]80675fc2011-06-21 02:05:49120 std::string result;
[email protected]a964e112011-04-14 21:52:51121 ASSERT_TRUE(
[email protected]b6987e02013-01-04 18:30:43122 content::ExecuteScriptAndExtractString(
[email protected]47ae23372013-01-29 01:50:48123 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13124 kGetAppDetails,
125 &result));
[email protected]a964e112011-04-14 21:52:51126 EXPECT_EQ("null", result);
127
128 // Check that an app page has chrome.app.isInstalled = true.
129 ui_test_utils::NavigateToURL(browser(), app_url);
[email protected]b27c3622014-03-22 00:26:55130 EXPECT_TRUE(IsAppInstalledInMainFrame());
[email protected]a964e112011-04-14 21:52:51131
132 // Check that an app page returns the correct result for
133 // chrome.app.getDetails().
134 ui_test_utils::NavigateToURL(browser(), app_url);
135 ASSERT_TRUE(
[email protected]b6987e02013-01-04 18:30:43136 content::ExecuteScriptAndExtractString(
[email protected]47ae23372013-01-29 01:50:48137 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13138 kGetAppDetails,
139 &result));
[email protected]023b3d12013-12-23 18:46:49140 scoped_ptr<base::DictionaryValue> app_details(
estadeb09312b2015-05-22 16:30:13141 static_cast<base::DictionaryValue*>(
142 base::JSONReader::DeprecatedRead(result)));
[email protected]953620b2011-12-04 00:55:32143 // extension->manifest() does not contain the id.
[email protected]a964e112011-04-14 21:52:51144 app_details->Remove("id", NULL);
145 EXPECT_TRUE(app_details.get());
[email protected]953620b2011-12-04 00:55:32146 EXPECT_TRUE(app_details->Equals(extension->manifest()->value()));
[email protected]a964e112011-04-14 21:52:51147
[email protected]9b3a5c22011-05-31 08:03:13148 // Try to change app.isInstalled. Should silently fail, so
149 // that isInstalled should have the initial value.
150 ASSERT_TRUE(
[email protected]b6987e02013-01-04 18:30:43151 content::ExecuteScriptAndExtractString(
[email protected]47ae23372013-01-29 01:50:48152 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]06bc5d92013-01-02 22:44:13153 "window.domAutomationController.send("
154 " function() {"
155 " var value = window.chrome.app.isInstalled;"
156 " window.chrome.app.isInstalled = !value;"
157 " if (window.chrome.app.isInstalled == value) {"
158 " return 'true';"
159 " } else {"
160 " return 'false';"
161 " }"
162 " }()"
163 ");",
164 &result));
[email protected]9b3a5c22011-05-31 08:03:13165
166 // Should not be able to alter window.chrome.app.isInstalled from javascript";
167 EXPECT_EQ("true", result);
[email protected]a964e112011-04-14 21:52:51168}
169
[email protected]f2fe87c2012-04-24 17:53:49170IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, InstallAndRunningState) {
nickfa2254b2015-08-07 23:27:29171 host_resolver()->AddRule("*", "127.0.0.1");
172 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
173 GURL app_url = embedded_test_server()->GetURL(
174 "app.com", "/extensions/get_app_details_for_frame.html");
175 GURL non_app_url = embedded_test_server()->GetURL(
176 "nonapp.com", "/extensions/get_app_details_for_frame.html");
[email protected]f2fe87c2012-04-24 17:53:49177
178 // Before the app is installed, app.com does not think that it is installed
179 ui_test_utils::NavigateToURL(browser(), app_url);
180
[email protected]b27c3622014-03-22 00:26:55181 EXPECT_EQ("not_installed", InstallStateInMainFrame());
182 EXPECT_EQ("cannot_run", RunningStateInMainFrame());
183 EXPECT_FALSE(IsAppInstalledInMainFrame());
[email protected]f2fe87c2012-04-24 17:53:49184
185 const Extension* extension = LoadExtension(
186 test_data_dir_.AppendASCII("app_dot_com_app"));
187 ASSERT_TRUE(extension);
188
[email protected]b27c3622014-03-22 00:26:55189 EXPECT_EQ("installed", InstallStateInMainFrame());
190 EXPECT_EQ("ready_to_run", RunningStateInMainFrame());
191 EXPECT_FALSE(IsAppInstalledInMainFrame());
[email protected]f2fe87c2012-04-24 17:53:49192
193 // Reloading the page should put the tab in an app process.
194 ui_test_utils::NavigateToURL(browser(), app_url);
[email protected]b27c3622014-03-22 00:26:55195 EXPECT_EQ("installed", InstallStateInMainFrame());
196 EXPECT_EQ("running", RunningStateInMainFrame());
197 EXPECT_TRUE(IsAppInstalledInMainFrame());
[email protected]f2fe87c2012-04-24 17:53:49198
199 // Disable the extension and verify the state.
[email protected]03d25812014-06-22 19:41:55200 ExtensionService* service = extensions::ExtensionSystem::Get(
201 browser()->profile())->extension_service();
202 service->DisableExtension(extension->id(),
203 Extension::DISABLE_PERMISSIONS_INCREASE);
[email protected]f2fe87c2012-04-24 17:53:49204 ui_test_utils::NavigateToURL(browser(), app_url);
205
[email protected]b27c3622014-03-22 00:26:55206 EXPECT_EQ("disabled", InstallStateInMainFrame());
207 EXPECT_EQ("cannot_run", RunningStateInMainFrame());
208 EXPECT_FALSE(IsAppInstalledInMainFrame());
[email protected]f2fe87c2012-04-24 17:53:49209
[email protected]03d25812014-06-22 19:41:55210 service->EnableExtension(extension->id());
[email protected]b27c3622014-03-22 00:26:55211 EXPECT_EQ("installed", InstallStateInMainFrame());
212 EXPECT_EQ("ready_to_run", RunningStateInMainFrame());
213 EXPECT_FALSE(IsAppInstalledInMainFrame());
[email protected]f2fe87c2012-04-24 17:53:49214
215 // The non-app URL should still not be installed or running.
216 ui_test_utils::NavigateToURL(browser(), non_app_url);
217
[email protected]b27c3622014-03-22 00:26:55218 EXPECT_EQ("not_installed", InstallStateInMainFrame());
219 EXPECT_EQ("cannot_run", RunningStateInMainFrame());
220 EXPECT_FALSE(IsAppInstalledInMainFrame());
[email protected]f2fe87c2012-04-24 17:53:49221
[email protected]b27c3622014-03-22 00:26:55222 EXPECT_EQ("installed", InstallStateInIFrame());
223 EXPECT_EQ("cannot_run", RunningStateInIFrame());
224 EXPECT_FALSE(IsAppInstalledInIFrame());
[email protected]f2fe87c2012-04-24 17:53:49225}
226
227IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, InstallAndRunningStateFrame) {
nickfa2254b2015-08-07 23:27:29228 host_resolver()->AddRule("*", "127.0.0.1");
229 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
230 GURL app_url = embedded_test_server()->GetURL(
231 "app.com", "/extensions/get_app_details_for_frame_reversed.html");
[email protected]f2fe87c2012-04-24 17:53:49232
233 // Check the install and running state of a non-app iframe running
234 // within an app.
235 ui_test_utils::NavigateToURL(browser(), app_url);
236
[email protected]b27c3622014-03-22 00:26:55237 EXPECT_EQ("not_installed", InstallStateInIFrame());
238 EXPECT_EQ("cannot_run", RunningStateInIFrame());
239 EXPECT_FALSE(IsAppInstalledInIFrame());
[email protected]f2fe87c2012-04-24 17:53:49240}