extension_apitest.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_APITEST_H_ 6#define CHROME_BROWSER_EXTENSIONS_EXTENSION_APITEST_H_ 7 8#include <deque> 9#include <string> 10 11#include "base/compiler_specific.h" 12#include "base/values.h" 13#include "chrome/browser/extensions/extension_browsertest.h" 14#include "content/public/browser/notification_registrar.h" 15 16class FilePath; 17 18namespace extensions { 19class Extension; 20} 21 22 23// The general flow of these API tests should work like this: 24// (1) Setup initial browser state (e.g. create some bookmarks for the 25// bookmark test) 26// (2) Call ASSERT_TRUE(RunExtensionTest(name)); 27// (3) In your extension code, run your test and call chrome.test.pass or 28// chrome.test.fail 29// (4) Verify expected browser state. 30// TODO(erikkay): There should also be a way to drive events in these tests. 31class ExtensionApiTest : public ExtensionBrowserTest { 32 public: 33 // Flags used to configure how the tests are run. 34 // TODO(aa): Many of these are dupes of ExtensionBrowserTest::Flags. Combine 35 // somehow? 36 enum Flags { 37 kFlagNone = 0, 38 39 // Allow the extension to run in incognito mode. 40 kFlagEnableIncognito = 1 << 0, 41 42 // Launch the test page in an incognito window. 43 kFlagUseIncognito = 1 << 1, 44 45 // Allow file access for the extension. 46 kFlagEnableFileAccess = 1 << 2, 47 48 // Loads the extension with location COMPONENT. 49 kFlagLoadAsComponent = 1 << 3, 50 51 // Launch the extension as a platform app. 52 kFlagLaunchPlatformApp = 1 << 4, 53 54 // Don't fail when the loaded manifest has warnings. 55 kFlagIgnoreManifestWarnings = 1 << 5, 56 57 // Allow manifest versions older that Extension::kModernManifestVersion. 58 // Used to test old manifest features. 59 kFlagAllowOldManifestVersions = 1 << 6, 60 }; 61 62 ExtensionApiTest(); 63 virtual ~ExtensionApiTest(); 64 65 protected: 66 // Helper class that observes tests failing or passing. Observation starts 67 // when the class is constructed. Get the next result by calling 68 // GetNextResult() and message() if GetNextResult() return false. If there 69 // are no results, this method will pump the UI message loop until one is 70 // received. 71 class ResultCatcher : public content::NotificationObserver { 72 public: 73 ResultCatcher(); 74 virtual ~ResultCatcher(); 75 76 // Pumps the UI loop until a notification is received that an API test 77 // succeeded or failed. Returns true if the test succeeded, false otherwise. 78 bool GetNextResult(); 79 80 void RestrictToProfile(Profile* profile) { profile_restriction_ = profile; } 81 82 const std::string& message() { return message_; } 83 84 private: 85 virtual void Observe(int type, 86 const content::NotificationSource& source, 87 const content::NotificationDetails& details) OVERRIDE; 88 89 content::NotificationRegistrar registrar_; 90 91 // A sequential list of pass/fail notifications from the test extension(s). 92 std::deque<bool> results_; 93 94 // If it failed, what was the error message? 95 std::deque<std::string> messages_; 96 std::string message_; 97 98 // If non-NULL, we will listen to events from this profile only. 99 Profile* profile_restriction_; 100 101 // True if we're in a nested message loop waiting for results from 102 // the extension. 103 bool waiting_; 104 }; 105 106 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE; 107 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE; 108 109 // Load |extension_name| and wait for pass / fail notification. 110 // |extension_name| is a directory in "test/data/extensions/api_test". 111 bool RunExtensionTest(const char* extension_name); 112 113 // Same as RunExtensionTest, but enables the extension for incognito mode. 114 bool RunExtensionTestIncognito(const char* extension_name); 115 116 // Same as RunExtensionTest, but ignores any warnings in the manifest. 117 bool RunExtensionTestIgnoreManifestWarnings(const char* extension_name); 118 119 // Same as RunExtensionTest, allow old manifest ersions. 120 bool RunExtensionTestAllowOldManifestVersion(const char* extension_name); 121 122 // Same as RunExtensionTest, but loads extension as component. 123 bool RunComponentExtensionTest(const char* extension_name); 124 125 // Same as RunExtensionTest, but disables file access. 126 bool RunExtensionTestNoFileAccess(const char* extension_name); 127 128 // Same as RunExtensionTestIncognito, but disables file access. 129 bool RunExtensionTestIncognitoNoFileAccess(const char* extension_name); 130 131 // If not empty, Load |extension_name|, load |page_url| and wait for pass / 132 // fail notification from the extension API on the page. Note that if 133 // |page_url| is not a valid url, it will be treated as a resource within 134 // the extension. |extension_name| is a directory in 135 // "test/data/extensions/api_test". 136 bool RunExtensionSubtest(const char* extension_name, 137 const std::string& page_url); 138 139 // Same as RunExtensionSubtest, except run with the specific |flags| 140 // (as defined in the Flags enum). 141 bool RunExtensionSubtest(const char* extension_name, 142 const std::string& page_url, 143 int flags); 144 145 // Load |page_url| and wait for pass / fail notification from the extension 146 // API on the page. 147 bool RunPageTest(const std::string& page_url); 148 bool RunPageTest(const std::string& page_url, int flags); 149 150 // Similar to RunExtensionTest, except used for running tests in platform app 151 // shell windows. 152 bool RunPlatformAppTest(const char* extension_name); 153 154 // Start the test server, and store details of its state. Those details 155 // will be available to javascript tests using chrome.test.getConfig(). 156 bool StartTestServer(); 157 158 // Start the test WebSocket server, and store details of its state. Those 159 // details will be available to javascript tests using 160 // chrome.test.getConfig(). 161 bool StartWebSocketServer(const FilePath& root_directory); 162 163 // Test that exactly one extension loaded. If so, return a pointer to 164 // the extension. If not, return NULL and set message_. 165 const extensions::Extension* GetSingleLoadedExtension(); 166 167 // All extensions tested by ExtensionApiTest are in the "api_test" dir. 168 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE; 169 170 // If it failed, what was the error message? 171 std::string message_; 172 173 private: 174 bool RunExtensionTestImpl(const char* extension_name, 175 const std::string& test_page, 176 int flags); 177 178 // Hold details of the test, set in C++, which can be accessed by 179 // javascript using chrome.test.getConfig(). 180 scoped_ptr<DictionaryValue> test_config_; 181 182 // Hold the test WebSocket server. 183 scoped_ptr<net::TestServer> websocket_server_; 184}; 185 186#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_APITEST_H_ 187