1 // Copyright (c) 2011 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 #pragma once 8 9 #include <deque> 10 #include <string> 11 12 #include "base/values.h" 13 #include "chrome/browser/extensions/extension_browsertest.h" 14 #include "content/common/notification_registrar.h" 15 16 class Extension; 17 18 // The general flow of these API tests should work like this: 19 // (1) Setup initial browser state (e.g. create some bookmarks for the 20 // bookmark test) 21 // (2) Call ASSERT_TRUE(RunExtensionTest(name)); 22 // (3) In your extension code, run your test and call chrome.test.pass or 23 // chrome.test.fail 24 // (4) Verify expected browser state. 25 // TODO(erikkay): There should also be a way to drive events in these tests. 26 27 class ExtensionApiTest : public ExtensionBrowserTest { 28 public: 29 ExtensionApiTest(); 30 virtual ~ExtensionApiTest(); 31 32 protected: 33 // Helper class that observes tests failing or passing. Observation starts 34 // when the class is constructed. Get the next result by calling 35 // GetNextResult() and message() if GetNextResult() return false. If there 36 // are no results, this method will pump the UI message loop until one is 37 // received. 38 class ResultCatcher : public NotificationObserver { 39 public: 40 ResultCatcher(); 41 ~ResultCatcher(); 42 43 // Pumps the UI loop until a notification is received that an API test 44 // succeeded or failed. Returns true if the test succeeded, false otherwise. 45 bool GetNextResult(); 46 47 void RestrictToProfile(Profile* profile) { profile_restriction_ = profile; } 48 49 const std::string& message() { return message_; } 50 51 private: 52 virtual void Observe(NotificationType type, 53 const NotificationSource& source, 54 const NotificationDetails& details); 55 56 NotificationRegistrar registrar_; 57 58 // A sequential list of pass/fail notifications from the test extension(s). 59 std::deque<bool> results_; 60 61 // If it failed, what was the error message? 62 std::deque<std::string> messages_; 63 std::string message_; 64 65 // If non-NULL, we will listen to events from this profile only. 66 Profile* profile_restriction_; 67 68 // True if we're in a nested message loop waiting for results from 69 // the extension. 70 bool waiting_; 71 }; 72 73 virtual void SetUpInProcessBrowserTestFixture(); 74 virtual void TearDownInProcessBrowserTestFixture(); 75 76 // Load |extension_name| and wait for pass / fail notification. 77 // |extension_name| is a directory in "test/data/extensions/api_test". 78 bool RunExtensionTest(const char* extension_name); 79 80 // Same as RunExtensionTest, but enables the extension for incognito mode. 81 bool RunExtensionTestIncognito(const char* extension_name); 82 83 // Same as RunExtensionTest, but loads extension as component. 84 bool RunComponentExtensionTest(const char* extension_name); 85 86 // Same as RunExtensionTest, but disables file access. 87 bool RunExtensionTestNoFileAccess(const char* extension_name); 88 89 // Same as RunExtensionTestIncognito, but disables file access. 90 bool RunExtensionTestIncognitoNoFileAccess(const char* extension_name); 91 92 // If not empty, Load |extension_name|, load |page_url| and wait for pass / 93 // fail notification from the extension API on the page. Note that if 94 // |page_url| is not a valid url, it will be treated as a resource within 95 // the extension. |extension_name| is a directory in 96 // "test/data/extensions/api_test". 97 bool RunExtensionSubtest(const char* extension_name, 98 const std::string& page_url); 99 100 // Load |page_url| and wait for pass / fail notification from the extension 101 // API on the page. 102 bool RunPageTest(const std::string& page_url); 103 104 // Start the test server, and store details of its state. Those details 105 // will be available to javascript tests using chrome.test.getConfig(). 106 bool StartTestServer(); 107 108 // Test that exactly one extension loaded. If so, return a pointer to 109 // the extension. If not, return NULL and set message_. 110 const Extension* GetSingleLoadedExtension(); 111 112 // All extensions tested by ExtensionApiTest are in the "api_test" dir. 113 virtual void SetUpCommandLine(CommandLine* command_line); 114 115 // If it failed, what was the error message? 116 std::string message_; 117 118 private: 119 bool RunExtensionTestImpl(const char* extension_name, 120 const std::string& test_page, 121 bool enable_incogntio, 122 bool enable_fileaccess, 123 bool load_as_component); 124 125 // Hold details of the test, set in C++, which can be accessed by 126 // javascript using chrome.test.getConfig(). 127 scoped_ptr<DictionaryValue> test_config_; 128 }; 129 130 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_APITEST_H_ 131