active_script_controller_browsertest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/files/file_path.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/macros.h"
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/stringprintf.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/active_script_controller.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_action.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_browsertest.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_test_message_listener.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/location_bar_controller.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/test_extension_dir.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/public/test/browser_test_utils.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/common/feature_switch.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/common/switches.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace extensions {
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kAllHostsScheme[] = "*://*/*";
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kExplicitHostsScheme[] = "http://127.0.0.1/*";
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kBackgroundScript[] =
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "\"background\": {\"scripts\": [\"script.js\"]}";
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kBackgroundScriptSource[] =
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "var listener = function(tabId) {\n"
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "  chrome.tabs.onUpdated.removeListener(listener);\n"
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "  chrome.tabs.executeScript(tabId, {\n"
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "    code: \"chrome.test.sendMessage('inject succeeded');\"\n"
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "  });"
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "};\n"
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "chrome.tabs.onUpdated.addListener(listener);";
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kContentScriptSource[] =
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "chrome.test.sendMessage('inject succeeded');";
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kInjectSucceeded[] = "inject succeeded";
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)enum InjectionType {
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CONTENT_SCRIPT,
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXECUTE_SCRIPT
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)enum HostType {
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ALL_HOSTS,
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPLICIT_HOSTS
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)enum RequiresConsent {
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  REQUIRES_CONSENT,
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DOES_NOT_REQUIRE_CONSENT
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Runs all pending tasks in the renderer associated with |web_contents|.
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Returns true on success.
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool RunAllPendingInRenderer(content::WebContents* web_contents) {
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This is slight hack to achieve a RunPendingInRenderer() method. Since IPCs
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // are sent synchronously, anything started prior to this method will finish
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // before this method returns (as content::ExecuteScript() is synchronous).
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return content::ExecuteScript(web_contents, "1 == 1;");
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class ActiveScriptControllerBrowserTest : public ExtensionBrowserTest {
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ActiveScriptControllerBrowserTest() {}
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE;
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void CleanUpOnMainThread() OVERRIDE;
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns an extension with the given |host_type| and |injection_type|. If
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // one already exists, the existing extension will be returned. Othewrwise,
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // one will be created.
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This could potentially return NULL if LoadExtension() fails.
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const Extension* CreateExtension(HostType host_type,
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                   InjectionType injection_type);
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ScopedVector<TestExtensionDir> test_extension_dirs_;
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<const Extension*> extensions_;
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ActiveScriptControllerBrowserTest::SetUpCommandLine(
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::CommandLine* command_line) {
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionBrowserTest::SetUpCommandLine(command_line);
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We append the actual switch to the commandline because it needs to be
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // passed over to the renderer, which a FeatureSwitch::ScopedOverride will
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // not do.
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  command_line->AppendSwitch(switches::kEnableScriptsRequireAction);
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ActiveScriptControllerBrowserTest::CleanUpOnMainThread() {
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  test_extension_dirs_.clear();
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const Extension* ActiveScriptControllerBrowserTest::CreateExtension(
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    HostType host_type, InjectionType injection_type) {
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string name =
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::StringPrintf(
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          "%s %s",
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          injection_type == CONTENT_SCRIPT ?
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)              "content_script" : "execute_script",
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          host_type == ALL_HOSTS ? "all_hosts" : "explicit_hosts");
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char* permission_scheme =
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      host_type == ALL_HOSTS ? kAllHostsScheme : kExplicitHostsScheme;
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string permissions = base::StringPrintf(
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "\"permissions\": [\"tabs\", \"%s\"]", permission_scheme);
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string scripts;
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string script_source;
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (injection_type == CONTENT_SCRIPT) {
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scripts = base::StringPrintf(
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "\"content_scripts\": ["
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        " {"
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "  \"matches\": [\"%s\"],"
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "  \"js\": [\"script.js\"],"
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "  \"run_at\": \"document_start\""
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        " }"
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "]",
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        permission_scheme);
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scripts = kBackgroundScript;
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string manifest = base::StringPrintf(
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "{"
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      " \"name\": \"%s\","
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      " \"version\": \"1.0\","
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      " \"manifest_version\": 2,"
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      " %s,"
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      " %s"
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "}",
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      name.c_str(),
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      permissions.c_str(),
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scripts.c_str());
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<TestExtensionDir> dir(new TestExtensionDir);
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  dir->WriteManifest(manifest);
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  dir->WriteFile(FILE_PATH_LITERAL("script.js"),
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 injection_type == CONTENT_SCRIPT ? kContentScriptSource :
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                    kBackgroundScriptSource);
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Extension* extension = LoadExtension(dir->unpacked_path());
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (extension) {
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    test_extension_dirs_.push_back(dir.release());
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    extensions_.push_back(extension);
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If extension is NULL here, it will be caught later in the test.
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return extension;
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class ActiveScriptTester {
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ActiveScriptTester(const std::string& name,
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     const Extension* extension,
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     Browser* browser,
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     RequiresConsent requires_consent,
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     InjectionType type);
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ~ActiveScriptTester();
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  testing::AssertionResult Verify();
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns the location bar controller, or NULL if one does not exist.
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LocationBarController* GetLocationBarController();
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns the active script controller, or NULL if one does not exist.
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ActiveScriptController* GetActiveScriptController();
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Get the ExtensionAction for this extension, or NULL if one does not exist.
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionAction* GetAction();
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The name of the extension, and also the message it sends.
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string name_;
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The extension associated with this tester.
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const Extension* extension_;
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The browser the tester is running in.
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Browser* browser_;
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Whether or not the extension has permission to run the script without
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // asking the user.
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RequiresConsent requires_consent_;
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The type of injection this tester uses.
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InjectionType type_;
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // All of these extensions should inject a script (either through content
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // scripts or through chrome.tabs.executeScript()) that sends a message with
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the |kInjectSucceeded| message.
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  linked_ptr<ExtensionTestMessageListener> inject_success_listener_;
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ActiveScriptTester::ActiveScriptTester(const std::string& name,
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       const Extension* extension,
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       Browser* browser,
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       RequiresConsent requires_consent,
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                       InjectionType type)
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : name_(name),
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      extension_(extension),
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      browser_(browser),
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      requires_consent_(requires_consent),
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      type_(type),
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      inject_success_listener_(
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          new ExtensionTestMessageListener(kInjectSucceeded,
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           false /* won't reply */)) {
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  inject_success_listener_->set_extension_id(extension->id());
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ActiveScriptTester::~ActiveScriptTester() {
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)testing::AssertionResult ActiveScriptTester::Verify() {
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!extension_)
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return testing::AssertionFailure() << "Could not load extension: " << name_;
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::WebContents* web_contents =
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      browser_ ? browser_->tab_strip_model()->GetActiveWebContents() : NULL;
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!web_contents)
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return testing::AssertionFailure() << "No web contents.";
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Give the extension plenty of time to inject.
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!RunAllPendingInRenderer(web_contents))
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return testing::AssertionFailure() << "Could not run pending in renderer.";
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Make sure all running tasks are complete.
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::RunAllPendingInMessageLoop();
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LocationBarController* location_bar_controller = GetLocationBarController();
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!location_bar_controller) {
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return testing::AssertionFailure()
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << "Could not find location bar controller";
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ActiveScriptController* controller =
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      location_bar_controller->active_script_controller();
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!controller)
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return testing::AssertionFailure() << "Could not find controller.";
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionAction* action = GetAction();
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool has_action = action != NULL;
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // An extension should have an action displayed iff it requires user consent.
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if ((requires_consent_ == REQUIRES_CONSENT && !has_action) ||
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      (requires_consent_ == DOES_NOT_REQUIRE_CONSENT && has_action)) {
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return testing::AssertionFailure()
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << "Improper action status for " << name_ << ": expected "
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << (requires_consent_ == REQUIRES_CONSENT) << ", found " << has_action;
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the extension has permission, we should be able to simply wait for it
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // to execute.
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (requires_consent_ == DOES_NOT_REQUIRE_CONSENT) {
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    inject_success_listener_->WaitUntilSatisfied();
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return testing::AssertionSuccess();
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Otherwise, we don't have permission, and have to grant it. Ensure the
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // script has *not* already executed.
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (inject_success_listener_->was_satisfied()) {
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return testing::AssertionFailure() <<
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        name_ << "'s script ran without permission.";
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If we reach this point, we should always have an action.
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(action);
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Grant permission by clicking on the extension action.
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  location_bar_controller->OnClicked(action);
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Now, the extension should be able to inject the script.
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  inject_success_listener_->WaitUntilSatisfied();
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The Action should have disappeared.
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  has_action = GetAction() != NULL;
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (has_action) {
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return testing::AssertionFailure()
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        << "Extension " << name_ << " has lingering action.";
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return testing::AssertionSuccess();
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)LocationBarController* ActiveScriptTester::GetLocationBarController() {
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::WebContents* web_contents =
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      browser_ ? browser_->tab_strip_model()->GetActiveWebContents() : NULL;
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!web_contents)
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TabHelper* tab_helper = TabHelper::FromWebContents(web_contents);
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return tab_helper ? tab_helper->location_bar_controller() : NULL;
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ActiveScriptController* ActiveScriptTester::GetActiveScriptController() {
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  LocationBarController* location_bar_controller = GetLocationBarController();
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return location_bar_controller ?
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      location_bar_controller->active_script_controller() : NULL;
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ExtensionAction* ActiveScriptTester::GetAction() {
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ActiveScriptController* controller = GetActiveScriptController();
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return controller ? controller->GetActionForExtension(extension_) : NULL;
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ActiveScriptControllerBrowserTest,
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       ActiveScriptsAreDisplayedAndDelayExecution) {
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::FilePath active_script_path =
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      test_data_dir_.AppendASCII("active_script");
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char* kExtensionNames[] = {
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "inject_scripts_all_hosts",
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "inject_scripts_explicit_hosts",
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "content_scripts_all_hosts",
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "content_scripts_explicit_hosts"
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // First, we load up three extensions:
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // - An extension that injects scripts into all hosts,
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // - An extension that injects scripts into explicit hosts,
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // - An extension with a content script that runs on all hosts,
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // - An extension with a content script that runs on explicit hosts.
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // The extensions that operate on explicit hosts have permission; the ones
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // that request all hosts require user consent.
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ActiveScriptTester testers[] = {
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ActiveScriptTester(
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          kExtensionNames[0],
33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          CreateExtension(ALL_HOSTS, EXECUTE_SCRIPT),
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          browser(),
341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          REQUIRES_CONSENT,
342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          EXECUTE_SCRIPT),
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ActiveScriptTester(
344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          kExtensionNames[1],
34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          CreateExtension(EXPLICIT_HOSTS, EXECUTE_SCRIPT),
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          browser(),
347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          DOES_NOT_REQUIRE_CONSENT,
348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          EXECUTE_SCRIPT),
349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ActiveScriptTester(
350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          kExtensionNames[2],
35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          CreateExtension(ALL_HOSTS, CONTENT_SCRIPT),
352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          browser(),
353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          REQUIRES_CONSENT,
354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          CONTENT_SCRIPT),
355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ActiveScriptTester(
356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          kExtensionNames[3],
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          CreateExtension(EXPLICIT_HOSTS, CONTENT_SCRIPT),
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          browser(),
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          DOES_NOT_REQUIRE_CONSENT,
360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          CONTENT_SCRIPT),
361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Navigate to an URL (which matches the explicit host specified in the
364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // extension content_scripts_explicit_hosts). All four extensions should
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // inject the script.
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ui_test_utils::NavigateToURL(
368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0u; i < arraysize(testers); ++i)
371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(testers[i].Verify()) << kExtensionNames[i];
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Test that removing an extension with pending injections a) removes the
37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// pending injections for that extension, and b) does not affect pending
37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// injections for other extensions.
37746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ActiveScriptControllerBrowserTest,
37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                       RemoveExtensionWithPendingInjections) {
37946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Load up two extensions, each with content scripts.
38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const Extension* extension1 = CreateExtension(ALL_HOSTS, CONTENT_SCRIPT);
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(extension1);
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  const Extension* extension2 = CreateExtension(ALL_HOSTS, CONTENT_SCRIPT);
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(extension2);
38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_NE(extension1->id(), extension2->id());
38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  content::WebContents* web_contents =
38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      browser()->tab_strip_model()->GetActiveWebContents();
38946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(web_contents);
39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ActiveScriptController* active_script_controller =
39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      ActiveScriptController::GetForWebContents(web_contents);
39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(active_script_controller);
39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ui_test_utils::NavigateToURL(
39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Both extensions should have pending requests.
39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(active_script_controller->GetActionForExtension(extension1));
40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(active_script_controller->GetActionForExtension(extension2));
40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
40246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Unload one of the extensions.
40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  UnloadExtension(extension2->id());
40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(RunAllPendingInRenderer(web_contents));
40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // We should have pending requests for extension1, but not the removed
40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // extension2.
40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(active_script_controller->GetActionForExtension(extension1));
41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(active_script_controller->GetActionForExtension(extension2));
41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // We should still be able to run the request for extension1.
41346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ExtensionTestMessageListener inject_success_listener(
41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new ExtensionTestMessageListener(kInjectSucceeded,
41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                       false /* won't reply */));
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  inject_success_listener.set_extension_id(extension1->id());
41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  active_script_controller->OnClicked(extension1);
41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  inject_success_listener.WaitUntilSatisfied();
41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
42046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// A version of the test with the flag off, in order to test that everything
422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// still works as expected.
423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class FlagOffActiveScriptControllerBrowserTest
424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : public ActiveScriptControllerBrowserTest {
425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Simply don't append the flag.
427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ExtensionBrowserTest::SetUpCommandLine(command_line);
429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(FlagOffActiveScriptControllerBrowserTest,
433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       ScriptsExecuteWhenFlagAbsent) {
434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char* kExtensionNames[] = {
435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "content_scripts_all_hosts",
436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "inject_scripts_all_hosts",
437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ActiveScriptTester testers[] = {
439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ActiveScriptTester(
440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          kExtensionNames[0],
44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          CreateExtension(ALL_HOSTS, CONTENT_SCRIPT),
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          browser(),
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          DOES_NOT_REQUIRE_CONSENT,
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          CONTENT_SCRIPT),
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ActiveScriptTester(
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          kExtensionNames[1],
44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          CreateExtension(ALL_HOSTS, EXECUTE_SCRIPT),
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          browser(),
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          DOES_NOT_REQUIRE_CONSENT,
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          EXECUTE_SCRIPT),
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ui_test_utils::NavigateToURL(
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0u; i < arraysize(testers); ++i)
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(testers[i].Verify()) << kExtensionNames[i];
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace extensions
462