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_TEST_MESSAGE_LISTENER_H_ 6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_TEST_MESSAGE_LISTENER_H_ 7 #pragma once 8 9 #include <string> 10 11 #include "content/common/notification_observer.h" 12 #include "content/common/notification_registrar.h" 13 14 class ExtensionTestSendMessageFunction; 15 16 // This class helps us wait for incoming messages sent from javascript via 17 // chrome.test.sendMessage(). A sample usage would be: 18 // 19 // ExtensionTestMessageListener listener("foo"); 20 // ... do some work 21 // ASSERT_TRUE(listener.WaitUntilSatisfied()); 22 // 23 // It is also possible to have the extension wait for our reply. This is 24 // useful for coordinating multiple pages/processes and having them wait on 25 // each other. Example: 26 // 27 // ExtensionTestMessageListener listener1("foo1"); 28 // ExtensionTestMessageListener listener2("foo2"); 29 // ASSERT_TRUE(listener1.WaitUntilSatisfied()); 30 // ASSERT_TRUE(listener2.WaitUntilSatisfied()); 31 // ... do some work 32 // listener1.Reply("foo2 is ready"); 33 // listener2.Reply("foo1 is ready"); 34 // 35 // TODO(asargent) - In the future we may want to add the ability to listen for 36 // multiple messages, and/or to wait for "any" message and then retrieve the 37 // contents of that message. We may also want to specify an extension id as 38 // satisfaction criteria in addition to message content. 39 // 40 // Note that when using it in browser tests, you need to make sure it gets 41 // destructed *before* the browser gets torn down. Two common patterns are to 42 // either make it a local variable inside your test body, or if it's a member 43 // variable of a ExtensionBrowserTest subclass, override the 44 // InProcessBrowserTest::CleanUpOnMainThread() method and clean it up there. 45 class ExtensionTestMessageListener : public NotificationObserver { 46 public: 47 // We immediately start listening for |expected_message|. 48 ExtensionTestMessageListener(const std::string& expected_message, 49 bool will_reply); 50 ~ExtensionTestMessageListener(); 51 52 // This returns true immediately if we've already gotten the expected 53 // message, or waits until it arrives. Returns false if the wait is 54 // interrupted and we still haven't gotten the message. 55 bool WaitUntilSatisfied(); 56 57 // Send the given message as a reply. It is only valid to call this after 58 // WaitUntilSatisfied has returned true, and if will_reply is true. 59 void Reply(const std::string& message); 60 61 // Implements the NotificationObserver interface. 62 virtual void Observe(NotificationType type, 63 const NotificationSource& source, 64 const NotificationDetails& details); 65 was_satisfied()66 bool was_satisfied() const { return satisfied_; } 67 68 private: 69 NotificationRegistrar registrar_; 70 71 // The message we're expecting. 72 std::string expected_message_; 73 74 // Whether we've seen expected_message_ yet. 75 bool satisfied_; 76 77 // If we're waiting, then we want to post a quit task when the expected 78 // message arrives. 79 bool waiting_; 80 81 // If true, we expect the calling code to manually send a reply. Otherwise, 82 // we send an automatic empty reply to the extension. 83 bool will_reply_; 84 85 // The function we need to reply to. 86 ExtensionTestSendMessageFunction* function_; 87 }; 88 89 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_TEST_MESSAGE_LISTENER_H_ 90