You.i Engine
YiWebDriver.h
Go to the documentation of this file.
1 // © You i Labs Inc. 2000-2017. All rights reserved.
2 #ifndef _YI_WEBDRIVER_H_
3 #define _YI_WEBDRIVER_H_
4 
5 #include "framework/YiPredef.h"
7 #include "signal/YiSignal.h"
10 #include "utility/YiString.h"
11 #include "utility/YiTimer.h"
12 #include "view/YiSceneView.h"
13 #include "view/YiScrollingView.h"
14 
15 class CYIKeyEvent;
16 class CYIAppiumTCPServer;
17 class CYIWebDriverPriv;
18 
29 {
30 public:
31  CYIWebDriver();
32  virtual ~CYIWebDriver();
33 
37  void Start();
38 
39  /*
40  \details
41  https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/remote/errorhandler.py
42 
43  """
44  Error codes defined in the WebDriver wire protocol.
45  """
46  # Keep in sync with org.openqa.selenium.remote.ErrorCodes and errorcodes.h
47  SUCCESS = 0
48  NO_SUCH_ELEMENT = [7, 'no such element']
49  NO_SUCH_FRAME = [8, 'no such frame']
50  UNKNOWN_COMMAND = [9, 'unknown command']
51  STALE_ELEMENT_REFERENCE = [10, 'stale element reference']
52  ELEMENT_NOT_VISIBLE = [11, 'element not visible']
53  INVALID_ELEMENT_STATE = [12, 'invalid element state']
54  UNKNOWN_ERROR = [13, 'unknown error']
55  ELEMENT_IS_NOT_SELECTABLE = [15, 'element not selectable']
56  JAVASCRIPT_ERROR = [17, 'javascript error']
57  XPATH_LOOKUP_ERROR = [19, 'invalid selector']
58  TIMEOUT = [21, 'timeout']
59  NO_SUCH_WINDOW = [23, 'no such window']
60  INVALID_COOKIE_DOMAIN = [24, 'invalid cookie domain']
61  UNABLE_TO_SET_COOKIE = [25, 'unable to set cookie']
62  UNEXPECTED_ALERT_OPEN = [26, 'unexpected alert open']
63  NO_ALERT_OPEN = [27, 'no such alert']
64  SCRIPT_TIMEOUT = [28, 'script timeout']
65  INVALID_ELEMENT_COORDINATES = [29, 'invalid element coordinates']
66  IME_NOT_AVAILABLE = [30, 'ime not available']
67  IME_ENGINE_ACTIVATION_FAILED = [31, 'ime engine activation failed']
68  INVALID_SELECTOR = [32, 'invalid selector']
69  MOVE_TARGET_OUT_OF_BOUNDS = [34, 'move target out of bounds']
70  INVALID_XPATH_SELECTOR = [51, 'invalid selector']
71  INVALID_XPATH_SELECTOR_RETURN_TYPER = [52, 'invalid selector']
72  METHOD_NOT_ALLOWED = [405, 'unsupported operation']
73  */
74 
76  {
87  };
88 
89 private:
90  static const int32_t LONG_PRESS_ACTION_DELAY = YI_LONG_PRESS_DELAY * 2;
91 
92  /*
93  \details
94  https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/Keys.html
95 
96  "Representations of pressable keys that aren't text."
97  */
98  enum WEB_DRIVER_KEY_CODE
99  {
100  NULL_KEY = 128,
101  CANCEL,
102  HELP,
103  BACKSPACE,
104  TAB,
105  CLEAR,
106  RETURN,
107  ENTER,
108  SHIFT,
109  CONTROL,
110  ALT,
111  PAUSE,
112  ESCAPE,
113  SPACE,
114  PAGE_UP,
115  PAGE_DOWN,
116  END,
117  HOME,
118  ARROW_LEFT,
119  ARROW_UP,
120  ARROW_RIGHT,
121  ARROW_DOWN,
122  INSERT,
123  DELETE_KEY,
124  SEMI_COLON,
125  EQUALS,
126  NUMPAD_0,
127  NUMPAD_1,
128  NUMPAD_2,
129  NUMPAD_3,
130  NUMPAD_4,
131  NUMPAD_5,
132  NUMPAD_6,
133  NUMPAD_7,
134  NUMPAD_8,
135  NUMPAD_9,
136  MULTIPLY,
137  ADD,
138  SEPARATOR,
139  SUBTRACT,
140  DECIMAL,
141  DIVIDE,//169
142 
143  F1 = 177,
144  F2,
145  F3,
146  F4,
147  F5,
148  F6,
149  F7,
150  F8,
151  F9,
152  F10,
153  F11,
154  F12,
155  META,
156 
157  KEY_CODE_MAX
158  };
159 
160  enum GET_NODE_STRATEGY
161  {
162  GET_NODE_BY_ID = 0,
163  GET_NODE_BY_NAME,
164  GET_NODE_BY_TYPE
165  };
166 
167  enum ATTRIBUTE_TAG
168  {
169  ATTRIBUTE_BOOL, //Attribute contains a bool
170  ATTRIBUTE_FLOAT, //Attribute contains a float
171  ATTRIBUTE_STRING,//Attribute contains a string
172  ATTRIBUTE_NONE};
173 
174  struct AttributeValue
175  {
176  ATTRIBUTE_TAG etag;
177  CYIString value;
178  bool bValue;
179  float fValue;
180 
181  AttributeValue() :
182  etag(ATTRIBUTE_NONE),
183  bValue(false),
184  fValue(0)
185  {
186  }
187  };
188 
189  struct SourceTreeFilter
190  {
191  CYIString attributeType;
192  CYIString attributeValue;
193 
194  SourceTreeFilter()
195  {
196  }
197  };
198 
199  /*
200  \details Parses each key in \a keys into a CYIKeyEvent and adds it to \a rKeysOutput.
201  */
202  static std::vector<std::unique_ptr<CYIKeyEvent>> CreateWebDriverKeyEvents(const CYIString &keys);
203 
204  /*
205  \details Returns a new CYIKeyEvent if \a eKey is a web driver key, otherwise returns null.
206  */
207  static std::unique_ptr<CYIKeyEvent> CreateWebDriverKeyEvent(WEB_DRIVER_KEY_CODE eKey);
208 
209  /*
210  \details Helper method for GetWebDriverKeyEvent(std::vector<CYIKeyEvent *> &rKeysOutput, WEB_DRIVER_KEY_CODE eKey).
211  Return a new CYIEvent::YI_KEY_DOWN with \a eKeyCode, and \a eKeyVaue.
212  */
213  static std::unique_ptr<CYIKeyEvent> CreateWebDriverKeyEvent(YI_KEY_CODE eKeyCode, YI_ASCII_CODE eKeyValue = YI_ASCII_NULL);
214 
215  /*
216  \details Helper method for GetWebDriverKeyEvent(std::vector<CYIKeyEvent *> &rKeysOutput, WEB_DRIVER_KEY_CODE eKey).
217  Returns a new CYIEvent::YI_KEY_INPUT event with the value of \a eKeyValue and CYIKeyEvent::KEY_LOCATION_NUMPAD.
218  */
219  static std::unique_ptr<CYIKeyEvent> CreateNumpadKeyEvent(YI_ASCII_CODE eKeyValue);
220 
221  /*
222  \details Returns a new CYIEvent::YI_KEY_INPUT event with the value of \a key.
223  */
224  static std::unique_ptr<CYIKeyEvent> CreateSimpleKeyEvent(char32_t key);
225 
226  class LongPressGestureHandler : public CYISignalHandler
227  {
228  public:
229  CYISignal<> LongPressComplete;
230  LongPressGestureHandler();
231  void Start(uint64_t uDelayLength);
232 
233  void SetDeltaCoords(const glm::vec3 &deltaCoords);
234  void SetReleaseCoords(const glm::vec3 &releaseCoords);
235  void SetDownCoords(const glm::vec3 &DownCoords);
236 
237  const glm::vec3 & GetDeltaCoords() const;
238  const glm::vec3 & GetReleaseCoords() const;
239  const glm::vec3 & GetDownCoords() const;
240 
241  private:
242  CYITimer m_delayTimer;
243  void OnTimeOut();
244 
245  glm::vec3 m_deltaCoords;
246  glm::vec3 m_releaseCoords;
247  glm::vec3 m_downCoords;
248 
249  };
250 
255  void ReceiveCommand(const CYIString &strCommand);
256  void SendByteResponse(const std::vector<uint8_t> byteData);
257  void SendStringResponse(const CYIString &strData) const;
258  void GetSource();
259  void RetrieveScreenshot();
260 
261  /*
262  \details This will get the width and height of the app surface.
263 
264  The name comes from the WebDriver Wire Protocol and is meant to reflect the browser's window size. In Appium, it represents the app size.
265  */
266  void GetWindowSize();
267 
276  void RespondGetElementByStrategy(GET_NODE_STRATEGY eStrategy, const std::vector<CYIString> &strategyArguments);
277 
286  void RespondGetElementsByStrategy(GET_NODE_STRATEGY eStrategy, const std::vector<CYIString> &strategyArguments);
287 
291  std::list<CYISceneNode *> FindNodesByStrategy(GET_NODE_STRATEGY eStrategy, const CYIString &strategyValue, const CYIString &referenceAddress);
292 
298  void RespondGetAttribute(const std::vector<CYIString> &attributeArguments);
299 
300  RESPONSE_STATUS ValidateAttribute(const CYIString &attributeString);
301 
305  RESPONSE_STATUS FindNodeAttribute(const CYISceneNode *pNode, const CYIString &attributeString, AttributeValue &attributeValue) const;
306 
311  void ClickNode(const std::vector<CYIString> &args);
312 
318  void DoTap(const std::vector<CYIString> &args, bool bLongPress = false);
319 
326  void DoSwipe(const std::vector<CYIString> &args, bool bLongPress = false);
327 
331  void SetSourceTreeFilter(const std::vector<CYIString> &args);
332 
336  void SetTimeDilation(const std::vector<CYIString> &args);
337 
347  void ClearNode(const std::vector<CYIString> &
348  args);
349 
354  void RespondGetText(const std::vector<CYIString> &args);
355 
359  CYIString FindNodeText(const CYISceneNode *pNode) const;
360 
369  void SendKeys(const std::vector<CYIString> &args);
370 
376  void RespondElementEnabled(const std::vector<CYIString> &args);
377 
384  bool IsElementEnabled(const CYISceneNode *pNode) const;
385 
389  bool IsElementFullyDisplayed(const CYISceneNode *pNode) const;
390 
394  bool IsElementHittable(const CYISceneNode *pNode) const;
395 
399  bool IsScrolling(const CYIScrollingView *pScrollingView) const;
400 
404  bool CoordinatesCanHitNode(const CYISceneNode *pNode, const glm::vec3 &coordinates) const;
405 
409  const glm::vec3 GetHitCoordinates(const CYISceneNode *pNode) const;
410 
416  void RespondElementSelected(const std::vector<CYIString> &args);
417 
423  bool IsElementSelected(const CYISceneNode *pNode) const;
424 
430  void RespondElementDisplayed(const std::vector<CYIString> &args) const;
431 
439  bool IsElementDisplayed(const CYISceneNode *pNode) const;
440 
444  bool IsElementOnScreen(const CYISceneNode *pNode) const;
445 
446  /*
447  \details Sends a response back to the client containing the size of the node in screen coordinates.
448 
449  Sends a WEBDRIVER_NO_SUCH_ELEMENT error response if the element ID cannot be found.
450  */
451  void RetrieveNodeSize(const std::vector<CYIString> &args) const;
452 
453  /*
454  \details Sends a response back to the client containing the top left corner of the node in screen coordinates.
455 
456  Sends a WEBDRIVER_NO_SUCH_ELEMENT error response if the element ID cannot be found.
457  */
458  void RetrieveNodeLocation(const std::vector<CYIString> &args) const;
459 
460  // higher-level responses
461  void SendSuccessResponse(yi::rapidjson::Document &responseObject) const;
462  void SendSuccessResponse(const CYIString &returnValue) const;
463  void SendSuccessResponse(bool returnValue) const;
464  void SendSuccessResponse(float returnValue) const;
465  void SendSuccessResponse() const;
466  void SendErrorResponse(RESPONSE_STATUS errorStatus, const CYIString &errorMessage = CYIString()) const;
467 
471  std::list<CYISceneNode*> GetAllNodesWithStrategyValue(GET_NODE_STRATEGY eStrategy, const CYIString &strategyValue);
472 
476  std::list<CYISceneNode*> GetAllNodesWithStrategyValueFromParent(GET_NODE_STRATEGY eStrategy, const CYIString &strategyValue, CYISceneNode *pParentNode);
477 
481  CYIString GetViewTreeSource(const CYISceneNode *pSceneNode, int32_t nIndentLevel = 0) const;
482 
486  CYIString EscapeXMLText(CYIString unescapedText) const;
487 
491  CYISceneNode *GetNodeFromAddressString(const CYIString &argString) const;
492 
497  bool IsDescendantOf(const CYISceneNode *pNode, const CYISceneNode *pParent) const;
498 
503  CYIAABB GetNodeScreenRect(const CYISceneNode *pNode) const;
504 
509  CYIAABB GetNodeMeshScreenRect(const CYISceneNode *pNode) const;
510 
514  CYIAABB GetSurfaceScreenRect() const;
515 
519  bool MatchesAttributeFilter(const CYISceneNode *pNode, const CYIString &attributeType, const CYIString &attributeValue) const;
520 
524  RESPONSE_STATUS ApplyAttributeFilter(std::list<CYISceneNode*> &sceneNodes, const CYIString &attributeType, const CYIString &attributeValue);
525 
533  std::list<CYISceneNode *> GetNodes(CYISceneNode *pSceneNode, const CYIString &propertyName, const CYIString &propertyValue);
534 
538  void GetNodesFromChildren(const CYISceneNode *pSceneNode, const CYIString &propertyName, const CYIString &propertyValue, std::list<CYISceneNode *> &list);
539 
540  void SimulateClick(const glm::vec3 &clickCoords, bool bLongPress = false);
541  void SimulateSwipe(const glm::vec3 &downCoords, const glm::vec3 &deltaCoords, bool bLongPress = false);
542 
543  void OnLongPressUpTimeout();
544  void OnLongPressMoveTimeout();
545 
546  void ActionUp(const glm::vec3 &releaseCoords);
547  void ActionMove(const glm::vec3 &releaseCoords);
548 
549  CYIAppiumTCPServer *m_pServer;
550  LongPressGestureHandler m_longPressHandler;
551  SourceTreeFilter m_sourceTreeFilter;
552 
554 };
555 
556 
561 #endif
#define YI_DISALLOW_COPY_AND_ASSIGN(TypeName)
Delete the copy constructor and assignment operator (and consequently the move constructor as well) ...
Definition: YiPredef.h:114
const int32_t YI_LONG_PRESS_DELAY
Definition: YiSceneManager.h:42
Class for key events.
Definition: YiKeyEvent.h:15
Definition: YiWebDriver.h:86
Definition: YiEvent.h:338
Container class for Unicode strings. Conceptually, a CYIString object is a sequence of Unicode charac...
Definition: YiString.h:35
Definition: YiWebDriver.h:78
YI_KEY_CODE
Key code for CYIKeyEvent events.
Definition: YiEvent.h:81
YI_ASCII_CODE
Ascii codes for key characters.
Definition: YiEvent.h:336
A low-precision timer driven by the update loop.
Definition: YiTimer.h:29
A scene node is the base type for all nodes which are used by the scene manager; it is an integral pa...
Definition: YiSceneNode.h:114
Definition: YiWebDriver.h:85
Definition: YiWebDriver.h:83
CYIWebDriver exposes functionality for the Appium driver to use, using a socket server.
Definition: YiWebDriver.h:28
RESPONSE_STATUS
Definition: YiWebDriver.h:75
Definition: YiSignalHandler.h:174
Definition: YiWebDriver.h:77
This class represents an Axis-Aligned Bounding Box.
Definition: YiAABB.h:24
Allows users to scroll and pan through content inside.
Definition: YiScrollingView.h:140
virtual ~CYIWebDriver()
Definition: YiWebDriver.h:79
Signals and slots are a thread-safe and flexible communication framework that will allow various obje...
Definition: YiSignal.h:164