extension_messages_apitest.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_path.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/path_service.h"
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/event_router.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_apitest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/dns/mock_host_resolver.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MessageSender : public content::NotificationObserver {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageSender() {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   content::NotificationService::AllSources());
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static scoped_ptr<ListValue> BuildEventArguments(const bool last_message,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   const std::string& data) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* event = new DictionaryValue();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->SetBoolean("lastMessage", last_message);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    event->SetString("data", data);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<ListValue> arguments(new ListValue());
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arguments->Append(event);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return arguments.Pass();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_ptr<extensions::Event> BuildEvent(
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<ListValue> event_args,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Profile* profile,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL event_url) {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<extensions::Event> event(new extensions::Event(
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "test.onMessage", event_args.Pass()));
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event->restrict_to_profile = profile;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event->event_url = event_url;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return event.Pass();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extensions::EventRouter* event_router =
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        extensions::ExtensionSystem::Get(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            content::Source<Profile>(source).ptr())->event_router();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sends four messages to the extension. All but the third message sent
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // from the origin http://b.com/ are supposed to arrive.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_router->BroadcastEvent(BuildEvent(
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BuildEventArguments(false, "no restriction"),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<Profile>(source).ptr(),
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GURL()));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_router->BroadcastEvent(BuildEvent(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BuildEventArguments(false, "http://a.com/"),
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<Profile>(source).ptr(),
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GURL("http://a.com/")));
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_router->BroadcastEvent(BuildEvent(
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BuildEventArguments(false, "http://b.com/"),
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<Profile>(source).ptr(),
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GURL("http://b.com/")));
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_router->BroadcastEvent(BuildEvent(
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BuildEventArguments(true, "last message"),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<Profile>(source).ptr(),
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GURL()));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that message passing between extensions and content scripts works.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, Messaging) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(StartTestServer());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("messaging/connect")) << message_;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that message passing from one extension to another works.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingExternal) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(LoadExtension(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_data_dir_.AppendASCII("..").AppendASCII("good")
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    .AppendASCII("Extensions")
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    .AppendASCII("1.0")));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("messaging/connect_external")) << message_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that messages with event_urls are only passed to extensions with
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// appropriate permissions.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MessagingEventURL) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageSender sender;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("messaging/event_url")) << message_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests connecting from a panel to its extension.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PanelMessagingTest : public ExtensionApiTest {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionApiTest::SetUpCommandLine(command_line);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line->AppendSwitch(switches::kEnablePanels);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(PanelMessagingTest, MessagingPanel) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(RunExtensionTest("messaging/connect_panel")) << message_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Tests externally_connectable between a web page and an extension.
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// TODO(kalman): Test between extensions. This is already tested in this file,
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// but not with externally_connectable set in the manifest.
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// TODO(kalman): Test with host permissions.
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ExternallyConnectableMessagingTest : public ExtensionApiTest {
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected:
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Result codes from the test. These must match up with |results| in
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // c/t/d/extensions/api_test/externally_connectable/sites/assertions.json.
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  enum Result {
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    OK = 0,
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    NAMESPACE_NOT_DEFINED = 1,
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    FUNCTION_NOT_DEFINED = 2,
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    COULD_NOT_ESTABLISH_CONNECTION_ERROR = 3,
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    OTHER_ERROR = 4,
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    INCORRECT_RESPONSE_SENDER = 5,
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    INCORRECT_RESPONSE_MESSAGE = 6,
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Result CanConnectAndSendMessages(const std::string& extension_id) {
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int result;
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CHECK(content::ExecuteScriptAndExtractInt(
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents(),
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "assertions.canConnectAndSendMessages('" + extension_id + "')",
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        &result));
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return static_cast<Result>(result);
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::AssertionResult AreAnyNonWebApisDefined() {
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // All runtime API methods are non-web except for sendRequest and connect.
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string non_messaging_apis[] = {
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "getBackgroundPage",
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "getManifest",
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "getURL",
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "reload",
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "requestUpdateCheck",
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "connectNative",
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "sendNativeMessage",
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onStartup",
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onInstalled",
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onSuspend",
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onSuspendCanceled",
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onUpdateAvailable",
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onBrowserUpdateAvailable",
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onConnect",
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onConnectExternal",
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onMessage",
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "onMessageExternal",
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "id",
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    };
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return AreAnyRuntimePropertiesDefined(std::vector<std::string>(
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        non_messaging_apis,
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        non_messaging_apis + arraysize(non_messaging_apis)));
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL GetURLForPath(const std::string& host, const std::string& path) {
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    std::string port = base::IntToString(embedded_test_server()->port());
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    GURL::Replacements replacements;
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    replacements.SetHostStr(host);
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    replacements.SetPortStr(port);
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return embedded_test_server()->GetURL(path).ReplaceComponents(replacements);
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  testing::AssertionResult AreAnyRuntimePropertiesDefined(
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      const std::vector<std::string>& names) {
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    for (size_t i = 0; i < names.size(); ++i) {
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (IsRuntimePropertyDefined(names[i]) == OK)
195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return testing::AssertionSuccess() << names[i] << " is defined";
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return testing::AssertionFailure()
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        << "none of " << names.size() << " properties are defined";
199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Result IsRuntimePropertyDefined(const std::string& name) {
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int result_int;
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    CHECK(content::ExecuteScriptAndExtractInt(
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents(),
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        "assertions.isDefined('" + name + "')",
206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        &result_int));
207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return static_cast<Result>(result_int);
208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Flaky on Windows. http://crbug.com/248413
212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN)
213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define MAYBE_ExternallyConnectableMessaging \
214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        DISABLED_ExternallyConnectableMessaging
215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#else
216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define MAYBE_ExternallyConnectableMessaging ExternallyConnectableMessaging
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest,
219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       MAYBE_ExternallyConnectableMessaging) {
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const char kExtensionDir[] = "messaging/externally_connectable";
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // The extension allows connections from chromium.org but not google.com.
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const char kChromiumOrg[] = "www.chromium.org";
224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const char kGoogleCom[] = "www.google.com";
225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::FilePath test_data;
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data));
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  embedded_test_server()->ServeFilesFromDirectory(
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      test_data.AppendASCII("extensions/api_test").AppendASCII(kExtensionDir));
230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host_resolver()->AddRule("*", embedded_test_server()->base_url().host());
233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL kChromiumOrgUrl =
235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetURLForPath(kChromiumOrg, "/sites/chromium.org.html");
236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const GURL kGoogleComUrl =
237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      GetURLForPath(kGoogleCom, "/sites/google.com.html");
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // When an extension isn't installed all attempts to connect to it should
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // fail.
241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const std::string kFakeId = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), kChromiumOrgUrl);
243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            CanConnectAndSendMessages(kFakeId));
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(AreAnyNonWebApisDefined());
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), kGoogleComUrl);
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            CanConnectAndSendMessages(kFakeId));
250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(AreAnyNonWebApisDefined());
251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Install the web connectable extension. chromium.org can connect to it,
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // google.com can't.
254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const extensions::Extension* web_connectable = LoadExtension(
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      test_data_dir_.AppendASCII(kExtensionDir).AppendASCII("web_connectable"));
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), kChromiumOrgUrl);
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(OK, CanConnectAndSendMessages(web_connectable->id()));
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(AreAnyNonWebApisDefined());
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), kGoogleComUrl);
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            CanConnectAndSendMessages(web_connectable->id()));
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(AreAnyNonWebApisDefined());
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Install the non-connectable extension. Nothing can connect to it.
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const extensions::Extension* not_connectable = LoadExtension(
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      test_data_dir_.AppendASCII(kExtensionDir).AppendASCII("not_connectable"));
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), kChromiumOrgUrl);
271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            CanConnectAndSendMessages(not_connectable->id()));
273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(AreAnyNonWebApisDefined());
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), kGoogleComUrl);
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR,
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            CanConnectAndSendMessages(not_connectable->id()));
278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(AreAnyNonWebApisDefined());
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
280