DumpRenderTreeChrome.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. /*
  2. * Copyright (C) 2011 ProFUSION Embedded Systems
  3. * Copyright (C) 2011 Samsung Electronics
  4. * Copyright (C) 2012 Intel Corporation
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND ITS CONTRIBUTORS
  16. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  18. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  19. * HOLDERS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "config.h"
  28. #include "DumpRenderTreeChrome.h"
  29. #include "DumpRenderTree.h"
  30. #include "DumpRenderTreeView.h"
  31. #include "EditingCallbacks.h"
  32. #include "EventSender.h"
  33. #include "GCController.h"
  34. #include "KURL.h"
  35. #include "NotImplemented.h"
  36. #include "TestRunner.h"
  37. #include "TextInputController.h"
  38. #include "WebCoreSupport/DumpRenderTreeSupportEfl.h"
  39. #include "WebCoreTestSupport.h"
  40. #include "WorkQueue.h"
  41. #include "ewk_private.h" // FIXME: create some WebCoreSupport/DumpRenderTree.cpp instead
  42. #include <EWebKit.h>
  43. #include <Ecore.h>
  44. #include <Eina.h>
  45. #include <Evas.h>
  46. #include <cstdio>
  47. #include <wtf/NotFound.h>
  48. #include <wtf/text/StringBuilder.h>
  49. #if HAVE(ACCESSIBILITY)
  50. #include "AccessibilityController.h"
  51. #endif
  52. using namespace WebCore;
  53. HashMap<unsigned long, CString> DumpRenderTreeChrome::m_dumpAssignedUrls;
  54. Evas_Object* DumpRenderTreeChrome::m_provisionalLoadFailedFrame = 0;
  55. PassOwnPtr<DumpRenderTreeChrome> DumpRenderTreeChrome::create(Evas* evas)
  56. {
  57. OwnPtr<DumpRenderTreeChrome> chrome = adoptPtr(new DumpRenderTreeChrome(evas));
  58. if (!chrome->initialize())
  59. return nullptr;
  60. return chrome.release();
  61. }
  62. DumpRenderTreeChrome::DumpRenderTreeChrome(Evas* evas)
  63. : m_mainView(0)
  64. , m_mainFrame(0)
  65. , m_evas(evas)
  66. , m_gcController(adoptPtr(new GCController))
  67. #if HAVE(ACCESSIBILITY)
  68. , m_axController(adoptPtr(new AccessibilityController))
  69. #endif
  70. {
  71. }
  72. DumpRenderTreeChrome::~DumpRenderTreeChrome()
  73. {
  74. }
  75. Evas_Object* DumpRenderTreeChrome::createNewWindow()
  76. {
  77. Evas_Object* newView = createView();
  78. ewk_view_setting_scripts_can_open_windows_set(newView, EINA_TRUE);
  79. ewk_view_setting_scripts_can_close_windows_set(newView, EINA_TRUE);
  80. m_extraViews.append(newView);
  81. return newView;
  82. }
  83. Evas_Object* DumpRenderTreeChrome::createView() const
  84. {
  85. Evas_Object* view = drtViewAdd(m_evas);
  86. if (!view)
  87. return 0;
  88. ewk_view_theme_set(view, TEST_THEME_DIR "/default.edj");
  89. evas_object_smart_callback_add(view, "download,request", onDownloadRequest, 0);
  90. evas_object_smart_callback_add(view, "load,resource,failed", onResourceLoadFailed, 0);
  91. evas_object_smart_callback_add(view, "load,resource,finished", onResourceLoadFinished, 0);
  92. evas_object_smart_callback_add(view, "load,started", onLoadStarted, 0);
  93. evas_object_smart_callback_add(view, "window,object,cleared", onWindowObjectCleared, m_gcController.get());
  94. evas_object_smart_callback_add(view, "statusbar,text,set", onStatusbarTextSet, 0);
  95. evas_object_smart_callback_add(view, "load,document,finished", onDocumentLoadFinished, 0);
  96. evas_object_smart_callback_add(view, "resource,request,new", onNewResourceRequest, 0);
  97. evas_object_smart_callback_add(view, "resource,request,willsend", onWillSendRequest, 0);
  98. evas_object_smart_callback_add(view, "resource,response,received", onResponseReceived, 0);
  99. evas_object_smart_callback_add(view, "onload,event", onWebViewOnloadEvent, 0);
  100. evas_object_smart_callback_add(view, "mixedcontent,run", onInsecureContentRun, 0);
  101. evas_object_smart_callback_add(view, "mixedcontent,displayed", onInsecureContentDisplayed, 0);
  102. evas_object_smart_callback_add(view, "frame,created", onFrameCreated, 0);
  103. evas_object_smart_callback_add(view, "navigate,with,data", onWebViewNavigatedWithData, 0);
  104. evas_object_smart_callback_add(view, "perform,server,redirect", onWebViewServerRedirect, 0);
  105. evas_object_smart_callback_add(view, "perform,client,redirect", onWebViewClientRedirect, 0);
  106. evas_object_smart_callback_add(view, "populate,visited,links", onWebViewPopulateVisitedLinks, 0);
  107. evas_object_smart_callback_add(view, "inspector,view,create", onInspectorViewCreate, 0);
  108. evas_object_smart_callback_add(view, "inspector,view,close", onInspectorViewClose, 0);
  109. connectEditingCallbacks(view);
  110. Evas_Object* mainFrame = ewk_view_frame_main_get(view);
  111. evas_object_smart_callback_add(mainFrame, "icon,changed", onFrameIconChanged, 0);
  112. evas_object_smart_callback_add(mainFrame, "load,provisional", onFrameProvisionalLoad, 0);
  113. evas_object_smart_callback_add(mainFrame, "load,provisional,failed", onFrameProvisionalLoadFailed, 0);
  114. evas_object_smart_callback_add(mainFrame, "load,committed", onFrameLoadCommitted, 0);
  115. evas_object_smart_callback_add(mainFrame, "load,finished", onFrameLoadFinished, 0);
  116. evas_object_smart_callback_add(mainFrame, "load,error", onFrameLoadError, 0);
  117. evas_object_smart_callback_add(mainFrame, "redirect,cancelled", onFrameRedirectCancelled, 0);
  118. evas_object_smart_callback_add(mainFrame, "redirect,load,provisional", onFrameRedirectForProvisionalLoad, 0);
  119. evas_object_smart_callback_add(mainFrame, "redirect,requested", onFrameRedirectRequested, 0);
  120. evas_object_smart_callback_add(mainFrame, "title,changed", onFrameTitleChanged, 0);
  121. evas_object_smart_callback_add(mainFrame, "xss,detected", onDidDetectXSS, 0);
  122. return view;
  123. }
  124. Evas_Object* DumpRenderTreeChrome::createInspectorView()
  125. {
  126. Evas_Object* inspectorView = drtViewAdd(m_evas);
  127. if (!inspectorView)
  128. return 0;
  129. // Inspector-related views are not expected to have their output logged.
  130. const bool ignoreMessages = true;
  131. evas_object_data_set(inspectorView, "ignore-console-messages", &ignoreMessages);
  132. ewk_view_theme_set(inspectorView, TEST_THEME_DIR "/default.edj");
  133. Evas_Object* mainFrame = ewk_view_frame_main_get(inspectorView);
  134. evas_object_smart_callback_add(mainFrame, "load,finished", onInspectorFrameLoadFinished, 0);
  135. evas_object_resize(inspectorView, TestRunner::viewWidth, TestRunner::viewHeight);
  136. evas_object_show(inspectorView);
  137. evas_object_focus_set(inspectorView, true);
  138. return inspectorView;
  139. }
  140. void DumpRenderTreeChrome::removeInspectorView()
  141. {
  142. Evas_Object* inspectorView = ewk_view_inspector_view_get(mainView());
  143. if (!inspectorView)
  144. return;
  145. Evas_Object* mainFrame = ewk_view_frame_main_get(inspectorView);
  146. evas_object_smart_callback_del(mainFrame, "load,finished", onInspectorFrameLoadFinished);
  147. evas_object_del(inspectorView);
  148. ewk_view_inspector_view_set(mainView(), 0);
  149. }
  150. void DumpRenderTreeChrome::waitInspectorLoadFinished()
  151. {
  152. // Waits until the page has finished loading.
  153. // Because it can't complete loading inspector.html before loading testURL.
  154. Evas_Object* inspectorView = ewk_view_inspector_view_get(mainView());
  155. if (inspectorView)
  156. ecore_main_loop_begin();
  157. }
  158. void DumpRenderTreeChrome::removeWindow(Evas_Object* view)
  159. {
  160. const size_t pos = m_extraViews.find(view);
  161. if (pos == notFound)
  162. return;
  163. m_extraViews.remove(pos);
  164. evas_object_del(view);
  165. }
  166. bool DumpRenderTreeChrome::initialize()
  167. {
  168. // Notifies that DRT is running for ewkView to create testable objects.
  169. DumpRenderTreeSupportEfl::setDumpRenderTreeModeEnabled(true);
  170. DumpRenderTreeSupportEfl::setMockScrollbarsEnabled(true);
  171. m_mainView = createView();
  172. if (!m_mainView)
  173. return false;
  174. ewk_view_theme_set(m_mainView, TEST_THEME_DIR "/default.edj");
  175. evas_object_name_set(m_mainView, "m_mainView");
  176. evas_object_move(m_mainView, 0, 0);
  177. evas_object_resize(m_mainView, TestRunner::viewWidth, TestRunner::viewHeight);
  178. evas_object_layer_set(m_mainView, EVAS_LAYER_MAX);
  179. evas_object_show(m_mainView);
  180. evas_object_focus_set(m_mainView, EINA_TRUE);
  181. m_mainFrame = ewk_view_frame_main_get(m_mainView);
  182. return true;
  183. }
  184. const Vector<Evas_Object*>& DumpRenderTreeChrome::extraViews() const
  185. {
  186. return m_extraViews;
  187. }
  188. void DumpRenderTreeChrome::clearExtraViews()
  189. {
  190. Vector<Evas_Object*>::iterator it = m_extraViews.begin();
  191. for (; it != m_extraViews.end(); ++it)
  192. evas_object_del(*it);
  193. m_extraViews.clear();
  194. }
  195. Evas_Object* DumpRenderTreeChrome::mainFrame() const
  196. {
  197. return m_mainFrame;
  198. }
  199. Evas_Object* DumpRenderTreeChrome::mainView() const
  200. {
  201. return m_mainView;
  202. }
  203. void DumpRenderTreeChrome::resetDefaultsToConsistentValues()
  204. {
  205. ewk_settings_icon_database_clear();
  206. ewk_settings_icon_database_path_set(0);
  207. ewk_web_database_remove_all();
  208. ewk_settings_web_database_default_quota_set(5 * 1024 * 1024);
  209. ewk_settings_memory_cache_clear();
  210. ewk_settings_application_cache_clear();
  211. ewk_settings_shadow_dom_enable_set(EINA_TRUE);
  212. ewk_view_setting_private_browsing_set(mainView(), EINA_FALSE);
  213. ewk_view_setting_spatial_navigation_set(mainView(), EINA_FALSE);
  214. ewk_view_setting_enable_frame_flattening_set(mainView(), EINA_FALSE);
  215. ewk_view_setting_application_cache_set(mainView(), EINA_TRUE);
  216. ewk_view_setting_enable_scripts_set(mainView(), EINA_TRUE);
  217. ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_STANDARD, "Times");
  218. ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_MONOSPACE, "Courier");
  219. ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_SERIF, "Times");
  220. ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_SANS_SERIF, "Helvetica");
  221. ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_CURSIVE, "cursive");
  222. ewk_view_font_family_name_set(mainView(), EWK_FONT_FAMILY_FANTASY, "fantasy");
  223. ewk_view_setting_font_default_size_set(mainView(), 16);
  224. ewk_view_setting_font_monospace_size_set(mainView(), 13);
  225. ewk_view_setting_font_minimum_size_set(mainView(), 0);
  226. ewk_view_setting_caret_browsing_set(mainView(), EINA_FALSE);
  227. ewk_view_setting_page_cache_set(mainView(), EINA_FALSE);
  228. ewk_view_setting_enable_auto_resize_window_set(mainView(), EINA_TRUE);
  229. ewk_view_setting_enable_plugins_set(mainView(), EINA_TRUE);
  230. ewk_view_setting_scripts_can_open_windows_set(mainView(), EINA_TRUE);
  231. ewk_view_setting_scripts_can_close_windows_set(mainView(), EINA_TRUE);
  232. ewk_view_setting_auto_load_images_set(mainView(), EINA_TRUE);
  233. ewk_view_setting_user_stylesheet_set(mainView(), 0);
  234. ewk_view_setting_enable_xss_auditor_set(browser->mainView(), EINA_TRUE);
  235. ewk_view_setting_enable_webgl_set(mainView(), EINA_TRUE);
  236. ewk_view_setting_enable_hyperlink_auditing_set(mainView(), EINA_FALSE);
  237. ewk_view_setting_include_links_in_focus_chain_set(mainView(), EINA_FALSE);
  238. ewk_view_setting_scripts_can_access_clipboard_set(mainView(), EINA_TRUE);
  239. ewk_view_setting_allow_universal_access_from_file_urls_set(mainView(), EINA_TRUE);
  240. ewk_view_setting_allow_file_access_from_file_urls_set(mainView(), EINA_TRUE);
  241. ewk_view_setting_resizable_textareas_set(mainView(), EINA_TRUE);
  242. ewk_view_zoom_set(mainView(), 1.0, 0, 0);
  243. ewk_view_scale_set(mainView(), 1.0, 0, 0);
  244. ewk_view_text_zoom_set(mainView(), 1.0);
  245. ewk_view_visibility_state_set(mainView(), EWK_PAGE_VISIBILITY_STATE_VISIBLE, true);
  246. ewk_view_text_direction_set(mainView(), EWK_TEXT_DIRECTION_DEFAULT);
  247. ewk_history_clear(ewk_view_history_get(mainView()));
  248. ewk_frame_feed_focus_in(mainFrame());
  249. ewk_cookies_clear();
  250. ewk_cookies_policy_set(EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY);
  251. ewk_security_policy_whitelist_origin_reset();
  252. #if HAVE(ACCESSIBILITY)
  253. browser->accessibilityController()->resetToConsistentState();
  254. #endif
  255. DumpRenderTreeSupportEfl::clearFrameName(mainFrame());
  256. DumpRenderTreeSupportEfl::clearOpener(mainFrame());
  257. DumpRenderTreeSupportEfl::clearUserScripts(mainView());
  258. DumpRenderTreeSupportEfl::clearUserStyleSheets(mainView());
  259. DumpRenderTreeSupportEfl::resetGeolocationClientMock(mainView());
  260. DumpRenderTreeSupportEfl::setInteractiveFormValidationEnabled(mainView(), true);
  261. DumpRenderTreeSupportEfl::setValidationMessageTimerMagnification(mainView(), -1);
  262. DumpRenderTreeSupportEfl::setAuthorAndUserStylesEnabled(mainView(), true);
  263. DumpRenderTreeSupportEfl::setCSSGridLayoutEnabled(mainView(), false);
  264. DumpRenderTreeSupportEfl::setDefersLoading(mainView(), false);
  265. DumpRenderTreeSupportEfl::setLoadsSiteIconsIgnoringImageLoadingSetting(mainView(), false);
  266. DumpRenderTreeSupportEfl::setSerializeHTTPLoads(false);
  267. DumpRenderTreeSupportEfl::setMinimumLogicalFontSize(mainView(), 9);
  268. DumpRenderTreeSupportEfl::setCSSRegionsEnabled(mainView(), true);
  269. DumpRenderTreeSupportEfl::setShouldTrackVisitedLinks(false);
  270. DumpRenderTreeSupportEfl::setTracksRepaints(mainFrame(), false);
  271. DumpRenderTreeSupportEfl::setSeamlessIFramesEnabled(true);
  272. DumpRenderTreeSupportEfl::setWebAudioEnabled(mainView(), false);
  273. // Reset capacities for the memory cache for dead objects.
  274. static const unsigned cacheTotalCapacity = 8192 * 1024;
  275. ewk_settings_object_cache_capacity_set(0, cacheTotalCapacity, cacheTotalCapacity);
  276. DumpRenderTreeSupportEfl::setDeadDecodedDataDeletionInterval(0);
  277. ewk_settings_page_cache_capacity_set(3);
  278. policyDelegateEnabled = false;
  279. policyDelegatePermissive = false;
  280. }
  281. static CString pathSuitableForTestResult(const char* uriString)
  282. {
  283. if (!uriString)
  284. return CString();
  285. KURL uri = KURL(ParsedURLString, uriString);
  286. if (!uri.isLocalFile())
  287. return uri.string().utf8();
  288. String pathString = uri.path();
  289. size_t indexBaseName = pathString.reverseFind('/');
  290. String baseName;
  291. if (indexBaseName == notFound)
  292. baseName = pathString;
  293. else
  294. baseName = pathString.substring(indexBaseName + 1);
  295. String dirName;
  296. if (indexBaseName != notFound) {
  297. size_t indexDirName = pathString.reverseFind('/', indexBaseName - 1);
  298. if (indexDirName != notFound)
  299. dirName = pathString.substring(indexDirName + 1, indexBaseName - indexDirName - 1);
  300. }
  301. String ret = dirName + "/" + baseName;
  302. return ret.utf8();
  303. }
  304. static CString urlSuitableForTestResult(const char* uriString)
  305. {
  306. KURL uri = KURL(ParsedURLString, uriString);
  307. if (!uri.isLocalFile())
  308. return CString(uriString);
  309. unsigned startIndex = uri.pathAfterLastSlash();
  310. return uri.string().substring(startIndex).utf8();
  311. }
  312. static CString descriptionSuitableForTestResult(Ewk_Frame_Resource_Request* request)
  313. {
  314. StringBuilder builder;
  315. builder.appendLiteral("<NSURLRequest URL ");
  316. builder.append(pathSuitableForTestResult(request->url).data());
  317. builder.appendLiteral(", main document URL ");
  318. builder.append(urlSuitableForTestResult(request->first_party).data());
  319. builder.appendLiteral(", http method ");
  320. if (request->http_method)
  321. builder.append(String(request->http_method));
  322. else
  323. builder.appendLiteral("(none)");
  324. builder.append('>');
  325. return builder.toString().utf8();
  326. }
  327. static CString descriptionSuitableForTestResult(const Ewk_Frame_Resource_Response* response)
  328. {
  329. if (!response)
  330. return CString("(null)");
  331. StringBuilder builder;
  332. builder.appendLiteral("<NSURLResponse ");
  333. builder.append(pathSuitableForTestResult(response->url).data());
  334. builder.appendLiteral(", http status code ");
  335. builder.append(String::number(response->status_code));
  336. builder.append('>');
  337. return builder.toString().utf8();
  338. }
  339. static CString descriptionSuitableForTestResult(Ewk_Frame_Load_Error* error)
  340. {
  341. const char* errorDomain = error->domain;
  342. int errorCode = error->code;
  343. // We need to do some error mapping here to match
  344. // the test expectations.
  345. if (!strcmp(error->domain, "WebKitNetworkError")) {
  346. errorDomain = "NSURLErrorDomain";
  347. errorCode = -999;
  348. }
  349. if (!strcmp(errorDomain, "WebKitPolicyError"))
  350. errorDomain = "WebKitErrorDomain";
  351. String ret = makeString("<NSError domain ", errorDomain, ", code ", String::number(errorCode));
  352. if (error->failing_url && *error->failing_url != '\0')
  353. ret = makeString(ret, ", failing URL \"", error->failing_url, "\"");
  354. ret = makeString(ret, ">");
  355. return ret.utf8();
  356. }
  357. // Smart Callbacks
  358. // ---------------
  359. void DumpRenderTreeChrome::onWindowObjectCleared(void* userData, Evas_Object*, void* eventInfo)
  360. {
  361. Ewk_Window_Object_Cleared_Event* objectClearedInfo = static_cast<Ewk_Window_Object_Cleared_Event*>(eventInfo);
  362. JSValueRef exception = 0;
  363. ASSERT(gTestRunner);
  364. #if HAVE(ACCESSIBILITY)
  365. browser->accessibilityController()->makeWindowObject(objectClearedInfo->context, objectClearedInfo->windowObject, &exception);
  366. ASSERT(!exception);
  367. #endif
  368. GCController* gcController = static_cast<GCController*>(userData);
  369. ASSERT(gcController);
  370. gTestRunner->makeWindowObject(objectClearedInfo->context, objectClearedInfo->windowObject, &exception);
  371. ASSERT(!exception);
  372. gcController->makeWindowObject(objectClearedInfo->context, objectClearedInfo->windowObject, &exception);
  373. ASSERT(!exception);
  374. JSRetainPtr<JSStringRef> controllerName(Adopt, JSStringCreateWithUTF8CString("eventSender"));
  375. JSObjectSetProperty(objectClearedInfo->context, objectClearedInfo->windowObject,
  376. controllerName.get(),
  377. makeEventSender(objectClearedInfo->context, !DumpRenderTreeSupportEfl::frameParent(objectClearedInfo->frame)),
  378. kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0);
  379. JSRetainPtr<JSStringRef> textInputControllerName(Adopt, JSStringCreateWithUTF8CString("textInputController"));
  380. JSObjectSetProperty(objectClearedInfo->context, objectClearedInfo->windowObject,
  381. textInputControllerName.get(),
  382. makeTextInputController(objectClearedInfo->context),
  383. kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0);
  384. WebCoreTestSupport::injectInternalsObject(objectClearedInfo->context);
  385. }
  386. void DumpRenderTreeChrome::onLoadStarted(void*, Evas_Object* view, void* eventInfo)
  387. {
  388. Evas_Object* frame = static_cast<Evas_Object*>(eventInfo);
  389. // Make sure we only set this once per test. If it gets cleared, and then set again, we might
  390. // end up doing two dumps for one test.
  391. if (!topLoadingFrame && !done)
  392. topLoadingFrame = frame;
  393. }
  394. Eina_Bool DumpRenderTreeChrome::processWork(void*)
  395. {
  396. if (WorkQueue::shared()->processWork() && !gTestRunner->waitToDump())
  397. dump();
  398. return ECORE_CALLBACK_CANCEL;
  399. }
  400. void DumpRenderTreeChrome::topLoadingFrameLoadFinished()
  401. {
  402. topLoadingFrame = 0;
  403. WorkQueue::shared()->setFrozen(true);
  404. if (gTestRunner->waitToDump())
  405. return;
  406. if (WorkQueue::shared()->count())
  407. ecore_idler_add(processWork, 0 /*frame*/);
  408. else
  409. dump();
  410. }
  411. void DumpRenderTreeChrome::onStatusbarTextSet(void*, Evas_Object*, void* eventInfo)
  412. {
  413. if (!gTestRunner->dumpStatusCallbacks())
  414. return;
  415. const char* statusbarText = static_cast<const char*>(eventInfo);
  416. printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", statusbarText);
  417. }
  418. void DumpRenderTreeChrome::onFrameIconChanged(void*, Evas_Object* frame, void*)
  419. {
  420. if (!done && gTestRunner->dumpIconChanges()) {
  421. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  422. printf("%s - didChangeIcons\n", frameName.utf8().data());
  423. }
  424. }
  425. void DumpRenderTreeChrome::onFrameTitleChanged(void*, Evas_Object* frame, void* eventInfo)
  426. {
  427. const Ewk_Text_With_Direction* titleText = static_cast<const Ewk_Text_With_Direction*>(eventInfo);
  428. if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
  429. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  430. printf("%s - didReceiveTitle: %s\n", frameName.utf8().data(), (titleText && titleText->string) ? titleText->string : "");
  431. }
  432. if (!done && gTestRunner->dumpTitleChanges())
  433. printf("TITLE CHANGED: '%s'\n", (titleText && titleText->string) ? titleText->string : "");
  434. if (!done && gTestRunner->dumpHistoryDelegateCallbacks())
  435. printf("WebView updated the title for history URL \"%s\" to \"%s\".\n", ewk_frame_uri_get(frame)
  436. , (titleText && titleText->string) ? titleText->string : "");
  437. gTestRunner->setTitleTextDirection(titleText->direction == EWK_TEXT_DIRECTION_LEFT_TO_RIGHT ? "ltr" : "rtl");
  438. }
  439. void DumpRenderTreeChrome::onDocumentLoadFinished(void*, Evas_Object*, void* eventInfo)
  440. {
  441. const Evas_Object* frame = static_cast<Evas_Object*>(eventInfo);
  442. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  443. if (!done && gTestRunner->dumpFrameLoadCallbacks())
  444. printf("%s - didFinishDocumentLoadForFrame\n", frameName.utf8().data());
  445. else if (!done) {
  446. const unsigned pendingFrameUnloadEvents = DumpRenderTreeSupportEfl::pendingUnloadEventCount(frame);
  447. if (pendingFrameUnloadEvents)
  448. printf("%s - has %u onunload handler(s)\n", frameName.utf8().data(), pendingFrameUnloadEvents);
  449. }
  450. }
  451. void DumpRenderTreeChrome::onWillSendRequest(void*, Evas_Object*, void* eventInfo)
  452. {
  453. Ewk_Frame_Resource_Messages* messages = static_cast<Ewk_Frame_Resource_Messages*>(eventInfo);
  454. if (!done && gTestRunner->dumpResourceLoadCallbacks())
  455. printf("%s - willSendRequest %s redirectResponse %s\n",
  456. m_dumpAssignedUrls.contains(messages->request->identifier) ? m_dumpAssignedUrls.get(messages->request->identifier).data() : "<unknown>",
  457. descriptionSuitableForTestResult(messages->request).data(),
  458. descriptionSuitableForTestResult(messages->redirect_response).data());
  459. if (!done && gTestRunner->willSendRequestReturnsNull()) {
  460. // As requested by the TestRunner, don't perform the request.
  461. messages->request->url = 0;
  462. return;
  463. }
  464. if (!done && gTestRunner->willSendRequestReturnsNullOnRedirect() && messages->redirect_response) {
  465. printf("Returning null for this redirect\n");
  466. messages->request->url = 0;
  467. return;
  468. }
  469. KURL url = KURL(ParsedURLString, messages->request->url);
  470. if (url.isValid()
  471. && url.protocolIsInHTTPFamily()
  472. && url.host() != "127.0.0.1"
  473. && url.host() != "255.255.255.255"
  474. && url.host().lower() != "localhost") {
  475. printf("Blocked access to external URL %s\n", messages->request->url);
  476. messages->request->url = 0;
  477. return;
  478. }
  479. const std::string& destination = gTestRunner->redirectionDestinationForURL(url.string().utf8().data());
  480. if (destination.length())
  481. messages->request->url = strdup(destination.c_str());
  482. }
  483. void DumpRenderTreeChrome::onWebViewOnloadEvent(void*, Evas_Object*, void* eventInfo)
  484. {
  485. const Evas_Object* frame = static_cast<Evas_Object*>(eventInfo);
  486. if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
  487. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  488. printf("%s - didHandleOnloadEventsForFrame\n", frameName.utf8().data());
  489. }
  490. }
  491. void DumpRenderTreeChrome::onInsecureContentRun(void*, Evas_Object*, void*)
  492. {
  493. if (!done && gTestRunner->dumpFrameLoadCallbacks())
  494. printf("didRunInsecureContent\n");
  495. }
  496. void DumpRenderTreeChrome::onInsecureContentDisplayed(void*, Evas_Object*, void*)
  497. {
  498. if (!done && gTestRunner->dumpFrameLoadCallbacks())
  499. printf("didDisplayInsecureContent\n");
  500. }
  501. void DumpRenderTreeChrome::onFrameCreated(void*, Evas_Object*, void* eventInfo)
  502. {
  503. Evas_Object* frame = static_cast<Evas_Object*>(eventInfo);
  504. evas_object_smart_callback_add(frame, "icon,changed", onFrameIconChanged, 0);
  505. evas_object_smart_callback_add(frame, "load,provisional", onFrameProvisionalLoad, 0);
  506. evas_object_smart_callback_add(frame, "load,provisional,failed", onFrameProvisionalLoadFailed, 0);
  507. evas_object_smart_callback_add(frame, "load,committed", onFrameLoadCommitted, 0);
  508. evas_object_smart_callback_add(frame, "load,finished", onFrameLoadFinished, 0);
  509. evas_object_smart_callback_add(frame, "load,error", onFrameLoadError, 0);
  510. evas_object_smart_callback_add(frame, "redirect,cancelled", onFrameRedirectCancelled, 0);
  511. evas_object_smart_callback_add(frame, "redirect,load,provisional", onFrameRedirectForProvisionalLoad, 0);
  512. evas_object_smart_callback_add(frame, "redirect,requested", onFrameRedirectRequested, 0);
  513. evas_object_smart_callback_add(frame, "title,changed", onFrameTitleChanged, 0);
  514. evas_object_smart_callback_add(frame, "xss,detected", onDidDetectXSS, 0);
  515. }
  516. void DumpRenderTreeChrome::onWebViewNavigatedWithData(void*, Evas_Object*, void* eventInfo)
  517. {
  518. if (done || !gTestRunner->dumpHistoryDelegateCallbacks())
  519. return;
  520. ASSERT(eventInfo);
  521. const Ewk_View_Navigation_Data* navigationData = static_cast<Ewk_View_Navigation_Data*>(eventInfo);
  522. ASSERT(navigationData->request);
  523. ASSERT(navigationData->response);
  524. const bool wasFailure = navigationData->has_substitute_data || navigationData->response->status_code >= 400;
  525. const bool wasRedirected = navigationData->client_redirect_source && *(navigationData->client_redirect_source);
  526. printf("WebView navigated to url \"%s\" with title \"%s\" with HTTP equivalent method \"%s\". The navigation was %s and was %s%s.\n",
  527. navigationData->url,
  528. navigationData->title,
  529. navigationData->request->http_method,
  530. wasFailure? "a failure" : "successful",
  531. (wasRedirected ? "a client redirect from " : "not a client redirect"),
  532. (wasRedirected ? navigationData->client_redirect_source : ""));
  533. }
  534. void DumpRenderTreeChrome::onWebViewServerRedirect(void*, Evas_Object*, void* eventInfo)
  535. {
  536. if (done || !gTestRunner->dumpHistoryDelegateCallbacks())
  537. return;
  538. ASSERT(eventInfo);
  539. const Ewk_View_Redirection_Data* data = static_cast<Ewk_View_Redirection_Data*>(eventInfo);
  540. printf("WebView performed a server redirect from \"%s\" to \"%s\".\n", data->source_url, data->destination_url);
  541. }
  542. void DumpRenderTreeChrome::onWebViewClientRedirect(void*, Evas_Object*, void* eventInfo)
  543. {
  544. if (done || !gTestRunner->dumpHistoryDelegateCallbacks())
  545. return;
  546. ASSERT(eventInfo);
  547. const Ewk_View_Redirection_Data* data = static_cast<Ewk_View_Redirection_Data*>(eventInfo);
  548. printf("WebView performed a client redirect from \"%s\" to \"%s\".\n", data->source_url, data->destination_url);
  549. }
  550. void DumpRenderTreeChrome::onWebViewPopulateVisitedLinks(void*, Evas_Object* ewkView, void*)
  551. {
  552. if (done || !gTestRunner->dumpHistoryDelegateCallbacks())
  553. return;
  554. printf("Asked to populate visited links for WebView \"%s\"\n", ewk_view_uri_get(ewkView));
  555. }
  556. void DumpRenderTreeChrome::onInspectorViewCreate(void*, Evas_Object*, void*)
  557. {
  558. Evas_Object* inspectorView = browser->createInspectorView();
  559. if (inspectorView)
  560. ewk_view_inspector_view_set(browser->mainView(), inspectorView);
  561. }
  562. void DumpRenderTreeChrome::onInspectorViewClose(void*, Evas_Object*, void*)
  563. {
  564. browser->removeInspectorView();
  565. }
  566. void DumpRenderTreeChrome::onInspectorFrameLoadFinished(void*, Evas_Object*, void*)
  567. {
  568. Evas_Object* inspectorView = ewk_view_inspector_view_get(browser->mainView());
  569. if (inspectorView)
  570. ecore_main_loop_quit();
  571. }
  572. void DumpRenderTreeChrome::onFrameProvisionalLoad(void*, Evas_Object* frame, void*)
  573. {
  574. if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
  575. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  576. printf("%s - didStartProvisionalLoadForFrame\n", frameName.utf8().data());
  577. }
  578. if (!topLoadingFrame && !done)
  579. topLoadingFrame = frame;
  580. if (!done && gTestRunner->stopProvisionalFrameLoads()) {
  581. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  582. printf("%s - stopping load in didStartProvisionalLoadForFrame callback\n", frameName.utf8().data());
  583. ewk_frame_stop(frame);
  584. }
  585. }
  586. void DumpRenderTreeChrome::onFrameProvisionalLoadFailed(void*, Evas_Object* frame, void*)
  587. {
  588. m_provisionalLoadFailedFrame = frame;
  589. if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
  590. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  591. printf("%s - didFailProvisionalLoadWithError\n", frameName.utf8().data());
  592. }
  593. }
  594. void DumpRenderTreeChrome::onFrameLoadCommitted(void*, Evas_Object* frame, void*)
  595. {
  596. if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
  597. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  598. printf("%s - didCommitLoadForFrame\n", frameName.utf8().data());
  599. }
  600. }
  601. void DumpRenderTreeChrome::onFrameLoadFinished(void*, Evas_Object* frame, void* eventInfo)
  602. {
  603. const Ewk_Frame_Load_Error* error = static_cast<Ewk_Frame_Load_Error*>(eventInfo);
  604. // EFL port emits both "load,finished" and "load,error" signals in error case.
  605. // Error case is therefore already handled in onFrameLoadError() and we don't need
  606. // to handle it here.
  607. if (error)
  608. return;
  609. if (!done && gTestRunner->dumpProgressFinishedCallback())
  610. printf("postProgressFinishedNotification\n");
  611. if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
  612. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  613. printf("%s - didFinishLoadForFrame\n", frameName.utf8().data());
  614. }
  615. if (frame == topLoadingFrame)
  616. topLoadingFrameLoadFinished();
  617. }
  618. void DumpRenderTreeChrome::onFrameLoadError(void*, Evas_Object* frame, void*)
  619. {
  620. // In case of provisional load error, we receive both "load,error" and "load,provisional,failed"
  621. // signals. m_provisionalLoadFailedFrame is used to avoid printing twice the load error: in
  622. // onFrameProvisionalLoadFailed() and onFrameLoadError().
  623. if (!done && gTestRunner->dumpFrameLoadCallbacks() && frame != m_provisionalLoadFailedFrame) {
  624. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  625. printf("%s - didFailLoadWithError\n", frameName.utf8().data());
  626. }
  627. if (m_provisionalLoadFailedFrame && frame == m_provisionalLoadFailedFrame)
  628. m_provisionalLoadFailedFrame = 0;
  629. if (frame == topLoadingFrame)
  630. topLoadingFrameLoadFinished();
  631. }
  632. void DumpRenderTreeChrome::onFrameRedirectCancelled(void*, Evas_Object* frame, void*)
  633. {
  634. if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
  635. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  636. printf("%s - didCancelClientRedirectForFrame\n", frameName.utf8().data());
  637. }
  638. }
  639. void DumpRenderTreeChrome::onFrameRedirectForProvisionalLoad(void*, Evas_Object* frame, void*)
  640. {
  641. if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
  642. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  643. printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", frameName.utf8().data());
  644. }
  645. }
  646. void DumpRenderTreeChrome::onFrameRedirectRequested(void*, Evas_Object* frame, void* eventInfo)
  647. {
  648. const char* url = static_cast<const char*>(eventInfo);
  649. if (!done && gTestRunner->dumpFrameLoadCallbacks()) {
  650. const String frameName(DumpRenderTreeSupportEfl::suitableDRTFrameName(frame));
  651. printf("%s - willPerformClientRedirectToURL: %s \n", frameName.utf8().data(), pathSuitableForTestResult(url).data());
  652. }
  653. }
  654. void DumpRenderTreeChrome::onDidDetectXSS(void*, Evas_Object* view, void*)
  655. {
  656. if (!done && gTestRunner->dumpFrameLoadCallbacks())
  657. printf("didDetectXSS\n");
  658. }
  659. void DumpRenderTreeChrome::onResponseReceived(void*, Evas_Object*, void* eventInfo)
  660. {
  661. Ewk_Frame_Resource_Response* response = static_cast<Ewk_Frame_Resource_Response*>(eventInfo);
  662. if (!done && gTestRunner->dumpResourceLoadCallbacks()) {
  663. CString responseDescription(descriptionSuitableForTestResult(response));
  664. printf("%s - didReceiveResponse %s\n",
  665. m_dumpAssignedUrls.contains(response->identifier) ? m_dumpAssignedUrls.get(response->identifier).data() : "<unknown>",
  666. responseDescription.data());
  667. }
  668. if (!done && gTestRunner->dumpResourceResponseMIMETypes()) {
  669. printf("%s has MIME type %s\n",
  670. KURL(ParsedURLString, response->url).lastPathComponent().utf8().data(),
  671. response->mime_type);
  672. }
  673. }
  674. void DumpRenderTreeChrome::onResourceLoadFinished(void*, Evas_Object*, void* eventInfo)
  675. {
  676. unsigned long identifier = *static_cast<unsigned long*>(eventInfo);
  677. if (!done && gTestRunner->dumpResourceLoadCallbacks())
  678. printf("%s - didFinishLoading\n",
  679. (m_dumpAssignedUrls.contains(identifier) ? m_dumpAssignedUrls.take(identifier).data() : "<unknown>"));
  680. }
  681. void DumpRenderTreeChrome::onResourceLoadFailed(void*, Evas_Object*, void* eventInfo)
  682. {
  683. Ewk_Frame_Load_Error* error = static_cast<Ewk_Frame_Load_Error*>(eventInfo);
  684. if (!done && gTestRunner->dumpResourceLoadCallbacks())
  685. printf("%s - didFailLoadingWithError: %s\n",
  686. (m_dumpAssignedUrls.contains(error->resource_identifier) ? m_dumpAssignedUrls.take(error->resource_identifier).data() : "<unknown>"),
  687. descriptionSuitableForTestResult(error).data());
  688. }
  689. void DumpRenderTreeChrome::onNewResourceRequest(void*, Evas_Object*, void* eventInfo)
  690. {
  691. Ewk_Frame_Resource_Request* request = static_cast<Ewk_Frame_Resource_Request*>(eventInfo);
  692. if (!done && gTestRunner->dumpResourceLoadCallbacks())
  693. m_dumpAssignedUrls.add(request->identifier, pathSuitableForTestResult(request->url));
  694. }
  695. void DumpRenderTreeChrome::onDownloadRequest(void*, Evas_Object*, void* eventInfo)
  696. {
  697. // In case of "download,request", the URL need to be downloaded, not opened on the current view.
  698. // Because there is no download agent for the DumpRenderTree,
  699. // create a new view and load the URL on that view just for a test.
  700. Evas_Object* newView = browser->createView();
  701. if (!newView)
  702. return;
  703. Ewk_Download* download = static_cast<Ewk_Download*>(eventInfo);
  704. ewk_view_theme_set(newView, TEST_THEME_DIR "/default.edj");
  705. ewk_view_uri_set(newView, download->url);
  706. browser->m_extraViews.append(newView);
  707. }
  708. #if HAVE(ACCESSIBILITY)
  709. AccessibilityController* DumpRenderTreeChrome::accessibilityController() const
  710. {
  711. return m_axController.get();
  712. }
  713. #endif