~azzar1/unity/lp-1226116

« back to all changes in this revision

Viewing changes to standalone-clients/nux_automated_test_framework.cpp

  • Committer: Daniel van Vugt
  • Date: 2012-03-14 06:24:18 UTC
  • mfrom: (2108 unity)
  • mto: This revision was merged to the branch mainline in revision 2146.
  • Revision ID: daniel.van.vugt@canonical.com-20120314062418-nprucpbr0m7qky5e
MergedĀ latestĀ lp:unity

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2010 Inalogic Inc.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 3, as published
 
6
 * by the  Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * version 3 along with this program.  If not, see
 
15
 * <http://www.gnu.org/licenses/>
 
16
 *
 
17
 * Authored by: Jay Taoko <jaytaoko@inalogic.com>
 
18
 *
 
19
 */
 
20
 
 
21
#include "Nux/Nux.h"
 
22
#include <X11/extensions/XTest.h>
 
23
#include <X11/keysym.h> 
 
24
#include "nux_automated_test_framework.h"
 
25
 
 
26
 
 
27
int NuxAutomatedTestFramework::mouse_motion_time_span = 1000; // milliseconds
 
28
int NuxAutomatedTestFramework::mouse_click_time_span = 300;   // milliseconds
 
29
int NuxAutomatedTestFramework::minimum_sleep_time = 600;      // milliseconds
 
30
int NuxAutomatedTestFramework::safety_border_inside_view = 1; // pixels
 
31
 
 
32
NuxAutomatedTestFramework::NuxAutomatedTestFramework(nux::WindowThread *window_thread)
 
33
{
 
34
  ready_to_start_ = false;
 
35
  display_ = NULL;
 
36
  window_thread_ = window_thread;
 
37
  window_x_ = 0;
 
38
  window_y_ = 0;
 
39
  window_width_ = 0;
 
40
  window_height_ = 0;
 
41
  terminate_when_test_over_ = false;
 
42
}
 
43
 
 
44
NuxAutomatedTestFramework::~NuxAutomatedTestFramework()
 
45
{
 
46
  XCloseDisplay(display_);
 
47
}
 
48
 
 
49
void NuxAutomatedTestFramework::SetTerminateProgramWhenDone(bool terminate)
 
50
{
 
51
  terminate_when_test_over_ = terminate;
 
52
}
 
53
 
 
54
bool NuxAutomatedTestFramework::WhenDoneTerminateProgram()
 
55
{
 
56
  return terminate_when_test_over_;
 
57
}
 
58
 
 
59
void NuxAutomatedTestFramework::Startup()
 
60
{
 
61
  display_ = XOpenDisplay(NULL);
 
62
  nux::Geometry rect = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
 
63
  //nuxDebugMsg("Window geometry: (%d, %d, %d, %d)", rect.x, rect.y, rect.width, rect.height);
 
64
 
 
65
  window_x_ = rect.x;
 
66
  window_y_ = rect.y;
 
67
  window_width_ = rect.width;
 
68
  window_height_ = rect.height;
 
69
}
 
70
 
 
71
void NuxAutomatedTestFramework::ViewSendMouseClick(nux::View *view, int button)
 
72
{
 
73
  nux::Rect r;
 
74
  if (view)
 
75
  {
 
76
    r = view->GetAbsoluteGeometry();
 
77
    r.OffsetPosition(window_x_ + r.width/2, window_y_ + r.height/2);
 
78
  }
 
79
  else
 
80
  {
 
81
    r = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
 
82
    r.OffsetPosition(r.width/2, r.height/2);
 
83
  }
 
84
 
 
85
  SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span);
 
86
  SendFakeMouseEvent(button, true);
 
87
  nux::SleepForMilliseconds(NuxAutomatedTestFramework::mouse_click_time_span);
 
88
  SendFakeMouseEvent(button, false);
 
89
 
 
90
  XSync(display_, False);
 
91
  nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time);
 
92
}
 
93
 
 
94
void NuxAutomatedTestFramework::ViewSendMouseDoubleClick(nux::View *view, int button)
 
95
{
 
96
  nux::Rect r;
 
97
  if (view)
 
98
  {
 
99
    r = view->GetAbsoluteGeometry();
 
100
    r.OffsetPosition(window_x_ + r.width/2, window_y_ + r.height/2);
 
101
  }
 
102
  else
 
103
  {
 
104
    r = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
 
105
    r.OffsetPosition(r.width/2, r.height/2);
 
106
  }
 
107
    
 
108
  // Send the mouse to the center of the view
 
109
  SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span);
 
110
 
 
111
  XTestFakeButtonEvent(display_, button, true,  CurrentTime);
 
112
  XTestFakeButtonEvent(display_, button, false,  CurrentTime);
 
113
  XTestFakeButtonEvent(display_, button, true,  CurrentTime);
 
114
  XTestFakeButtonEvent(display_, button, false,  CurrentTime);
 
115
  XSync(display_, False);
 
116
  nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time);
 
117
}
 
118
 
 
119
void NuxAutomatedTestFramework::ViewSendMouseDown(nux::View *view, int button)
 
120
{
 
121
  XEvent event;
 
122
  /* Get the current pointer position */  
 
123
  XQueryPointer(display_, RootWindow(display_, 0),  
 
124
        &event.xbutton.root, &event.xbutton.window,  
 
125
        &event.xbutton.x_root, &event.xbutton.y_root,  
 
126
        &event.xbutton.x, &event.xbutton.y,  
 
127
        &event.xbutton.state);
 
128
 
 
129
  int current_x = event.xbutton.x - window_x_;
 
130
  int current_y = event.xbutton.y - window_y_;
 
131
 
 
132
  nux::Rect r = view->GetAbsoluteGeometry();
 
133
 
 
134
  if (!r.IsInside(nux::Point(current_x, current_y)))
 
135
  {
 
136
    // The mouse pointer is not inside the view.
 
137
    // Move the mouse pointer to the center of the view.
 
138
    r.OffsetPosition(window_x_, window_y_);
 
139
 
 
140
    // Go to the center of the view
 
141
    int view_center_x = r.x + r.width/2;
 
142
    int view_center_y = r.y + r.height/2;
 
143
    SendFakeMouseMotionEvent(view_center_x, view_center_y, NuxAutomatedTestFramework::mouse_motion_time_span);
 
144
    nux::SleepForMilliseconds(minimum_sleep_time);
 
145
  }
 
146
  SendFakeMouseEvent(button, true);
 
147
}
 
148
 
 
149
void NuxAutomatedTestFramework::ViewSendMouseUp(nux::View *view, int button)
 
150
{
 
151
  //   nux::Rect r = view->GetAbsoluteGeometry();
 
152
  // r.OffsetPosition(window_x_, window_y_);
 
153
 
 
154
  // int view_center_x = r.x + r.width/2;
 
155
  // int view_center_y = r.y + r.height/2;
 
156
 
 
157
  // SendFakeMouseMotionEvent(view_center_x, view_center_y, 1000);
 
158
  // nux::SleepForMilliseconds(minimum_sleep_time);
 
159
  SendFakeMouseEvent(button, false);
 
160
}
 
161
 
 
162
void NuxAutomatedTestFramework::ViewSendMouseDrag(nux::View *view, int button_index, int x0, int y0, int x1, int y1)
 
163
{
 
164
  nux::Rect r0 = view->GetAbsoluteGeometry();
 
165
  nux::Rect r1 = view->GetAbsoluteGeometry();
 
166
  r0.OffsetPosition(window_x_ + x0, window_y_ + y0);
 
167
  r1.OffsetPosition(window_x_ + x1, window_y_ + y1);
 
168
 
 
169
  // Go to first point
 
170
  SendFakeMouseMotionEvent(r0.x, r0.y, NuxAutomatedTestFramework::mouse_motion_time_span);
 
171
  nux::SleepForMilliseconds(minimum_sleep_time);
 
172
  
 
173
  // Mouse down
 
174
  ViewSendMouseDown(view, button_index);
 
175
 
 
176
  // Drag to second point
 
177
  SendFakeMouseMotionEvent(r1.x, r1.y, NuxAutomatedTestFramework::mouse_motion_time_span);
 
178
  nux::SleepForMilliseconds(minimum_sleep_time);
 
179
 
 
180
  // Mouse up
 
181
  ViewSendMouseUp(view, button_index);
 
182
}
 
183
 
 
184
void NuxAutomatedTestFramework::ViewSendMouseMotionTo(nux::View *view, int x, int y)
 
185
{
 
186
  nux::Rect r;
 
187
  if (view)
 
188
  {
 
189
    r = view->GetAbsoluteGeometry();
 
190
    r.OffsetPosition(window_x_ + x, window_y_ + y);
 
191
  }
 
192
  else
 
193
  {
 
194
    r = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
 
195
    r.OffsetPosition(x, y);
 
196
  }
 
197
 
 
198
  SendFakeMouseMotionEvent(r.x, r.y, NuxAutomatedTestFramework::mouse_motion_time_span);
 
199
}
 
200
 
 
201
void NuxAutomatedTestFramework::ViewSendMouseMotionToCenter(nux::View *view)
 
202
{
 
203
  nux::Rect r;
 
204
  if (view)
 
205
  {
 
206
    r = view->GetAbsoluteGeometry();
 
207
    r.OffsetPosition(window_x_, window_y_);
 
208
  }
 
209
  else
 
210
  {
 
211
    r = window_thread_->GetGraphicsDisplay().GetWindowGeometry();
 
212
  }
 
213
 
 
214
  int view_center_x = r.x + r.width/2;
 
215
  int view_center_y = r.y + r.height/2;
 
216
 
 
217
  SendFakeMouseMotionEvent(view_center_x, view_center_y, NuxAutomatedTestFramework::mouse_motion_time_span);
 
218
}
 
219
 
 
220
void NuxAutomatedTestFramework::ViewSendMouseMotionToTopLeft(nux::View *view)
 
221
{
 
222
  nux::Rect r = view->GetAbsoluteGeometry();
 
223
  r.OffsetPosition(window_x_, window_y_);
 
224
 
 
225
  SendFakeMouseMotionEvent(r.x + safety_border_inside_view, r.y + safety_border_inside_view, NuxAutomatedTestFramework::mouse_motion_time_span);
 
226
}
 
227
 
 
228
void NuxAutomatedTestFramework::ViewSendMouseMotionToTopRight(nux::View *view)
 
229
{
 
230
  nux::Rect r = view->GetAbsoluteGeometry();
 
231
  r.OffsetPosition(window_x_, window_y_);
 
232
 
 
233
  SendFakeMouseMotionEvent(r.x + r.width-1, r.y+safety_border_inside_view, NuxAutomatedTestFramework::mouse_motion_time_span);
 
234
}
 
235
 
 
236
void NuxAutomatedTestFramework::ViewSendMouseMotionToBottomLeft(nux::View *view)
 
237
{
 
238
  nux::Rect r = view->GetAbsoluteGeometry();
 
239
  r.OffsetPosition(window_x_, window_y_);
 
240
 
 
241
  SendFakeMouseMotionEvent(r.x+safety_border_inside_view, r.y + r.height-1, NuxAutomatedTestFramework::mouse_motion_time_span);
 
242
}
 
243
 
 
244
void NuxAutomatedTestFramework::ViewSendMouseMotionToBottomRight(nux::View *view)
 
245
{
 
246
  nux::Rect r = view->GetAbsoluteGeometry();
 
247
  r.OffsetPosition(window_x_, window_y_);
 
248
 
 
249
  SendFakeMouseMotionEvent(r.x + r.width-1, r.y + r.height-1, NuxAutomatedTestFramework::mouse_motion_time_span);
 
250
}
 
251
 
 
252
void NuxAutomatedTestFramework::ViewSendChar(const char c)
 
253
{
 
254
  KeySym modifier = 0;
 
255
 
 
256
  if ((c >= 'A') && (c <= 'Z'))
 
257
  {
 
258
    modifier = XK_Shift_L;
 
259
  }
 
260
 
 
261
  std::string s(1, c);
 
262
  SendFakeKeyEvent(XStringToKeysym(s.c_str()), modifier);
 
263
  nux::SleepForMilliseconds(300);
 
264
}
 
265
 
 
266
void NuxAutomatedTestFramework::ViewSendString(const std::string &str)
 
267
{
 
268
  int l = str.length();
 
269
  if (l == 0)
 
270
    return;
 
271
  
 
272
  int i = 0;
 
273
 
 
274
  while (i < l)
 
275
  {
 
276
    KeySym modifier = 0;
 
277
    char c = str[i++];
 
278
 
 
279
    if ((c >= 'A') && (c <= 'Z'))
 
280
    {
 
281
      modifier = XK_Shift_L;
 
282
    }
 
283
 
 
284
    std::string s(1, c);
 
285
    SendFakeKeyEvent(XStringToKeysym(s.c_str()), modifier);
 
286
    nux::SleepForMilliseconds(300);
 
287
  }
 
288
}
 
289
 
 
290
void NuxAutomatedTestFramework::ViewSendKeyCombo(KeySym modsym0, KeySym modsym1, KeySym modsym2, const char c)
 
291
{
 
292
  KeyCode keycode = 0;
 
293
  KeyCode modcode0 = 0;
 
294
  KeyCode modcode1 = 0;
 
295
  KeyCode modcode2 = 0;
 
296
  
 
297
  std::string s(1, c);
 
298
  keycode = XKeysymToKeycode(display_, XStringToKeysym(s.c_str()));
 
299
  XTestGrabControl(display_, True);
 
300
  
 
301
  /* Generate modkey press */
 
302
  if (modsym0 != 0)
 
303
  {
 
304
    modcode0 = XKeysymToKeycode(display_, modsym0);
 
305
    XTestFakeKeyEvent(display_, modcode0, True, 0);
 
306
  }
 
307
  if (modsym1 != 0)
 
308
  {
 
309
    modcode1 = XKeysymToKeycode(display_, modsym1);
 
310
    XTestFakeKeyEvent(display_, modcode1, True, 0);
 
311
  }
 
312
  if (modsym2 != 0)
 
313
  {
 
314
    modcode2 = XKeysymToKeycode(display_, modsym2);
 
315
    XTestFakeKeyEvent(display_, modcode2, True, 0);
 
316
  }
 
317
      
 
318
  /* Generate regular key press and release */
 
319
  XTestFakeKeyEvent(display_, keycode, True, 0);
 
320
  XTestFakeKeyEvent(display_, keycode, False, 0);
 
321
  
 
322
  /* Generate modkey release */
 
323
  if (modsym0 != 0)
 
324
  {
 
325
    XTestFakeKeyEvent(display_, modcode0, False, 0);
 
326
  }
 
327
  if (modsym1 != 0)
 
328
  {
 
329
    XTestFakeKeyEvent(display_, modcode1, False, 0);
 
330
  }
 
331
  if (modsym2 != 0)
 
332
  {
 
333
    XTestFakeKeyEvent(display_, modcode2, False, 0);
 
334
  }
 
335
    
 
336
  XSync(display_, False);
 
337
  XTestGrabControl(display_, False);  
 
338
}
 
339
 
 
340
void NuxAutomatedTestFramework::ViewSendCtrlA()
 
341
{
 
342
  ViewSendKeyCombo(XK_Control_L, 0, 0, 'a');
 
343
}
 
344
 
 
345
void NuxAutomatedTestFramework::ViewSendDelete()
 
346
{
 
347
  SendFakeKeyEvent(XK_Delete, 0);
 
348
}
 
349
 
 
350
void NuxAutomatedTestFramework::ViewSendBackspace()
 
351
{
 
352
  SendFakeKeyEvent(XK_BackSpace, 0);  
 
353
}
 
354
 
 
355
void NuxAutomatedTestFramework::ViewSendEscape()
 
356
{
 
357
  SendFakeKeyEvent(XK_Escape, 0);  
 
358
}
 
359
 
 
360
void NuxAutomatedTestFramework::ViewSendTab()
 
361
{
 
362
  SendFakeKeyEvent(XK_Tab, 0);
 
363
}
 
364
 
 
365
void NuxAutomatedTestFramework::ViewSendReturn()
 
366
{
 
367
  SendFakeKeyEvent(XK_Return, 0);
 
368
}
 
369
 
 
370
void NuxAutomatedTestFramework::PutMouseAt(int x, int y)
 
371
{
 
372
  XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), x, y, CurrentTime);  
 
373
  XSync(display_, False);
 
374
}
 
375
 
 
376
void NuxAutomatedTestFramework::SendFakeKeyEvent(KeySym keysym, KeySym modsym)
 
377
{
 
378
  KeyCode keycode = 0;
 
379
  KeyCode modcode = 0;
 
380
  
 
381
  keycode = XKeysymToKeycode(display_, keysym);
 
382
  XTestGrabControl(display_, True);
 
383
  
 
384
  /* Generate modkey press */
 
385
  if (modsym != 0)
 
386
  {
 
387
    modcode = XKeysymToKeycode(display_, modsym);
 
388
    XTestFakeKeyEvent(display_, modcode, True, 0);
 
389
  }
 
390
  
 
391
  /* Generate regular key press and release */
 
392
  XTestFakeKeyEvent(display_, keycode, True, 0);
 
393
  XTestFakeKeyEvent(display_, keycode, False, 0);
 
394
  
 
395
  /* Generate modkey release */
 
396
  if (modsym != 0)
 
397
  {
 
398
    XTestFakeKeyEvent(display_, modcode, False, 0);
 
399
  }
 
400
 
 
401
  XSync(display_, False);
 
402
  XTestGrabControl(display_, False);
 
403
}
 
404
 
 
405
void NuxAutomatedTestFramework::SendFakeMouseEvent(int mouse_button_index, bool pressed)
 
406
{
 
407
  XTestFakeButtonEvent(display_, mouse_button_index, pressed,  CurrentTime);
 
408
  XSync(display_, False);  
 
409
}
 
410
 
 
411
void NuxAutomatedTestFramework::SendFakeMouseMotionEvent(int x, int y, int ms_delay)
 
412
{
 
413
  XEvent event;
 
414
  /* Get the current pointer position */
 
415
  XQueryPointer(display_, RootWindow(display_, 0),
 
416
        &event.xbutton.root, &event.xbutton.window,
 
417
        &event.xbutton.x_root, &event.xbutton.y_root,
 
418
        &event.xbutton.x, &event.xbutton.y,
 
419
        &event.xbutton.state);
 
420
 
 
421
  int old_x = event.xbutton.x;
 
422
  int old_y = event.xbutton.y;
 
423
 
 
424
  int n_iteration = ms_delay / 16.0f;
 
425
 
 
426
  //nuxDebugMsg("n_iteration: %d", n_iteration);
 
427
 
 
428
  if (n_iteration < 1)
 
429
  {
 
430
    n_iteration = 1;
 
431
  }
 
432
 
 
433
  XSync(display_, False);
 
434
 
 
435
  for (int i = 0; i < n_iteration; i++)
 
436
  {
 
437
    float t = ((float)i + 1.0f) / n_iteration;
 
438
 
 
439
    int cx = (1.0f - t) * old_x + t * x;
 
440
    int cy = (1.0f - t) * old_y + t * y;
 
441
    XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), cx, cy, CurrentTime);
 
442
    XSync(display_, False);
 
443
    usleep(16*1000);
 
444
  }
 
445
 
 
446
  XTestFakeMotionEvent(display_, XScreenNumberOfScreen(DefaultScreenOfDisplay(display_)), x, y, CurrentTime);  
 
447
  XSync(display_, False);
 
448
  nux::SleepForMilliseconds(NuxAutomatedTestFramework::minimum_sleep_time);
 
449
}
 
450
 
 
451
void NuxAutomatedTestFramework::TestReportMsg(bool b, const char* msg)
 
452
{
 
453
  if (b)
 
454
  {
 
455
    nuxOkMsg("%s: %s", msg, "Ok");
 
456
  }
 
457
  else
 
458
  {
 
459
    nuxAlertMsg("%s: %s", msg, "Failed");
 
460
  }  
 
461
}
 
 
b'\\ No newline at end of file'