15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <string>
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/ref_counted.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/path_service.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/stringprintf.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/api/debugger/debugger_api.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/extension_function_test_utils.h"
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/sessions/session_tab_helper.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/tabs/tab_strip_model.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/chrome_paths.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/test/base/ui_test_utils.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/extension_function.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/extension.h"
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/extension_builder.h"
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/manifest_constants.h"
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/switches.h"
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/value_builder.h"
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace extensions {
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass DebuggerApiTest : public ExtensionApiTest {
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch protected:
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~DebuggerApiTest() {}
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE;
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void SetUpOnMainThread() OVERRIDE;
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Run the attach function. If |expected_error| is not empty, then the
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // function should fail with the error. Otherwise, the function is expected
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // to succeed.
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  testing::AssertionResult RunAttachFunction(const GURL& url,
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                             const std::string& expected_error);
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const Extension* extension() const { return extension_.get(); }
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::CommandLine* command_line() const { return command_line_; }
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The command-line for the test process, preserved in order to modify
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // mid-test.
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::CommandLine* command_line_;
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // A basic extension with the debugger permission.
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<const Extension> extension_;
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid DebuggerApiTest::SetUpCommandLine(base::CommandLine* command_line) {
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ExtensionApiTest::SetUpCommandLine(command_line);
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // We need to hold onto |command_line| in order to modify it during the test.
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  command_line_ = command_line;
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid DebuggerApiTest::SetUpOnMainThread() {
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ExtensionApiTest::SetUpOnMainThread();
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  extension_ =
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ExtensionBuilder().SetManifest(
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          DictionaryBuilder().Set("name", "debugger")
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             .Set("version", "0.1")
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             .Set("manifest_version", 2)
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             .Set("permissions",
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  ListBuilder().Append("debugger"))).Build();
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtesting::AssertionResult DebuggerApiTest::RunAttachFunction(
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GURL& url, const std::string& expected_error) {
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ui_test_utils::NavigateToURL(browser(), url);
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::WebContents* web_contents =
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      browser()->tab_strip_model()->GetActiveWebContents();
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  int tab_id = SessionTabHelper::IdForTab(web_contents);
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<DebuggerAttachFunction> attach_function =
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new DebuggerAttachFunction();
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  attach_function->set_extension(extension_.get());
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string args = base::StringPrintf("[{\"tabId\": %d}, \"1.1\"]", tab_id);
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!expected_error.empty()) {
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string actual_error =
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        extension_function_test_utils::RunFunctionAndReturnError(
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            attach_function.get(), args, browser());
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (actual_error != expected_error) {
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return testing::AssertionFailure() << "Did not get correct error: "
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          << "expected: " << expected_error << ", found: " << actual_error;
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!RunFunction(attach_function.get(),
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     args,
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     browser(),
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     extension_function_test_utils::NONE)) {
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return testing::AssertionFailure() << "Could not run function: "
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          << attach_function->GetError();
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Clean up and detach.
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<DebuggerDetachFunction> detach_function =
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        new DebuggerDetachFunction();
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    detach_function->set_extension(extension_.get());
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!RunFunction(detach_function.get(),
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     base::StringPrintf("[{\"tabId\": %d}]", tab_id),
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     browser(),
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     extension_function_test_utils::NONE)) {
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return testing::AssertionFailure() << "Could not detach: "
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          << detach_function->GetError();
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return testing::AssertionSuccess();
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Debugger) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("debugger")) << message_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
117116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(DebuggerApiTest,
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       DebuggerNotAllowedOnOtherExtensionPages) {
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Load another arbitrary extension with an associated resource (popup.html).
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::FilePath path;
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  path = path.AppendASCII("extensions").AppendASCII("good_unpacked");
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const Extension* another_extension = LoadExtension(path);
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_TRUE(another_extension);
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GURL other_ext_url =
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      GURL(base::StringPrintf("chrome-extension://%s/popup.html",
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              another_extension->id().c_str()));
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This extension should not be able to access another extension.
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(RunAttachFunction(
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      other_ext_url, manifest_errors::kCannotAccessExtensionUrl));
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This extension *should* be able to debug itself.
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(RunAttachFunction(
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                  GURL(base::StringPrintf("chrome-extension://%s/foo.html",
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                          extension()->id().c_str())),
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                  std::string()));
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Append extensions on chrome urls switch. The extension should now be able
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // to debug any extension.
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  command_line()->AppendSwitch(switches::kExtensionsOnChromeURLs);
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(RunAttachFunction(other_ext_url, std::string()));
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace extensions
147