// 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 <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); // 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_; // 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_