• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RestrictToProfile(Profile * profile)47     void RestrictToProfile(Profile* profile) { profile_restriction_ = profile; }
48 
message()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