/src/test-run/commands/actions.js

https://github.com/DevExpress/testcafe · JavaScript · 491 lines · 405 code · 84 blank · 2 comment · 7 complexity · 9a1a87bda3f5b7a30aed7d168d5191df MD5 · raw file

  1. import TYPE from './type';
  2. import SelectorBuilder from '../../client-functions/selectors/selector-builder';
  3. import ClientFunctionBuilder from '../../client-functions/client-function-builder';
  4. import functionBuilderSymbol from '../../client-functions/builder-symbol';
  5. import CommandBase from './base';
  6. import {
  7. ActionOptions,
  8. ClickOptions,
  9. MouseOptions,
  10. TypeOptions,
  11. DragToElementOptions
  12. } from './options';
  13. import { initSelector, initUploadSelector } from './validations/initializers';
  14. import { executeJsExpression } from '../execute-js-expression';
  15. import { isJSExpression } from './utils';
  16. import {
  17. actionOptions,
  18. integerArgument,
  19. positiveIntegerArgument,
  20. stringArgument,
  21. nonEmptyStringArgument,
  22. nullableStringArgument,
  23. urlArgument,
  24. stringOrStringArrayArgument,
  25. setSpeedArgument,
  26. actionRoleArgument,
  27. booleanArgument,
  28. functionArgument
  29. } from './validations/argument';
  30. import { SetNativeDialogHandlerCodeWrongTypeError } from '../../errors/test-run';
  31. import { ExecuteClientFunctionCommand } from './observation';
  32. // Initializers
  33. function initActionOptions (name, val) {
  34. return new ActionOptions(val, true);
  35. }
  36. function initClickOptions (name, val) {
  37. return new ClickOptions(val, true);
  38. }
  39. function initMouseOptions (name, val) {
  40. return new MouseOptions(val, true);
  41. }
  42. function initTypeOptions (name, val) {
  43. return new TypeOptions(val, true);
  44. }
  45. function initDragToElementOptions (name, val) {
  46. return new DragToElementOptions(val, true);
  47. }
  48. function initDialogHandler (name, val, { skipVisibilityCheck, testRun }) {
  49. let fn;
  50. if (isJSExpression(val))
  51. fn = executeJsExpression(val.value, testRun, { skipVisibilityCheck });
  52. else
  53. fn = val.fn;
  54. if (fn === null || fn instanceof ExecuteClientFunctionCommand)
  55. return fn;
  56. const options = val.options;
  57. const methodName = 'setNativeDialogHandler';
  58. const functionType = typeof fn;
  59. let builder = fn && fn[functionBuilderSymbol];
  60. const isSelector = builder instanceof SelectorBuilder;
  61. const isClientFunction = builder instanceof ClientFunctionBuilder;
  62. if (functionType !== 'function' || isSelector)
  63. throw new SetNativeDialogHandlerCodeWrongTypeError(isSelector ? 'Selector' : functionType);
  64. if (isClientFunction)
  65. builder = fn.with(options)[functionBuilderSymbol];
  66. else
  67. builder = new ClientFunctionBuilder(fn, options, { instantiation: methodName, execution: methodName });
  68. return builder.getCommand([]);
  69. }
  70. // Commands
  71. export class ClickCommand extends CommandBase {
  72. constructor (obj, testRun) {
  73. super(obj, testRun, TYPE.click);
  74. }
  75. _getAssignableProperties () {
  76. return [
  77. { name: 'selector', init: initSelector, required: true },
  78. { name: 'options', type: actionOptions, init: initClickOptions, required: true }
  79. ];
  80. }
  81. }
  82. export class RightClickCommand extends CommandBase {
  83. constructor (obj, testRun) {
  84. super(obj, testRun, TYPE.rightClick);
  85. }
  86. _getAssignableProperties () {
  87. return [
  88. { name: 'selector', init: initSelector, required: true },
  89. { name: 'options', type: actionOptions, init: initClickOptions, required: true }
  90. ];
  91. }
  92. }
  93. export class ExecuteExpressionCommand extends CommandBase {
  94. constructor (obj, testRun) {
  95. super(obj, testRun, TYPE.executeExpression);
  96. }
  97. _getAssignableProperties () {
  98. return [
  99. { name: 'expression', type: nonEmptyStringArgument, required: true },
  100. { name: 'resultVariableName', type: nonEmptyStringArgument, defaultValue: null }
  101. ];
  102. }
  103. }
  104. export class ExecuteAsyncExpressionCommand extends CommandBase {
  105. constructor (obj, testRun) {
  106. super(obj, testRun, TYPE.executeAsyncExpression);
  107. }
  108. _getAssignableProperties () {
  109. return [
  110. { name: 'expression', type: stringArgument, required: true }
  111. ];
  112. }
  113. }
  114. export class DoubleClickCommand extends CommandBase {
  115. constructor (obj, testRun) {
  116. super(obj, testRun, TYPE.doubleClick);
  117. }
  118. _getAssignableProperties () {
  119. return [
  120. { name: 'selector', init: initSelector, required: true },
  121. { name: 'options', type: actionOptions, init: initClickOptions, required: true }
  122. ];
  123. }
  124. }
  125. export class HoverCommand extends CommandBase {
  126. constructor (obj, testRun) {
  127. super(obj, testRun, TYPE.hover);
  128. }
  129. _getAssignableProperties () {
  130. return [
  131. { name: 'selector', init: initSelector, required: true },
  132. { name: 'options', type: actionOptions, init: initMouseOptions, required: true }
  133. ];
  134. }
  135. }
  136. export class TypeTextCommand extends CommandBase {
  137. constructor (obj, testRun) {
  138. super(obj, testRun, TYPE.typeText);
  139. }
  140. _getAssignableProperties () {
  141. return [
  142. { name: 'selector', init: initSelector, required: true },
  143. { name: 'text', type: nonEmptyStringArgument, required: true },
  144. { name: 'options', type: actionOptions, init: initTypeOptions, required: true }
  145. ];
  146. }
  147. }
  148. export class DragCommand extends CommandBase {
  149. constructor (obj, testRun) {
  150. super(obj, testRun, TYPE.drag);
  151. }
  152. _getAssignableProperties () {
  153. return [
  154. { name: 'selector', init: initSelector, required: true },
  155. { name: 'dragOffsetX', type: integerArgument, required: true },
  156. { name: 'dragOffsetY', type: integerArgument, required: true },
  157. { name: 'options', type: actionOptions, init: initMouseOptions, required: true }
  158. ];
  159. }
  160. }
  161. export class DragToElementCommand extends CommandBase {
  162. constructor (obj, testRun) {
  163. super(obj, testRun, TYPE.dragToElement);
  164. }
  165. _getAssignableProperties () {
  166. return [
  167. { name: 'selector', init: initSelector, required: true },
  168. { name: 'destinationSelector', init: initSelector, required: true },
  169. { name: 'options', type: actionOptions, init: initDragToElementOptions, required: true }
  170. ];
  171. }
  172. }
  173. export class SelectTextCommand extends CommandBase {
  174. constructor (obj, testRun) {
  175. super(obj, testRun, TYPE.selectText);
  176. }
  177. _getAssignableProperties () {
  178. return [
  179. { name: 'selector', init: initSelector, required: true },
  180. { name: 'startPos', type: positiveIntegerArgument, defaultValue: null },
  181. { name: 'endPos', type: positiveIntegerArgument, defaultValue: null },
  182. { name: 'options', type: actionOptions, init: initActionOptions, required: true }
  183. ];
  184. }
  185. }
  186. export class SelectEditableContentCommand extends CommandBase {
  187. constructor (obj, testRun) {
  188. super(obj, testRun, TYPE.selectEditableContent);
  189. }
  190. _getAssignableProperties () {
  191. return [
  192. { name: 'startSelector', init: initSelector, required: true },
  193. { name: 'endSelector', init: initSelector, defaultValue: null },
  194. { name: 'options', type: actionOptions, init: initActionOptions, required: true }
  195. ];
  196. }
  197. }
  198. export class SelectTextAreaContentCommand extends CommandBase {
  199. constructor (obj, testRun) {
  200. super(obj, testRun, TYPE.selectTextAreaContent);
  201. }
  202. _getAssignableProperties () {
  203. return [
  204. { name: 'selector', init: initSelector, required: true },
  205. { name: 'startLine', type: positiveIntegerArgument, defaultValue: null },
  206. { name: 'startPos', type: positiveIntegerArgument, defaultValue: null },
  207. { name: 'endLine', type: positiveIntegerArgument, defaultValue: null },
  208. { name: 'endPos', type: positiveIntegerArgument, defaultValue: null },
  209. { name: 'options', type: actionOptions, init: initActionOptions, required: true }
  210. ];
  211. }
  212. }
  213. export class PressKeyCommand extends CommandBase {
  214. constructor (obj, testRun) {
  215. super(obj, testRun, TYPE.pressKey);
  216. }
  217. _getAssignableProperties () {
  218. return [
  219. { name: 'keys', type: nonEmptyStringArgument, required: true },
  220. { name: 'options', type: actionOptions, init: initActionOptions, required: true }
  221. ];
  222. }
  223. }
  224. export class NavigateToCommand extends CommandBase {
  225. constructor (obj, testRun) {
  226. super(obj, testRun, TYPE.navigateTo);
  227. }
  228. _getAssignableProperties () {
  229. return [
  230. { name: 'url', type: urlArgument, required: true },
  231. { name: 'stateSnapshot', type: nullableStringArgument, defaultValue: null },
  232. { name: 'forceReload', type: booleanArgument, defaultValue: false }
  233. ];
  234. }
  235. }
  236. export class SetFilesToUploadCommand extends CommandBase {
  237. constructor (obj, testRun) {
  238. super(obj, testRun, TYPE.setFilesToUpload);
  239. }
  240. _getAssignableProperties () {
  241. return [
  242. { name: 'selector', init: initUploadSelector, required: true },
  243. { name: 'filePath', type: stringOrStringArrayArgument, required: true }
  244. ];
  245. }
  246. }
  247. export class ClearUploadCommand extends CommandBase {
  248. constructor (obj, testRun) {
  249. super(obj, testRun, TYPE.clearUpload);
  250. }
  251. _getAssignableProperties () {
  252. return [
  253. { name: 'selector', init: initUploadSelector, required: true }
  254. ];
  255. }
  256. }
  257. export class SwitchToIframeCommand extends CommandBase {
  258. constructor (obj, testRun) {
  259. super(obj, testRun, TYPE.switchToIframe);
  260. }
  261. _getAssignableProperties () {
  262. return [
  263. { name: 'selector', init: initSelector, required: true }
  264. ];
  265. }
  266. }
  267. export class SwitchToMainWindowCommand {
  268. constructor () {
  269. this.type = TYPE.switchToMainWindow;
  270. }
  271. }
  272. export class OpenWindowCommand extends CommandBase {
  273. constructor (obj, testRun) {
  274. super(obj, testRun, TYPE.openWindow);
  275. }
  276. _getAssignableProperties () {
  277. return [
  278. { name: 'url', type: urlArgument },
  279. ];
  280. }
  281. }
  282. export class CloseWindowCommand extends CommandBase {
  283. constructor (obj, testRun) {
  284. super(obj, testRun, TYPE.closeWindow);
  285. }
  286. _getAssignableProperties () {
  287. return [
  288. { name: 'windowId', type: nullableStringArgument, required: true },
  289. ];
  290. }
  291. }
  292. export class GetCurrentWindowCommand extends CommandBase {
  293. constructor (obj, testRun) {
  294. super(obj, testRun, TYPE.getCurrentWindow);
  295. }
  296. _getAssignableProperties () {
  297. return [
  298. ];
  299. }
  300. }
  301. export class GetCurrentWindowsCommand extends CommandBase {
  302. constructor (obj, testRun) {
  303. super(obj, testRun, TYPE.getCurrentWindows);
  304. }
  305. _getAssignableProperties () {
  306. return [
  307. ];
  308. }
  309. }
  310. export class SwitchToWindowCommand extends CommandBase {
  311. constructor (obj, testRun) {
  312. super(obj, testRun, TYPE.switchToWindow);
  313. }
  314. _getAssignableProperties () {
  315. return [
  316. { name: 'windowId', type: nonEmptyStringArgument, required: true }
  317. ];
  318. }
  319. }
  320. export class SwitchToWindowByPredicateCommand extends CommandBase {
  321. constructor (obj, testRun) {
  322. super(obj, testRun, TYPE.switchToWindowByPredicate);
  323. }
  324. _getAssignableProperties () {
  325. return [
  326. { name: 'findWindow', type: functionArgument, required: true }
  327. ];
  328. }
  329. }
  330. export class SwitchToParentWindowCommand extends CommandBase {
  331. constructor (obj, testRun) {
  332. super(obj, testRun, TYPE.switchToParentWindow);
  333. }
  334. _getAssignableProperties () {
  335. return [
  336. ];
  337. }
  338. }
  339. export class SwitchToPreviousWindowCommand extends CommandBase {
  340. constructor (obj, testRun) {
  341. super(obj, testRun, TYPE.switchToPreviousWindow);
  342. }
  343. _getAssignableProperties () {
  344. return [];
  345. }
  346. }
  347. export class SetNativeDialogHandlerCommand extends CommandBase {
  348. constructor (obj, testRun) {
  349. super(obj, testRun, TYPE.setNativeDialogHandler);
  350. }
  351. _getAssignableProperties () {
  352. return [
  353. { name: 'dialogHandler', init: initDialogHandler, required: true }
  354. ];
  355. }
  356. }
  357. export class GetNativeDialogHistoryCommand {
  358. constructor () {
  359. this.type = TYPE.getNativeDialogHistory;
  360. }
  361. }
  362. export class GetBrowserConsoleMessagesCommand {
  363. constructor () {
  364. this.type = TYPE.getBrowserConsoleMessages;
  365. }
  366. }
  367. export class SetTestSpeedCommand extends CommandBase {
  368. constructor (obj, testRun) {
  369. super(obj, testRun, TYPE.setTestSpeed);
  370. }
  371. _getAssignableProperties () {
  372. return [
  373. { name: 'speed', type: setSpeedArgument, required: true }
  374. ];
  375. }
  376. }
  377. export class SetPageLoadTimeoutCommand extends CommandBase {
  378. constructor (obj, testRun) {
  379. super(obj, testRun, TYPE.setPageLoadTimeout);
  380. }
  381. _getAssignableProperties () {
  382. return [
  383. { name: 'duration', type: positiveIntegerArgument, required: true }
  384. ];
  385. }
  386. }
  387. export class UseRoleCommand extends CommandBase {
  388. constructor (obj, testRun) {
  389. super(obj, testRun, TYPE.useRole);
  390. }
  391. _getAssignableProperties () {
  392. return [
  393. { name: 'role', type: actionRoleArgument, required: true }
  394. ];
  395. }
  396. }
  397. export class RecorderCommand extends CommandBase {
  398. constructor (obj, testRun) {
  399. super(obj, testRun, TYPE.recorder);
  400. }
  401. _getAssignableProperties () {
  402. return [
  403. { name: 'subtype', type: nonEmptyStringArgument, required: true },
  404. { name: 'forceExecutionInTopWindowOnly', type: booleanArgument, defaultValue: false }
  405. ];
  406. }
  407. }