[M120 Migration][MM] Support W3C EME
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / unittest / utc_blink_ewk_base.cpp
1 // Copyright 2016 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /**
6  * @file   utc_blink_ewk_base.cpp
7  * @author Kamil Klimek <k.klimek@partner.samsung.com>
8  * @date   2014-03-03
9  * @brief  A Source file to be used by all unit test cases for Chromium EFL API
10  *
11  * This header file contains a common content for unit test cases, i.e.:
12  * it includes useful header files, defines shared object pointers,
13  * useful macros, functions and enumeration types.
14  */
15
16 #include "utc_blink_ewk_base.h"
17
18 // Do not use them except ctor. You can access argv table from
19 // utc_blink_ewk_base::argv if needed.
20 extern int argc_;
21 extern char** argv_;
22
23 utc_blink_ewk_base::utc_blink_ewk_base()
24     : ::testing::Test()
25     , timeout(NULL)
26     , main_loop_running(false)
27     , main_loop_result(utc_blink_ewk_base::NoOp)
28     , log_javascript(true)
29     , ewk_window(NULL)
30     , ewk_evas(NULL)
31     , ewk_background(NULL)
32     , ewk_webview(NULL)
33     , ewk_context(NULL)
34     , resource_dir(NULL)
35 {
36     char *env_dir = getenv("UTC_RESOURCE_PATH");
37
38     if (env_dir) {
39         resource_dir = strdup(env_dir);
40     } else {
41         resource_dir = strdup("/opt/usr/resources");
42     }
43     for (int i = 0; i < argc_; i++)
44       argv.push_back(argv_[i]);
45 }
46
47 utc_blink_ewk_base::~utc_blink_ewk_base()
48 {
49     if (timeout) {
50         ecore_timer_del(timeout);
51         timeout = NULL;
52     }
53
54     free(resource_dir);
55 }
56
57 void utc_blink_ewk_base::AllowFileAccessFromFiles() {
58   static const char* file_access_literal = "--allow-file-access-from-files";
59   argv.push_back(const_cast<char*>(file_access_literal));
60 }
61
62 std::string utc_blink_ewk_base::GetResourcePath(const char* resource_path) const
63 {
64     std::string retval = resource_dir;
65     retval.append("/");
66     retval.append(resource_path);
67
68     return retval;
69 }
70
71 bool utc_blink_ewk_base::CompareEvasImageWithResource(Evas_Object* image, const char* resource, int pixel_fuzziness) const
72 {
73   if (!image || !resource) {
74     utc_warning("[CompareEvasImageWithResource] :: both image and resource can't be NULL");
75     return false;
76   }
77   std::string resource_absolute_path = GetResourcePath(resource);
78
79   Evas_Object* resource_image = evas_object_image_filled_add(GetEwkEvas());
80   evas_object_image_file_set(resource_image, resource_absolute_path.c_str(), nullptr);
81
82   int resource_w = 0, resource_h = 0;
83   evas_object_image_size_get(resource_image, &resource_w, &resource_h);
84
85   int image_w = 0, image_h = 0;
86   evas_object_image_size_get(image, &image_w, &image_h);
87
88   if (resource_w != image_w || resource_h != image_h) {
89     evas_object_del(resource_image);
90     utc_warning("[CompareEvasImageWithResource] :: image size differs: %dx%d (image) vs %dx%d (resource)", image_w, image_h, resource_w, resource_h);
91     return false;
92   }
93
94   if (evas_object_image_colorspace_get(image) != evas_object_image_colorspace_get(resource_image)) {
95     evas_object_del(resource_image);
96     utc_warning("[CompareEvasImageWithResource] :: image colorspace differs");
97     return false;
98   }
99
100   int bytes_per_pixel = 0;
101
102   switch (evas_object_image_colorspace_get(image)) {
103     case EVAS_COLORSPACE_ARGB8888:
104       bytes_per_pixel = 4;
105       break;
106
107     case EVAS_COLORSPACE_RGB565_A5P:
108       bytes_per_pixel = 2;
109       break;
110
111     case EVAS_COLORSPACE_GRY8:
112       bytes_per_pixel = 1;
113       break;
114
115     default:
116       evas_object_del(resource_image);
117       utc_warning("[CompareEvasImageWithResource] :: unsupported colorspace");
118       return false;
119   }
120
121   unsigned char* image_data = static_cast<unsigned char*>(evas_object_image_data_get(image, EINA_FALSE));
122   unsigned char* resource_data = static_cast<unsigned char*>(evas_object_image_data_get(resource_image, EINA_FALSE));
123
124   bool retval = true;
125   int mismatch_bytes = 0;
126   for (int i = 0; i < image_w * image_h * bytes_per_pixel; i += bytes_per_pixel) {
127     // we allow little differences in pixels, Evas_Image and SkBitmap has different decoders and there
128     // may be little diference in individual bytes
129
130     int total_diff = 0;
131
132     for (int j = 0; j < bytes_per_pixel; ++j) {
133       total_diff += abs(resource_data[i + j] - image_data[i + j]);
134     }
135
136     if (total_diff > pixel_fuzziness) {
137       utc_warning("[CompareEvasImageWithResource] :: maximum fuzziness (%d) exceeded at %d pixel: %d", pixel_fuzziness, i, total_diff);
138       retval = false;
139
140       for (int j = 0; j < bytes_per_pixel; ++j) {
141         utc_info("image: 0x%2X resource: 0x%2X", image_data[i + j], resource_data[i + j]);
142       }
143
144       break;
145     }
146   }
147
148   evas_object_image_data_set(image, image_data);
149   evas_object_image_data_set(resource_image, resource_data);
150   evas_object_del(resource_image);
151
152   return retval;
153 }
154
155 std::string utc_blink_ewk_base::GetResourceUrl(const char* resource_path) const
156 {
157     std::string retval("file://");
158     retval.append(GetResourcePath(resource_path));
159     utc_debug("Resource:\t\"%s\"",retval.c_str());
160     return retval;
161 }
162
163 utc_blink_ewk_base::MainLoopResult utc_blink_ewk_base::EventLoopStart(double max_time)
164 {
165     utc_blink_ewk_base::MainLoopResult retval = utc_blink_ewk_base::NoOp;
166
167     if (!main_loop_running) {
168         main_loop_result = utc_blink_ewk_base::NoOp;
169
170         utc_debug("[EventLoopStart] :: timeout: %f", max_time);
171         main_loop_running = true;
172         timeout = ecore_timer_add(max_time, timeout_cb, this);
173         ecore_main_loop_begin();
174
175         if (timeout) {
176           ecore_timer_del(timeout);
177           timeout = NULL;
178         }
179
180         main_loop_running = false;
181         retval = main_loop_result;
182     }
183
184     return retval;
185 }
186
187 bool utc_blink_ewk_base::EventLoopWait(double time)
188 {
189     if (!main_loop_running) {
190         utc_debug("[EventLoopWait] :: time %f", time);
191         main_loop_running = true;
192         timeout = ecore_timer_add(time, timeout_cb_event_loop_wait, this);
193
194         ecore_main_loop_begin();
195
196         if (timeout) {
197           ecore_timer_del(timeout);
198           timeout = NULL;
199         }
200
201         main_loop_running = false;
202         return true;
203     }
204
205     return false;
206 }
207
208 bool utc_blink_ewk_base::EventLoopStop(utc_blink_ewk_base::MainLoopResult result)
209 {
210     if (main_loop_running && result != utc_blink_ewk_base::NoOp ) {
211         utc_debug("[EventLoopStop] :: Setting result to: %s", (result == utc_blink_ewk_base::Success ? "Success" : "Failure"));
212         main_loop_running = false;
213         main_loop_result = result;
214         ecore_main_loop_quit();
215         return true;
216     }
217
218     return false;
219 }
220
221 bool utc_blink_ewk_base::TimeOut() {
222   return false;
223 }
224
225 bool utc_blink_ewk_base::LoadError(Evas_Object* webview, Ewk_Error* error) {
226   EventLoopStop(LoadFailure);
227   return false;
228 }
229
230 void utc_blink_ewk_base::SetUp()
231 {
232     PreSetUp();
233
234     EwkInit();
235
236     evas_object_smart_callback_add(ewk_webview, "load,started", load_started_cb, this);
237     evas_object_smart_callback_add(ewk_webview, "load,finished", load_finished_cb, this);
238     evas_object_smart_callback_add(ewk_webview, "load,error", load_error_cb, this);
239     evas_object_smart_callback_add(ewk_webview, "load,progress", load_progress_cb, this);
240     evas_object_smart_callback_add(ewk_webview, "console,message", ToSmartCallback(console_message_cb), this);
241
242     PostSetUp();
243 }
244
245 void utc_blink_ewk_base::TearDown()
246 {
247     PreTearDown();
248
249     evas_object_smart_callback_del(ewk_webview, "load,started", load_started_cb);
250     evas_object_smart_callback_del(ewk_webview, "load,finished", load_finished_cb);
251     evas_object_smart_callback_del(ewk_webview, "load,error", load_error_cb);
252     evas_object_smart_callback_del(ewk_webview, "load,progress", load_progress_cb);
253     evas_object_smart_callback_del(ewk_webview, "console,message", ToSmartCallback(console_message_cb));
254
255     EwkDeinit();
256
257     PostTearDown();
258 }
259
260 void utc_blink_ewk_base::load_started_cb(void* data, Evas_Object* webview, void* event_info)
261 {
262     utc_debug("[load,started] :: data: %p, webview: %p, event_info: %p", data, webview, event_info);
263     utc_blink_ewk_base *ut = static_cast<utc_blink_ewk_base*>(data);
264     ut->LoadStarted(webview);
265 }
266
267 void utc_blink_ewk_base::load_finished_cb(void* data, Evas_Object* webview, void* event_info)
268 {
269     utc_debug("[load,finished] :: data: %p, webview: %p, event_info: %p", data, webview, event_info);
270     utc_blink_ewk_base *ut = static_cast<utc_blink_ewk_base*>(data);
271     ut->LoadFinished(webview);
272 }
273
274 void utc_blink_ewk_base::load_error_cb(void* data, Evas_Object* webview, void* event_info)
275 {
276     utc_debug("[load,error] :: data: %p, webview: %p, event_info: %p", data, webview, event_info);
277     utc_blink_ewk_base *ut = static_cast<utc_blink_ewk_base*>(data);
278     Ewk_Error *err = static_cast<Ewk_Error *>(event_info);
279
280     if(!ut->LoadError(webview, err)) {
281         utc_warning("[load,error] :: not handled by test, stopping main loop with Failure");
282         ut->EventLoopStop(utc_blink_ewk_base::Failure);
283     }
284 }
285
286 void utc_blink_ewk_base::load_progress_cb(void* data, Evas_Object* webview, void* event_info)
287 {
288     utc_debug("[load,progress] :: data: %p, webview: %p, event_info: %p", data, webview, event_info);
289     double progress = -1.0;
290     if (event_info) {
291         progress = *((double*)event_info);
292     }
293
294     utc_blink_ewk_base *ut = static_cast<utc_blink_ewk_base*>(data);
295     ut->LoadProgress(webview, progress);
296 }
297
298 void utc_blink_ewk_base::ConsoleMessage(Evas_Object*webview, const Ewk_Console_Message* msg)
299 {
300   EXPECT_EQ(ewk_webview, webview);
301   if (log_javascript)
302     fprintf(stdout, "JavaScript::console (%p):\t\"%s\"", webview, ewk_console_message_text_get(msg));
303 }
304
305 void utc_blink_ewk_base::console_message_cb(utc_blink_ewk_base* owner, Evas_Object* webview, Ewk_Console_Message* console)
306 {
307   ASSERT_TRUE(owner);
308   owner->ConsoleMessage(webview, console);
309 }
310
311 Eina_Bool utc_blink_ewk_base::timeout_cb(void *data)
312 {
313     utc_debug("[timeout] :: data: %p", data);
314     utc_blink_ewk_base *ut = static_cast<utc_blink_ewk_base*>(data);
315
316     if (!ut->TimeOut()) {
317         utc_warning("[timeout] :: not handled by test, stopping main loop with Failure");
318         ut->EventLoopStop(utc_blink_ewk_base::Timeout);
319     }
320
321     ut->timeout = NULL;
322     return ECORE_CALLBACK_CANCEL;
323 }
324
325 Eina_Bool utc_blink_ewk_base::timeout_cb_event_loop_wait(void *data)
326 {
327     utc_blink_ewk_base *ut = static_cast<utc_blink_ewk_base*>(data);
328     ecore_main_loop_quit();
329     ut->timeout = NULL;
330     return ECORE_CALLBACK_CANCEL;
331 }
332
333 void utc_blink_ewk_base::EwkInit()
334 {
335     /* 1. Standard TETware test initialization message */
336     utc_info("[[ TET_MSG ]]:: ============ Startup ============");
337
338     ewk_set_arguments(argv.size(), argv.data());
339
340     ewk_window = elm_win_add(NULL, "TC Launcher", ELM_WIN_BASIC);
341     elm_win_title_set(ewk_window, "TC Launcher");
342     ewk_evas = evas_object_evas_get(ewk_window);
343
344     ewk_background = evas_object_rectangle_add(ewk_evas);
345     evas_object_name_set(ewk_background, "view");
346     evas_object_color_set(ewk_background, 255, 0, 255, 255);
347     evas_object_move(ewk_background, 0, 0);
348     evas_object_resize(ewk_background, DEFAULT_WIDTH_OF_WINDOW, DEFAULT_HEIGHT_OF_WINDOW);
349     evas_object_layer_set(ewk_background, EVAS_LAYER_MIN);
350
351     evas_object_show(ewk_background);
352
353     /* 3. Initialization of webview */
354     ewk_context = ewk_context_default_get();
355     ewk_webview = ewk_view_add_with_context(ewk_evas, ewk_context);
356     evas_object_move(ewk_webview, 10, 10);
357     evas_object_resize(ewk_webview, DEFAULT_WIDTH_OF_WINDOW - 20, DEFAULT_HEIGHT_OF_WINDOW - 20);
358
359     evas_object_show(ewk_webview);
360     evas_object_show(ewk_window);
361 }
362
363 void utc_blink_ewk_base::EwkDeinit()
364 {
365     /* 1. Standard TETware test end/cleanup messages */
366     utc_info("[[ TET_MSG ]]:: ============ Cleanup ============");
367
368     /* 2. Freeing resources */
369     if (ewk_webview)
370         evas_object_del(ewk_webview);
371
372     if (ewk_window)
373         evas_object_del(ewk_window);
374
375     ewk_window = NULL;
376     ewk_evas = NULL;
377     ewk_background = NULL;
378     ewk_webview = NULL;
379 }
380
381 void utc_blink_ewk_base::FeedMouseClick(int x, int y, int button) {
382   if (!ewk_evas)
383     return;
384
385   evas_event_feed_mouse_move(ewk_evas, x, y, ecore_time_get(), 0);
386   evas_event_feed_mouse_down(ewk_evas, button, EVAS_BUTTON_NONE,
387                              ecore_time_get(), 0);
388   evas_event_feed_mouse_up(ewk_evas, button, EVAS_BUTTON_NONE, ecore_time_get(),
389                            0);
390 }
391
392 void utc_log(UtcLogSeverity severity, const char* format, ...) {
393   static UtcLogSeverity minLogSeverity = -1;
394   if (minLogSeverity == -1) {
395     char *env_severity = getenv("UTC_MIN_LOG");
396     if (env_severity && !strcmp(env_severity, "DEBUG")) {
397       minLogSeverity = UTC_LOG_DEBUG;
398     } else if (env_severity && !strcmp(env_severity, "INFO")) {
399       minLogSeverity = UTC_LOG_INFO;
400     } else if (env_severity && !strcmp(env_severity, "WARNING")) {
401       minLogSeverity = UTC_LOG_WARNING;
402     } else if (env_severity && !strcmp(env_severity, "ERROR")) {
403       minLogSeverity = UTC_LOG_ERROR;
404     } else {
405       minLogSeverity = UTC_LOG_INFO;
406     }
407   }
408   if (minLogSeverity > severity)
409     return;
410
411   va_list arglist;
412   va_start(arglist, format);
413   vfprintf(stderr, format, arglist );
414   va_end(arglist);
415 }