| // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef PPAPI_TESTS_TESTING_INSTANCE_H_ | 
 | #define PPAPI_TESTS_TESTING_INSTANCE_H_ | 
 |  | 
 | #include <stdint.h> | 
 |  | 
 | #include <string> | 
 |  | 
 | #include "ppapi/utility/completion_callback_factory.h" | 
 |  | 
 | #if defined(__native_client__) | 
 | #include "ppapi/cpp/instance.h" | 
 | #else | 
 | #include "ppapi/cpp/private/instance_private.h" | 
 | #endif | 
 |  | 
 | // Windows defines 'PostMessage', so we have to undef it. | 
 | #ifdef PostMessage | 
 | #undef PostMessage | 
 | #endif | 
 |  | 
 | class TestCase; | 
 |  | 
 | // How signaling works: | 
 | // | 
 | // We want to signal to the Chrome browser test harness | 
 | // (chrome/test/ppapi/ppapi_browsertest.cc) that we're making progress and when | 
 | // we're done. This is done using the DOM controlller. The browser test waits | 
 | // for a message from it. We don't want to have a big wait for all tests in a | 
 | // TestCase since they can take a while and it might timeout.  So we send it | 
 | // pings between each test to tell it that we're still running tests and aren't | 
 | // stuck. | 
 | // | 
 | // If the value of the message is "..." then that tells the test runner that | 
 | // the test is progressing. It then waits for the next message until it either | 
 | // times out or the value is something other than "...". In this case, the value | 
 | // will be either "PASS" or "FAIL [optional message]" corresponding to the | 
 | // outcome of the entire test case. Timeout will be treated just like a failure | 
 | // of the entire test case and the test will be terminated. | 
 | // | 
 | // In trusted builds, we use InstancePrivate and allow tests that use | 
 | // synchronous scripting. NaCl does not support synchronous scripting. | 
 | class TestingInstance : public | 
 | #if defined(__native_client__) | 
 | pp::Instance { | 
 | #else | 
 | pp::InstancePrivate { | 
 | #endif | 
 |  public: | 
 |   explicit TestingInstance(PP_Instance instance); | 
 |   virtual ~TestingInstance(); | 
 |  | 
 |   // pp::Instance override. | 
 |   virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); | 
 |   virtual void DidChangeView(const pp::View& view); | 
 |   virtual bool HandleInputEvent(const pp::InputEvent& event); | 
 |  | 
 | #if !(defined __native_client__) | 
 |   virtual pp::Var GetInstanceObject(); | 
 | #endif | 
 |  | 
 |   // Outputs the information from one test run, using the format | 
 |   //   <test_name> [PASS|FAIL <error_message>] | 
 |   // | 
 |   // You should generally use one of the RUN_TEST* macros in test_case.h | 
 |   // instead. | 
 |   // | 
 |   // If error_message is empty, we say the test passed and emit PASS. If | 
 |   // error_message is nonempty, the test failed with that message as the error | 
 |   // string. | 
 |   // | 
 |   // Intended usage: | 
 |   //   PP_TimeTicks start_time(core.GetTimeTicks()); | 
 |   //   LogTest("Foo", FooTest(), start_time); | 
 |   // | 
 |   // Where FooTest is defined as: | 
 |   //   std::string FooTest() { | 
 |   //     if (something_horrible_happened) | 
 |   //       return "Something horrible happened"; | 
 |   //     return ""; | 
 |   //   } | 
 |   // | 
 |   // NOTE: It's important to get the start time in the previous line, rather | 
 |   //       than calling GetTimeTicks in the LogTestLine. There's no guarantee | 
 |   //       that GetTimeTicks will be evaluated before FooTest(). | 
 |   void LogTest(const std::string& test_name, | 
 |                const std::string& error_message, | 
 |                PP_TimeTicks start_time); | 
 |   const std::string& current_test_name() { return current_test_name_; } | 
 |  | 
 |   // Appends an error message to the log. | 
 |   void AppendError(const std::string& message); | 
 |  | 
 |   // Passes the message_data through to the HandleMessage method on the | 
 |   // TestClass object that's associated with this instance. | 
 |   virtual void HandleMessage(const pp::Var& message_data); | 
 |  | 
 |   const std::string& protocol() { | 
 |     return protocol_; | 
 |   } | 
 |  | 
 |   int ssl_server_port() { return ssl_server_port_; } | 
 |  | 
 |   const std::string& websocket_host() { return websocket_host_; } | 
 |   int websocket_port() { return websocket_port_; } | 
 |  | 
 |   // Posts a message to the test page to eval() the script. | 
 |   void EvalScript(const std::string& script); | 
 |  | 
 |   // Sets the given cookie in the current document. | 
 |   void SetCookie(const std::string& name, const std::string& value); | 
 |  | 
 |   void ReportProgress(const std::string& progress_value); | 
 |  | 
 |   // Logs the amount of time that a given test took to run. This is to help | 
 |   // debug test timeouts that occur in automated testing. | 
 |   void LogTestTime(const std::string& test_time); | 
 |  | 
 |   // Add a post-condition to the JavaScript on the test_case.html page. This | 
 |   // JavaScript code will be run after the instance is shut down and must | 
 |   // evaluate to |true| or the test will fail. | 
 |   void AddPostCondition(const std::string& script); | 
 |  | 
 |   // See doc for |remove_plugin_|. | 
 |   void set_remove_plugin(bool remove) { remove_plugin_ = remove; } | 
 |  | 
 |  private: | 
 |   void ExecuteTests(int32_t unused); | 
 |  | 
 |   // Creates a new TestCase for the give test name, or NULL if there is no such | 
 |   // test. Ownership is passed to the caller. The given string is split by '_'. | 
 |   // The test case name is the first part. | 
 |   TestCase* CaseForTestName(const std::string& name); | 
 |  | 
 |   // Sends a test command to the page using PostMessage. | 
 |   void SendTestCommand(const std::string& command); | 
 |   void SendTestCommand(const std::string& command, const std::string& params); | 
 |  | 
 |   // Appends a list of available tests to the console in the document. | 
 |   void LogAvailableTests(); | 
 |  | 
 |   // Appends the given error test to the console in the document. | 
 |   void LogError(const std::string& text); | 
 |  | 
 |   // Appends the given HTML string to the console in the document. | 
 |   void LogHTML(const std::string& html); | 
 |  | 
 |   pp::CompletionCallbackFactory<TestingInstance> callback_factory_; | 
 |  | 
 |   // Owning pointer to the current test case. Valid after Init has been called. | 
 |   TestCase* current_case_; | 
 |  | 
 |   std::string current_test_name_; | 
 |  | 
 |   // A filter to use when running tests. This is passed to 'RunTests', which | 
 |   // runs only tests whose name contains test_filter_ as a substring. | 
 |   std::string test_filter_; | 
 |  | 
 |   // Set once the tests are run so we know not to re-run when the view is sized. | 
 |   bool executed_tests_; | 
 |  | 
 |   // The number of tests executed so far. | 
 |   int32_t number_tests_executed_; | 
 |  | 
 |   // Collects all errors to send the the browser. Empty indicates no error yet. | 
 |   std::string errors_; | 
 |  | 
 |   // True if running in Native Client. | 
 |   bool nacl_mode_; | 
 |  | 
 |   // String representing the protocol.  Used for detecting whether we're running | 
 |   // with http. | 
 |   std::string protocol_; | 
 |  | 
 |   // SSL server port. | 
 |   int ssl_server_port_; | 
 |  | 
 |   // WebSocket host. | 
 |   std::string websocket_host_; | 
 |  | 
 |   // WebSocket port. | 
 |   int websocket_port_; | 
 |  | 
 |   // At the end of each set of tests, the plugin is removed from the web-page. | 
 |   // However, for some tests, it is desirable to not remove the plguin from the | 
 |   // page. | 
 |   bool remove_plugin_; | 
 | }; | 
 |  | 
 | #endif  // PPAPI_TESTS_TESTING_INSTANCE_H_ |