webdriver_commands.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. /**
  4. * Utilities for parsing WebDriver commands from HTTP Requests.
  5. */
  6. const events = require("events");
  7. var CommandName;
  8. (function (CommandName) {
  9. CommandName[CommandName["NewSession"] = 0] = "NewSession";
  10. CommandName[CommandName["DeleteSession"] = 1] = "DeleteSession";
  11. CommandName[CommandName["Status"] = 2] = "Status";
  12. CommandName[CommandName["GetTimeouts"] = 3] = "GetTimeouts";
  13. CommandName[CommandName["SetTimeouts"] = 4] = "SetTimeouts";
  14. CommandName[CommandName["Go"] = 5] = "Go";
  15. CommandName[CommandName["GetCurrentURL"] = 6] = "GetCurrentURL";
  16. CommandName[CommandName["Back"] = 7] = "Back";
  17. CommandName[CommandName["Forward"] = 8] = "Forward";
  18. CommandName[CommandName["Refresh"] = 9] = "Refresh";
  19. CommandName[CommandName["GetTitle"] = 10] = "GetTitle";
  20. CommandName[CommandName["FindElement"] = 11] = "FindElement";
  21. CommandName[CommandName["FindElements"] = 12] = "FindElements";
  22. CommandName[CommandName["FindElementFromElement"] = 13] = "FindElementFromElement";
  23. CommandName[CommandName["FindElementsFromElement"] = 14] = "FindElementsFromElement";
  24. CommandName[CommandName["IsElementSelected"] = 15] = "IsElementSelected";
  25. CommandName[CommandName["GetElementAttribute"] = 16] = "GetElementAttribute";
  26. CommandName[CommandName["GetElementProperty"] = 17] = "GetElementProperty";
  27. CommandName[CommandName["GetElementCSSValue"] = 18] = "GetElementCSSValue";
  28. CommandName[CommandName["GetElementText"] = 19] = "GetElementText";
  29. CommandName[CommandName["GetElementTagName"] = 20] = "GetElementTagName";
  30. CommandName[CommandName["GetElementRect"] = 21] = "GetElementRect";
  31. CommandName[CommandName["IsElementEnabled"] = 22] = "IsElementEnabled";
  32. CommandName[CommandName["ElementClick"] = 23] = "ElementClick";
  33. CommandName[CommandName["ElementClear"] = 24] = "ElementClear";
  34. CommandName[CommandName["ElementSendKeys"] = 25] = "ElementSendKeys";
  35. CommandName[CommandName["WireMoveTo"] = 26] = "WireMoveTo";
  36. CommandName[CommandName["WireButtonDown"] = 27] = "WireButtonDown";
  37. CommandName[CommandName["WireButtonUp"] = 28] = "WireButtonUp";
  38. CommandName[CommandName["GetAlertText"] = 29] = "GetAlertText";
  39. CommandName[CommandName["AcceptAlert"] = 30] = "AcceptAlert";
  40. CommandName[CommandName["DismissAlert"] = 31] = "DismissAlert";
  41. CommandName[CommandName["UNKNOWN"] = 32] = "UNKNOWN";
  42. })(CommandName = exports.CommandName || (exports.CommandName = {}));
  43. /**
  44. * Represents an endpoint in the WebDriver spec. Endpoints are defined by
  45. * the CommandName enum and the url pattern that they match.
  46. *
  47. * For example, the pattern
  48. * /session/:sessionId/element/:elementId/click
  49. * will match urls such as
  50. * /session/d9e52b96-9b6a-4cb3-b017-76e8b4236646/element/1c2855ba-213d-4466-ba16-b14a7e6c3699/click
  51. *
  52. * @param pattern The url pattern
  53. * @param method The HTTP method, ie GET, POST, DELETE
  54. * @param name The CommandName of this endpoint.
  55. */
  56. class Endpoint {
  57. constructor(pattern, method, name) {
  58. this.pattern = pattern;
  59. this.method = method;
  60. this.name = name;
  61. }
  62. /**
  63. * Tests whether a given url from a request matches this endpoint.
  64. *
  65. * @param url A url from a request to test against the endpoint.
  66. * @param method The HTTP method.
  67. * @returns {boolean} Whether the endpoint matches.
  68. */
  69. matches(url, method) {
  70. let urlParts = url.split('/');
  71. let patternParts = this.pattern.split('/');
  72. if (method != this.method || urlParts.length != patternParts.length) {
  73. return false;
  74. }
  75. // TODO: Replace this naive search with better parsing.
  76. for (let idx in patternParts) {
  77. if (!patternParts[idx].startsWith(':') && patternParts[idx] != urlParts[idx]) {
  78. return false;
  79. }
  80. }
  81. return true;
  82. }
  83. /**
  84. * Given a url from a http request, create an object containing parameters from the URL.
  85. *
  86. * Parameters are the parts of the endpoint's pattern that start with ':'. The ':' is dropped
  87. * from the parameter key.
  88. *
  89. * @param url The url from the request.
  90. * @returns An object mapping parameter keys to values from the url.
  91. */
  92. getParams(url) {
  93. let urlParts = url.split('/');
  94. let patternParts = this.pattern.split('/');
  95. let params = {};
  96. for (let idx in patternParts) {
  97. if (patternParts[idx].startsWith(':')) {
  98. let paramName = patternParts[idx].slice(1);
  99. params[paramName] = urlParts[idx];
  100. }
  101. }
  102. return params;
  103. }
  104. }
  105. /**
  106. * An instance of a WebDriver command, containing the params and data for that request.
  107. *
  108. * @param commandName The enum identifying the command.
  109. * @param params Parameters for the command taken from the request's url.
  110. * @param data Optional data included with the command, taken from the body of the request.
  111. */
  112. class WebDriverCommand extends events.EventEmitter {
  113. constructor(commandName, url, method, params) {
  114. super();
  115. this.commandName = commandName;
  116. this.url = url;
  117. this.method = method;
  118. this.params = params;
  119. }
  120. // All WebDriver commands have a session Id, except for two.
  121. // NewSession will have a session Id in the data
  122. // Status just doesn't
  123. get sessionId() {
  124. if (!this.getParam('sessionId') && this.url.startsWith('/session')) {
  125. return this.url.split('/')[2];
  126. }
  127. return this.getParam('sessionId');
  128. }
  129. getParam(key) {
  130. return this.params[key];
  131. }
  132. handleData(data) {
  133. try {
  134. this.data = JSON.parse(data);
  135. }
  136. catch (err) {
  137. this.data = data;
  138. }
  139. this.emit('data');
  140. }
  141. handleResponse(statusCode, data) {
  142. this.responseStatus = statusCode;
  143. try {
  144. this.responseData = JSON.parse(data);
  145. }
  146. catch (err) {
  147. this.responseData = data;
  148. }
  149. this.emit('response');
  150. }
  151. }
  152. exports.WebDriverCommand = WebDriverCommand;
  153. /**
  154. * The set of known endpoints.
  155. */
  156. let endpoints = [];
  157. function addWebDriverCommand(command, method, pattern) {
  158. endpoints.push(new Endpoint(pattern, method, command));
  159. }
  160. /**
  161. * Returns a new WebdriverCommand object for the resource at the given URL.
  162. */
  163. function parseWebDriverCommand(url, method) {
  164. for (let endpoint of endpoints) {
  165. if (endpoint.matches(url, method)) {
  166. let params = endpoint.getParams(url);
  167. return new WebDriverCommand(endpoint.name, url, method, params);
  168. }
  169. }
  170. return new WebDriverCommand(CommandName.UNKNOWN, url, method, {});
  171. }
  172. exports.parseWebDriverCommand = parseWebDriverCommand;
  173. let sessionPrefix = '/session/:sessionId';
  174. addWebDriverCommand(CommandName.NewSession, 'POST', '/session');
  175. addWebDriverCommand(CommandName.DeleteSession, 'DELETE', '/session/:sessionId');
  176. addWebDriverCommand(CommandName.Status, 'GET', '/status');
  177. addWebDriverCommand(CommandName.GetTimeouts, 'GET', sessionPrefix + '/timeouts');
  178. addWebDriverCommand(CommandName.SetTimeouts, 'POST', sessionPrefix + '/timeouts');
  179. addWebDriverCommand(CommandName.Go, 'POST', sessionPrefix + '/url');
  180. addWebDriverCommand(CommandName.GetCurrentURL, 'GET', sessionPrefix + '/url');
  181. addWebDriverCommand(CommandName.Back, 'POST', sessionPrefix + '/back');
  182. addWebDriverCommand(CommandName.Forward, 'POST', sessionPrefix + '/forward');
  183. addWebDriverCommand(CommandName.Refresh, 'POST', sessionPrefix + '/refresh');
  184. addWebDriverCommand(CommandName.GetTitle, 'GET', sessionPrefix + '/title');
  185. addWebDriverCommand(CommandName.FindElement, 'POST', sessionPrefix + '/element');
  186. addWebDriverCommand(CommandName.FindElements, 'POST', sessionPrefix + '/elements');
  187. addWebDriverCommand(CommandName.FindElementFromElement, 'POST', sessionPrefix + '/element/:elementId/element');
  188. addWebDriverCommand(CommandName.FindElementsFromElement, 'POST', sessionPrefix + '/element/:elementId/elements');
  189. addWebDriverCommand(CommandName.IsElementSelected, 'POST', sessionPrefix + '/element/:elementId/selected');
  190. addWebDriverCommand(CommandName.GetElementAttribute, 'GET', sessionPrefix + '/element/:elementId/attribute/:attributeName');
  191. addWebDriverCommand(CommandName.GetElementProperty, 'GET', sessionPrefix + '/element/:elementId/property/:propertyName');
  192. addWebDriverCommand(CommandName.GetElementCSSValue, 'GET', sessionPrefix + '/element/:elementId/css/:cssPropertyName');
  193. addWebDriverCommand(CommandName.GetElementText, 'GET', sessionPrefix + '/element/:elementId/text');
  194. addWebDriverCommand(CommandName.GetElementTagName, 'GET', sessionPrefix + '/element/:elementId/name');
  195. addWebDriverCommand(CommandName.GetElementRect, 'GET', sessionPrefix + '/element/:elementId/rect');
  196. addWebDriverCommand(CommandName.GetElementRect, 'GET', sessionPrefix + '/element/:elementId/size');
  197. addWebDriverCommand(CommandName.IsElementEnabled, 'GET', sessionPrefix + '/element/:elementId/enabled');
  198. addWebDriverCommand(CommandName.ElementClick, 'POST', sessionPrefix + '/element/:elementId/click');
  199. addWebDriverCommand(CommandName.ElementClear, 'POST', sessionPrefix + '/element/:elementId/clear');
  200. addWebDriverCommand(CommandName.ElementSendKeys, 'POST', sessionPrefix + '/element/:elementId/value');
  201. addWebDriverCommand(CommandName.GetAlertText, 'GET', sessionPrefix + '/alert_text');
  202. addWebDriverCommand(CommandName.GetAlertText, 'GET', sessionPrefix + '/alert/text');
  203. addWebDriverCommand(CommandName.AcceptAlert, 'POST', sessionPrefix + '/alert/accept');
  204. addWebDriverCommand(CommandName.AcceptAlert, 'POST', sessionPrefix + '/accept_alert');
  205. addWebDriverCommand(CommandName.DismissAlert, 'POST', sessionPrefix + '/alert/dismiss');
  206. addWebDriverCommand(CommandName.DismissAlert, 'POST', sessionPrefix + '/dismiss_alert');
  207. // These commands are part of the JSON protocol, and were replaced by Perform Actions in the W3C
  208. // spec
  209. addWebDriverCommand(CommandName.WireMoveTo, 'POST', sessionPrefix + '/moveto');
  210. addWebDriverCommand(CommandName.WireButtonDown, 'POST', sessionPrefix + '/buttondown');
  211. addWebDriverCommand(CommandName.WireButtonUp, 'POST', sessionPrefix + '/buttonup');
  212. //# sourceMappingURL=webdriver_commands.js.map