DumpRenderTreeView.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Copyright (C) 2011 ProFUSION Embedded Systems
  3. * Copyright (C) 2011 Samsung Electronics
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Red istributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
  15. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  18. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  21. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #define __STDC_FORMAT_MACROS
  26. #include "config.h"
  27. #include "DumpRenderTreeView.h"
  28. #include "DumpRenderTree.h"
  29. #include "DumpRenderTreeChrome.h"
  30. #include "DumpRenderTreeEfl.h"
  31. #include "TestRunner.h"
  32. #include <EWebKit.h>
  33. #include <Ecore.h>
  34. #include <Eina.h>
  35. #include <Evas.h>
  36. #include <cstdio>
  37. #include <cstdlib>
  38. #include <inttypes.h>
  39. #include <wtf/NotFound.h>
  40. #include <wtf/text/CString.h>
  41. #include <wtf/text/WTFString.h>
  42. using namespace std;
  43. static Ewk_View_Smart_Class gParentSmartClass = EWK_VIEW_SMART_CLASS_INIT_NULL;
  44. static WTF::String urlSuitableForTestResult(const WTF::String& uriString)
  45. {
  46. if (uriString.isEmpty() || !uriString.startsWith("file://"))
  47. return uriString;
  48. const size_t index = uriString.reverseFind('/');
  49. return (index == WTF::notFound) ? uriString : uriString.substring(index + 1);
  50. }
  51. static void onConsoleMessage(Ewk_View_Smart_Data* smartData, const char* message, unsigned lineNumber, const char*)
  52. {
  53. Evas_Object* evasObject = smartData->self;
  54. if (evas_object_data_get(evasObject, "ignore-console-messages"))
  55. return;
  56. // Tests expect only the filename part of local URIs
  57. WTF::String newMessage = WTF::String::fromUTF8(message);
  58. if (!newMessage.isEmpty()) {
  59. const size_t fileProtocol = newMessage.find("file://");
  60. if (fileProtocol != WTF::notFound)
  61. newMessage = newMessage.left(fileProtocol) + urlSuitableForTestResult(newMessage.substring(fileProtocol));
  62. }
  63. // Ignore simple translation-related messages and unnecessary messages
  64. if (newMessage.contains("Localized string") || newMessage.contains("Protocol Error: the message is for non-existing domain 'Profiler'"))
  65. return;
  66. printf("CONSOLE MESSAGE: ");
  67. if (lineNumber)
  68. printf("line %u: ", lineNumber);
  69. printf("%s\n", newMessage.utf8().data());
  70. }
  71. static void onJavaScriptAlert(Ewk_View_Smart_Data*, Evas_Object*, const char* message)
  72. {
  73. printf("ALERT: %s\n", message);
  74. fflush(stdout);
  75. }
  76. static Eina_Bool onJavaScriptConfirm(Ewk_View_Smart_Data*, Evas_Object*, const char* message)
  77. {
  78. printf("CONFIRM: %s\n", message);
  79. return EINA_TRUE;
  80. }
  81. static Eina_Bool onBeforeUnloadConfirm(Ewk_View_Smart_Data*, Evas_Object*, const char* message)
  82. {
  83. printf("CONFIRM NAVIGATION: %s\n", message);
  84. return !gTestRunner->shouldStayOnPageAfterHandlingBeforeUnload();
  85. }
  86. static Eina_Bool onJavaScriptPrompt(Ewk_View_Smart_Data*, Evas_Object*, const char* message, const char* defaultValue, const char** value)
  87. {
  88. printf("PROMPT: %s, default text: %s\n", message, defaultValue);
  89. *value = eina_stringshare_add(defaultValue);
  90. return EINA_TRUE;
  91. }
  92. static Evas_Object* onWindowCreate(Ewk_View_Smart_Data*, Eina_Bool, const Ewk_Window_Features*)
  93. {
  94. return gTestRunner->canOpenWindows() ? browser->createNewWindow() : 0;
  95. }
  96. static Eina_Bool onWindowCloseDelayed(void* data)
  97. {
  98. Evas_Object* view = static_cast<Evas_Object*>(data);
  99. browser->removeWindow(view);
  100. return EINA_FALSE;
  101. }
  102. static void onWindowClose(Ewk_View_Smart_Data* smartData)
  103. {
  104. Evas_Object* view = smartData->self;
  105. ecore_idler_add(onWindowCloseDelayed, view);
  106. }
  107. static uint64_t onExceededDatabaseQuota(Ewk_View_Smart_Data* smartData, Evas_Object* frame, const char* databaseName, uint64_t currentSize, uint64_t expectedSize)
  108. {
  109. if (!gTestRunner->dumpDatabaseCallbacks())
  110. return 0;
  111. Ewk_Security_Origin* origin = ewk_frame_security_origin_get(frame);
  112. printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n",
  113. ewk_security_origin_protocol_get(origin),
  114. ewk_security_origin_host_get(origin),
  115. ewk_security_origin_port_get(origin),
  116. databaseName);
  117. ewk_security_origin_free(origin);
  118. return 5 * 1024 * 1024;
  119. }
  120. static int64_t onExceededApplicationCacheQuota(Ewk_View_Smart_Data*, Ewk_Security_Origin *origin, int64_t defaultOriginQuota, int64_t totalSpaceNeeded)
  121. {
  122. if (gTestRunner->dumpApplicationCacheDelegateCallbacks()) {
  123. // For example, numbers from 30000 - 39999 will output as 30000.
  124. // Rounding up or down does not really matter for these tests. It's
  125. // sufficient to just get a range of 10000 to determine if we were
  126. // above or below a threshold.
  127. int64_t truncatedSpaceNeeded = (totalSpaceNeeded / 10000) * 10000;
  128. printf("UI DELEGATE APPLICATION CACHE CALLBACK: exceededApplicationCacheOriginQuotaForSecurityOrigin:{%s, %s, %i} totalSpaceNeeded:~%" PRId64 "\n",
  129. ewk_security_origin_protocol_get(origin),
  130. ewk_security_origin_host_get(origin),
  131. ewk_security_origin_port_get(origin),
  132. truncatedSpaceNeeded);
  133. }
  134. if (gTestRunner->disallowIncreaseForApplicationCacheQuota())
  135. return 0;
  136. return defaultOriginQuota;
  137. }
  138. static bool shouldUseTiledBackingStore()
  139. {
  140. const char* useTiledBackingStore = getenv("DRT_USE_TILED_BACKING_STORE");
  141. return useTiledBackingStore && *useTiledBackingStore == '1';
  142. }
  143. static bool chooseAndInitializeAppropriateSmartClass(Ewk_View_Smart_Class* api)
  144. {
  145. return !shouldUseTiledBackingStore() ? ewk_view_single_smart_set(api) : ewk_view_tiled_smart_set(api);
  146. }
  147. // Taken from the file "WebKit/Tools/DumpRenderTree/chromium/WebViewHost.cpp".
  148. static inline const char* navigationTypeToString(const Ewk_Navigation_Type type)
  149. {
  150. switch (type) {
  151. case EWK_NAVIGATION_TYPE_LINK_CLICKED:
  152. return "link clicked";
  153. case EWK_NAVIGATION_TYPE_FORM_SUBMITTED:
  154. return "form submitted";
  155. case EWK_NAVIGATION_TYPE_BACK_FORWARD:
  156. return "back/forward";
  157. case EWK_NAVIGATION_TYPE_RELOAD:
  158. return "reload";
  159. case EWK_NAVIGATION_TYPE_FORM_RESUBMITTED:
  160. return "form resubmitted";
  161. case EWK_NAVIGATION_TYPE_OTHER:
  162. return "other";
  163. }
  164. return "illegal value";
  165. }
  166. static Eina_Bool onNavigationPolicyDecision(Ewk_View_Smart_Data*, Ewk_Frame_Resource_Request* request, Ewk_Navigation_Type navigationType)
  167. {
  168. if (!policyDelegateEnabled)
  169. return true;
  170. printf("Policy delegate: attempt to load %s with navigation type '%s'\n", urlSuitableForTestResult(request->url).utf8().data(),
  171. navigationTypeToString(navigationType));
  172. if (gTestRunner)
  173. gTestRunner->notifyDone();
  174. return policyDelegatePermissive;
  175. }
  176. static Eina_Bool onFocusCanCycle(Ewk_View_Smart_Data*, Ewk_Focus_Direction)
  177. {
  178. // This is the behavior of Mac and Chromium ports and is expected by some test cases.
  179. return true;
  180. }
  181. Evas_Object* drtViewAdd(Evas* evas)
  182. {
  183. static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("DRT_View");
  184. if (!chooseAndInitializeAppropriateSmartClass(&api))
  185. return 0;
  186. if (EINA_UNLIKELY(!gParentSmartClass.sc.add))
  187. ewk_view_base_smart_set(&gParentSmartClass);
  188. api.add_console_message = onConsoleMessage;
  189. api.run_javascript_alert = onJavaScriptAlert;
  190. api.run_javascript_confirm = onJavaScriptConfirm;
  191. api.run_before_unload_confirm = onBeforeUnloadConfirm;
  192. api.run_javascript_prompt = onJavaScriptPrompt;
  193. api.window_create = onWindowCreate;
  194. api.window_close = onWindowClose;
  195. api.exceeded_application_cache_quota = onExceededApplicationCacheQuota;
  196. api.exceeded_database_quota = onExceededDatabaseQuota;
  197. api.navigation_policy_decision = onNavigationPolicyDecision;
  198. api.focus_can_cycle = onFocusCanCycle;
  199. return evas_object_smart_add(evas, evas_smart_class_new(&api.sc));
  200. }