| /* |
| Copyright (C) 2012 Samsung Electronics |
| Copyright (C) 2012 Intel Corporation. All rights reserved. |
| |
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| This library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public License |
| along with this library; if not, write to the Free Software Foundation, |
| Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include "config.h" |
| #include "EWK2UnitTestBase.h" |
| |
| #include "EWK2UnitTestEnvironment.h" |
| #include <Ecore.h> |
| #include <glib-object.h> |
| |
| extern EWK2UnitTest::EWK2UnitTestEnvironment* environment; |
| |
| namespace EWK2UnitTest { |
| |
| static Ewk_View_Smart_Class ewk2UnitTestBrowserViewSmartClass() |
| { |
| static Ewk_View_Smart_Class ewkViewClass = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("Browser_View"); |
| return ewkViewClass; |
| } |
| |
| EWK2UnitTestBase::EWK2UnitTestBase() |
| : m_ecoreEvas(0) |
| , m_webView(0) |
| , m_ewkViewClass(ewk2UnitTestBrowserViewSmartClass()) |
| , m_multipleProcesses(false) |
| , m_withExtension(false) |
| { |
| ewk_view_smart_class_set(&m_ewkViewClass); |
| } |
| |
| void EWK2UnitTestBase::SetUp() |
| { |
| unsigned width = environment->defaultWidth(); |
| unsigned height = environment->defaultHeight(); |
| |
| #if defined(HAVE_ECORE_X) |
| const char* engine = "opengl_x11"; |
| m_ecoreEvas = ecore_evas_new(engine, 0, 0, width, height, 0); |
| // Graceful fallback to software rendering if evas_gl engine is not available. |
| if (!m_ecoreEvas) |
| #endif |
| m_ecoreEvas = ecore_evas_new(0, 0, 0, width, height, 0); |
| |
| ecore_evas_show(m_ecoreEvas); |
| Evas* evas = ecore_evas_get(m_ecoreEvas); |
| |
| Evas_Smart* smart = evas_smart_class_new(&m_ewkViewClass.sc); |
| |
| Ewk_Context* newContext; |
| if (m_withExtension) |
| newContext = ewk_context_new_with_extensions_path(TEST_LIB_DIR); |
| else |
| newContext = ewk_context_new(); |
| |
| if (m_multipleProcesses) |
| ewk_context_web_process_count_limit_set(newContext, 0); |
| |
| Ewk_Page_Group* newPageGroup = ewk_page_group_create("UnitTest"); |
| m_webView = ewk_view_smart_add(evas, smart, newContext, newPageGroup); |
| |
| // Clear HTTP cache files before running the unit tests, which prevents |
| // performance degradation due to so many cache files. |
| ewk_context_resource_cache_clear(newContext); |
| ewk_object_unref(newContext); |
| ewk_object_unref(newPageGroup); |
| |
| ewk_view_theme_set(m_webView, environment->defaultTheme()); |
| |
| evas_object_resize(m_webView, width, height); |
| evas_object_show(m_webView); |
| evas_object_focus_set(m_webView, true); |
| } |
| |
| void EWK2UnitTestBase::TearDown() |
| { |
| evas_object_del(m_webView); |
| ecore_evas_free(m_ecoreEvas); |
| } |
| |
| bool EWK2UnitTestBase::loadUrlSync(const char* url, double timeoutSeconds) |
| { |
| ewk_view_url_set(m_webView, url); |
| return waitUntilLoadFinished(timeoutSeconds); |
| } |
| |
| class CallbackDataTimer { |
| public: |
| explicit CallbackDataTimer(double timeoutSeconds) |
| : m_done(false) |
| , m_timer(timeoutSeconds >= 0 ? ecore_timer_add(timeoutSeconds, timeOutCallback, this) : nullptr) |
| , m_didTimeOut(false) |
| { |
| } |
| |
| virtual ~CallbackDataTimer() |
| { |
| if (m_timer) |
| ecore_timer_del(m_timer); |
| } |
| |
| bool isDone() const { return m_done; } |
| |
| void setDone() |
| { |
| if (m_timer) { |
| ecore_timer_del(m_timer); |
| m_timer = nullptr; |
| } |
| m_done = true; |
| } |
| |
| bool didTimeOut() const { return m_didTimeOut; } |
| |
| protected: |
| bool m_done; |
| Ecore_Timer* m_timer; |
| bool m_didTimeOut; |
| |
| private: |
| static Eina_Bool timeOutCallback(void* userData) |
| { |
| CallbackDataTimer* data = static_cast<CallbackDataTimer*>(userData); |
| data->setTimedOut(); |
| return ECORE_CALLBACK_CANCEL; |
| } |
| |
| void setTimedOut() |
| { |
| m_done = true; |
| m_timer = nullptr; |
| m_didTimeOut = true; |
| } |
| |
| }; |
| |
| template <class T> |
| class CallbackDataExpectedValue : public CallbackDataTimer { |
| public: |
| CallbackDataExpectedValue(const T& expectedValue, double timeoutSeconds) |
| : CallbackDataTimer(timeoutSeconds) |
| , m_expectedValue(expectedValue) |
| { |
| } |
| |
| const T& expectedValue() const { return m_expectedValue; } |
| |
| private: |
| T m_expectedValue; |
| }; |
| |
| static void onLoadFinished(void* userData, Evas_Object* webView, void* eventInfo) |
| { |
| UNUSED_PARAM(webView); |
| UNUSED_PARAM(eventInfo); |
| |
| CallbackDataTimer* data = static_cast<CallbackDataTimer*>(userData); |
| data->setDone(); |
| } |
| |
| bool EWK2UnitTestBase::waitUntilLoadFinished(double timeoutSeconds) |
| { |
| CallbackDataTimer data(timeoutSeconds); |
| |
| evas_object_smart_callback_add(m_webView, "load,finished", onLoadFinished, &data); |
| |
| while (!data.isDone()) |
| ecore_main_loop_iterate(); |
| |
| evas_object_smart_callback_del(m_webView, "load,finished", onLoadFinished); |
| |
| return !data.didTimeOut(); |
| } |
| |
| static void onTitleChanged(void* userData, Evas_Object* webView, void*) |
| { |
| CallbackDataExpectedValue<CString>* data = static_cast<CallbackDataExpectedValue<CString>*>(userData); |
| |
| if (strcmp(ewk_view_title_get(webView), data->expectedValue().data())) |
| return; |
| |
| data->setDone(); |
| } |
| |
| bool EWK2UnitTestBase::waitUntilTitleChangedTo(const char* expectedTitle, double timeoutSeconds) |
| { |
| return waitUntilTitleChangedTo(m_webView, expectedTitle, timeoutSeconds); |
| } |
| |
| bool EWK2UnitTestBase::waitUntilTitleChangedTo(Evas_Object* webView, const char* expectedTitle, double timeoutSeconds) |
| { |
| CallbackDataExpectedValue<CString> data(expectedTitle, timeoutSeconds); |
| |
| evas_object_smart_callback_add(webView, "title,changed", onTitleChanged, &data); |
| |
| while (!data.isDone()) |
| ecore_main_loop_iterate(); |
| |
| evas_object_smart_callback_del(webView, "title,changed", onTitleChanged); |
| |
| return !data.didTimeOut(); |
| } |
| |
| static void onURLChanged(void* userData, Evas_Object* webView, void*) |
| { |
| CallbackDataExpectedValue<CString>* data = static_cast<CallbackDataExpectedValue<CString>*>(userData); |
| |
| if (strcmp(ewk_view_url_get(webView), data->expectedValue().data())) |
| return; |
| |
| data->setDone(); |
| } |
| |
| bool EWK2UnitTestBase::waitUntilURLChangedTo(const char* expectedURL, double timeoutSeconds) |
| { |
| CallbackDataExpectedValue<CString> data(expectedURL, timeoutSeconds); |
| |
| evas_object_smart_callback_add(m_webView, "url,changed", onURLChanged, &data); |
| |
| while (!data.isDone()) |
| ecore_main_loop_iterate(); |
| |
| evas_object_smart_callback_del(m_webView, "url,changed", onURLChanged); |
| |
| return !data.didTimeOut(); |
| } |
| |
| bool EWK2UnitTestBase::waitUntilTrue(bool &flag, double timeoutSeconds) |
| { |
| CallbackDataExpectedValue<bool> data(true, timeoutSeconds); |
| |
| while (!data.isDone() && !flag) |
| ecore_main_loop_iterate(); |
| |
| return !data.didTimeOut(); |
| } |
| |
| bool EWK2UnitTestBase::waitUntilNotNull(Evas_Object** rawPointer, double timeoutSeconds) |
| { |
| CallbackDataExpectedValue<bool> data(true, timeoutSeconds); |
| |
| while (!data.isDone() && !*rawPointer) |
| ecore_main_loop_iterate(); |
| |
| return !data.didTimeOut(); |
| } |
| |
| bool EWK2UnitTestBase::waitUntilDirectionChanged(Ewk_Focus_Direction &direction, double timeoutSeconds) |
| { |
| CallbackDataTimer data(timeoutSeconds); |
| Ewk_Focus_Direction initialDirection = direction; |
| |
| while (!data.isDone() && direction == initialDirection) |
| ecore_main_loop_iterate(); |
| |
| return !data.didTimeOut(); |
| } |
| |
| Eina_List* EWK2UnitTestBase::waitUntilSpellingLanguagesLoaded(unsigned expectedLanguageCount, double timeoutValue) |
| { |
| // Keep waiting until all languages has been loaded or leave afqter timeout. |
| // Languages are being loaded in the timer, we have to wait for them. |
| Eina_List* loadedLanguages = nullptr; |
| void* actual = nullptr; |
| |
| CallbackDataExpectedValue<bool> data(true, timeoutValue); |
| while ((eina_list_count(loadedLanguages) != expectedLanguageCount) && !data.isDone()) { |
| if (loadedLanguages) { |
| // List has to be freed before acquiring new one. |
| actual = nullptr; |
| EINA_LIST_FREE(loadedLanguages, actual) |
| eina_stringshare_del(static_cast<const char*>(actual)); |
| } |
| |
| loadedLanguages = ewk_text_checker_spell_checking_languages_get(); |
| ecore_main_loop_iterate(); |
| } |
| |
| return loadedLanguages; |
| } |
| |
| void EWK2UnitTestBase::mouseClick(int x, int y, int button) |
| { |
| Evas* evas = evas_object_evas_get(m_webView); |
| evas_event_feed_mouse_move(evas, x, y, 0, 0); |
| evas_event_feed_mouse_down(evas, button, EVAS_BUTTON_NONE, 0, 0); |
| evas_event_feed_mouse_up(evas, button, EVAS_BUTTON_NONE, 0, 0); |
| } |
| |
| void EWK2UnitTestBase::mouseDoubleClick(int x, int y, int button) |
| { |
| Evas* evas = evas_object_evas_get(m_webView); |
| evas_event_feed_mouse_move(evas, x, y, 0, 0); |
| evas_event_feed_mouse_down(evas, button, EVAS_BUTTON_DOUBLE_CLICK, 0, 0); |
| evas_event_feed_mouse_up(evas, button, EVAS_BUTTON_NONE, 0, 0); |
| } |
| |
| void EWK2UnitTestBase::mouseDown(int x, int y, int button) |
| { |
| Evas* evas = evas_object_evas_get(m_webView); |
| evas_event_feed_mouse_move(evas, x, y, 0, 0); |
| evas_event_feed_mouse_down(evas, button, EVAS_BUTTON_NONE, 0, 0); |
| } |
| |
| void EWK2UnitTestBase::mouseUp(int x, int y, int button) |
| { |
| Evas* evas = evas_object_evas_get(m_webView); |
| evas_event_feed_mouse_move(evas, x, y, 0, 0); |
| evas_event_feed_mouse_up(evas, button, EVAS_BUTTON_NONE, 0, 0); |
| } |
| |
| void EWK2UnitTestBase::mouseMove(int x, int y) |
| { |
| evas_event_feed_mouse_move(evas_object_evas_get(m_webView), x, y, 0, 0); |
| } |
| |
| void EWK2UnitTestBase::multiDown(int id, int x, int y) |
| { |
| evas_event_feed_multi_down(evas_object_evas_get(m_webView), id, x, y, 0, 0, 0, 0, 0, 0, 0, EVAS_BUTTON_NONE, 0, 0); |
| } |
| |
| void EWK2UnitTestBase::multiUp(int id, int x, int y) |
| { |
| evas_event_feed_multi_up(evas_object_evas_get(m_webView), id, x, y, 0, 0, 0, 0, 0, 0, 0, EVAS_BUTTON_NONE, 0, 0); |
| } |
| |
| void EWK2UnitTestBase::multiMove(int id, int x, int y) |
| { |
| evas_event_feed_multi_move(evas_object_evas_get(m_webView), id, x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0); |
| } |
| |
| void EWK2UnitTestBase::keyDown(const char* keyname, const char* key, const char* string, const char* modifier) |
| { |
| Evas* evas = evas_object_evas_get(m_webView); |
| ASSERT(evas); |
| |
| if (modifier) { |
| evas_key_modifier_on(evas, modifier); |
| evas_event_feed_key_down(evas, keyname, key, string, 0, 0, 0); |
| evas_key_modifier_off(evas, modifier); |
| return; |
| } |
| |
| evas_event_feed_key_down(evas, keyname, key, string, 0, 0, 0); |
| } |
| |
| void EWK2UnitTestBase::keyUp(const char* keyname, const char* key, const char* string) |
| { |
| evas_event_feed_key_up(evas_object_evas_get(m_webView), keyname, key, string, 0, 0, 0); |
| } |
| |
| } // namespace EWK2UnitTest |