octoparse-cli 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +271 -0
  2. package/RUNTIME_SECURITY_NOTICE.txt +41 -0
  3. package/SECURITY.md +24 -0
  4. package/dist/cli/args.js +34 -0
  5. package/dist/cli/help.js +214 -0
  6. package/dist/cli/output.js +39 -0
  7. package/dist/commands/auth.js +283 -0
  8. package/dist/commands/capabilities.js +118 -0
  9. package/dist/commands/cloud.js +241 -0
  10. package/dist/commands/data.js +220 -0
  11. package/dist/commands/doctor.js +73 -0
  12. package/dist/commands/env.js +63 -0
  13. package/dist/commands/local.js +251 -0
  14. package/dist/commands/run.js +622 -0
  15. package/dist/commands/runs.js +171 -0
  16. package/dist/commands/task.js +101 -0
  17. package/dist/index.js +133 -0
  18. package/dist/runtime/account-capabilities.js +71 -0
  19. package/dist/runtime/api-client.js +290 -0
  20. package/dist/runtime/artifacts.js +33 -0
  21. package/dist/runtime/auth.js +94 -0
  22. package/dist/runtime/bridge-hub.js +173 -0
  23. package/dist/runtime/client-headers.js +23 -0
  24. package/dist/runtime/cloud-data.js +75 -0
  25. package/dist/runtime/config.js +48 -0
  26. package/dist/runtime/data-exporter.js +267 -0
  27. package/dist/runtime/engine-host.js +449 -0
  28. package/dist/runtime/local-runs.js +92 -0
  29. package/dist/runtime/naming.js +13 -0
  30. package/dist/runtime/run-control.js +363 -0
  31. package/dist/runtime/run-services.js +380 -0
  32. package/dist/runtime/security-notice.js +78 -0
  33. package/dist/runtime/task-definition-provider.js +282 -0
  34. package/dist/types.js +4 -0
  35. package/examples/minimal-task.json +6 -0
  36. package/examples/navigate-example-task.json +6 -0
  37. package/node_modules/@octopus/bpmn/index.js +3 -0
  38. package/node_modules/@octopus/bpmn/lib/Context.js +245 -0
  39. package/node_modules/@octopus/bpmn/lib/Definition.js +258 -0
  40. package/node_modules/@octopus/bpmn/lib/Engine.js +275 -0
  41. package/node_modules/@octopus/bpmn/lib/PrematureStopError.js +7 -0
  42. package/node_modules/@octopus/bpmn/lib/activities/Activity.js +202 -0
  43. package/node_modules/@octopus/bpmn/lib/activities/BaseProcess.js +308 -0
  44. package/node_modules/@octopus/bpmn/lib/activities/BaseTask.js +145 -0
  45. package/node_modules/@octopus/bpmn/lib/activities/BoundaryEvent.js +12 -0
  46. package/node_modules/@octopus/bpmn/lib/activities/Dummy.js +10 -0
  47. package/node_modules/@octopus/bpmn/lib/activities/EventDefinition.js +99 -0
  48. package/node_modules/@octopus/bpmn/lib/activities/Flow.js +52 -0
  49. package/node_modules/@octopus/bpmn/lib/activities/Form.js +67 -0
  50. package/node_modules/@octopus/bpmn/lib/activities/InputOutput.js +53 -0
  51. package/node_modules/@octopus/bpmn/lib/activities/IntermediateCatchEvent.js +12 -0
  52. package/node_modules/@octopus/bpmn/lib/activities/MessageFlow.js +19 -0
  53. package/node_modules/@octopus/bpmn/lib/activities/MultiInstanceLoopCharacteristics.js +160 -0
  54. package/node_modules/@octopus/bpmn/lib/activities/Properties.js +27 -0
  55. package/node_modules/@octopus/bpmn/lib/activities/SequenceFlow.js +56 -0
  56. package/node_modules/@octopus/bpmn/lib/activities/ServiceConnector.js +71 -0
  57. package/node_modules/@octopus/bpmn/lib/context-helper.js +198 -0
  58. package/node_modules/@octopus/bpmn/lib/events/EndEvent.js +22 -0
  59. package/node_modules/@octopus/bpmn/lib/events/ErrorEvent.js +41 -0
  60. package/node_modules/@octopus/bpmn/lib/events/MessageEvent.js +19 -0
  61. package/node_modules/@octopus/bpmn/lib/events/StartEvent.js +55 -0
  62. package/node_modules/@octopus/bpmn/lib/events/TimerEvent.js +75 -0
  63. package/node_modules/@octopus/bpmn/lib/expressions.js +41 -0
  64. package/node_modules/@octopus/bpmn/lib/gateways/ExclusiveGateway.js +86 -0
  65. package/node_modules/@octopus/bpmn/lib/gateways/InclusiveGateway.js +56 -0
  66. package/node_modules/@octopus/bpmn/lib/gateways/ParallelGateway.js +195 -0
  67. package/node_modules/@octopus/bpmn/lib/getPropertyValue.js +83 -0
  68. package/node_modules/@octopus/bpmn/lib/index.js +6 -0
  69. package/node_modules/@octopus/bpmn/lib/mapper.js +55 -0
  70. package/node_modules/@octopus/bpmn/lib/parameter.js +119 -0
  71. package/node_modules/@octopus/bpmn/lib/script-helper.js +45 -0
  72. package/node_modules/@octopus/bpmn/lib/tasks/ManualTask.js +31 -0
  73. package/node_modules/@octopus/bpmn/lib/tasks/ReceiveTask.js +31 -0
  74. package/node_modules/@octopus/bpmn/lib/tasks/ScriptTask.js +35 -0
  75. package/node_modules/@octopus/bpmn/lib/tasks/SendTask.js +16 -0
  76. package/node_modules/@octopus/bpmn/lib/tasks/ServiceTask.js +68 -0
  77. package/node_modules/@octopus/bpmn/lib/tasks/SubProcess.js +17 -0
  78. package/node_modules/@octopus/bpmn/lib/tasks/Task.js +16 -0
  79. package/node_modules/@octopus/bpmn/lib/tasks/UserTask.js +47 -0
  80. package/node_modules/@octopus/bpmn/lib/transformer.js +13 -0
  81. package/node_modules/@octopus/bpmn/lib/validation.js +111 -0
  82. package/node_modules/@octopus/bpmn/package.json +17 -0
  83. package/node_modules/@octopus/bpmn/types/bpmn.d.ts +85 -0
  84. package/node_modules/@octopus/engine/README.md +370 -0
  85. package/node_modules/@octopus/engine/dist/actions/BackPreWebPageAction.d.ts +4 -0
  86. package/node_modules/@octopus/engine/dist/actions/BackPreWebPageAction.js +1 -0
  87. package/node_modules/@octopus/engine/dist/actions/BaseAction.d.ts +339 -0
  88. package/node_modules/@octopus/engine/dist/actions/BaseAction.js +1559 -0
  89. package/node_modules/@octopus/engine/dist/actions/BranchAction.d.ts +9 -0
  90. package/node_modules/@octopus/engine/dist/actions/BranchAction.js +1 -0
  91. package/node_modules/@octopus/engine/dist/actions/ClickAction.d.ts +22 -0
  92. package/node_modules/@octopus/engine/dist/actions/ClickAction.js +1 -0
  93. package/node_modules/@octopus/engine/dist/actions/ConditionAction.d.ts +4 -0
  94. package/node_modules/@octopus/engine/dist/actions/ConditionAction.js +1 -0
  95. package/node_modules/@octopus/engine/dist/actions/EmptyAction.d.ts +4 -0
  96. package/node_modules/@octopus/engine/dist/actions/EmptyAction.js +12 -0
  97. package/node_modules/@octopus/engine/dist/actions/EnterCaptchaAction.d.ts +28 -0
  98. package/node_modules/@octopus/engine/dist/actions/EnterCaptchaAction.js +1 -0
  99. package/node_modules/@octopus/engine/dist/actions/EnterTextAction.d.ts +20 -0
  100. package/node_modules/@octopus/engine/dist/actions/EnterTextAction.js +1 -0
  101. package/node_modules/@octopus/engine/dist/actions/ExtractDataAction.d.ts +40 -0
  102. package/node_modules/@octopus/engine/dist/actions/ExtractDataAction.js +1 -0
  103. package/node_modules/@octopus/engine/dist/actions/LoopAction.d.ts +41 -0
  104. package/node_modules/@octopus/engine/dist/actions/LoopAction.js +526 -0
  105. package/node_modules/@octopus/engine/dist/actions/LoopStartAction.d.ts +47 -0
  106. package/node_modules/@octopus/engine/dist/actions/LoopStartAction.js +607 -0
  107. package/node_modules/@octopus/engine/dist/actions/MouseOverAction.d.ts +8 -0
  108. package/node_modules/@octopus/engine/dist/actions/MouseOverAction.js +34 -0
  109. package/node_modules/@octopus/engine/dist/actions/NavigateAction.d.ts +38 -0
  110. package/node_modules/@octopus/engine/dist/actions/NavigateAction.js +535 -0
  111. package/node_modules/@octopus/engine/dist/actions/SwitchComboAction.d.ts +13 -0
  112. package/node_modules/@octopus/engine/dist/actions/SwitchComboAction.js +69 -0
  113. package/node_modules/@octopus/engine/dist/browser.d.ts +17 -0
  114. package/node_modules/@octopus/engine/dist/browser.js +157 -0
  115. package/node_modules/@octopus/engine/dist/browserProxy.d.ts +90 -0
  116. package/node_modules/@octopus/engine/dist/browserProxy.js +1 -0
  117. package/node_modules/@octopus/engine/dist/configs/BaseConfig.d.ts +20 -0
  118. package/node_modules/@octopus/engine/dist/configs/BaseConfig.js +88 -0
  119. package/node_modules/@octopus/engine/dist/configs/BranchConfig.d.ts +7 -0
  120. package/node_modules/@octopus/engine/dist/configs/BranchConfig.js +1 -0
  121. package/node_modules/@octopus/engine/dist/configs/ClickConfig.d.ts +36 -0
  122. package/node_modules/@octopus/engine/dist/configs/ClickConfig.js +65 -0
  123. package/node_modules/@octopus/engine/dist/configs/EnterCaptchaConfig.d.ts +19 -0
  124. package/node_modules/@octopus/engine/dist/configs/EnterCaptchaConfig.js +25 -0
  125. package/node_modules/@octopus/engine/dist/configs/EnterTextConfig.d.ts +24 -0
  126. package/node_modules/@octopus/engine/dist/configs/EnterTextConfig.js +36 -0
  127. package/node_modules/@octopus/engine/dist/configs/ExtractDataConfig.d.ts +12 -0
  128. package/node_modules/@octopus/engine/dist/configs/ExtractDataConfig.js +1 -0
  129. package/node_modules/@octopus/engine/dist/configs/LoopConfig.d.ts +25 -0
  130. package/node_modules/@octopus/engine/dist/configs/LoopConfig.js +40 -0
  131. package/node_modules/@octopus/engine/dist/configs/LoopStartConfig.d.ts +4 -0
  132. package/node_modules/@octopus/engine/dist/configs/LoopStartConfig.js +12 -0
  133. package/node_modules/@octopus/engine/dist/configs/MouseOverConfig.d.ts +8 -0
  134. package/node_modules/@octopus/engine/dist/configs/MouseOverConfig.js +15 -0
  135. package/node_modules/@octopus/engine/dist/configs/NavigateConfig.d.ts +41 -0
  136. package/node_modules/@octopus/engine/dist/configs/NavigateConfig.js +121 -0
  137. package/node_modules/@octopus/engine/dist/configs/SwitchComboConfig.d.ts +8 -0
  138. package/node_modules/@octopus/engine/dist/configs/SwitchComboConfig.js +15 -0
  139. package/node_modules/@octopus/engine/dist/enums/index.d.ts +419 -0
  140. package/node_modules/@octopus/engine/dist/enums/index.js +314 -0
  141. package/node_modules/@octopus/engine/dist/extension/BrowserWebSocketTransport-D_zAGZMQ.js +1 -0
  142. package/node_modules/@octopus/engine/dist/extension/LaunchOptions-DxvePrV4.js +6 -0
  143. package/node_modules/@octopus/engine/dist/extension/NodeWebSocketTransport-BTgRVB7Z.js +6 -0
  144. package/node_modules/@octopus/engine/dist/extension/background.js +396 -0
  145. package/node_modules/@octopus/engine/dist/extension/bidi-C_GIZ8Uz.js +131 -0
  146. package/node_modules/@octopus/engine/dist/extension/manifest.json +27 -0
  147. package/node_modules/@octopus/engine/dist/extension/src/content/anti-detection.js +1 -0
  148. package/node_modules/@octopus/engine/dist/extension-bridge/BaseExtensionBridge.d.ts +21 -0
  149. package/node_modules/@octopus/engine/dist/extension-bridge/BaseExtensionBridge.js +117 -0
  150. package/node_modules/@octopus/engine/dist/extension-bridge/SessionExtensionBridge.d.ts +17 -0
  151. package/node_modules/@octopus/engine/dist/extension-bridge/SessionExtensionBridge.js +29 -0
  152. package/node_modules/@octopus/engine/dist/extension-bridge/index.d.ts +2 -0
  153. package/node_modules/@octopus/engine/dist/extension-bridge/index.js +5 -0
  154. package/node_modules/@octopus/engine/dist/extension-bridge/types.d.ts +159 -0
  155. package/node_modules/@octopus/engine/dist/extension-bridge/types.js +5 -0
  156. package/node_modules/@octopus/engine/dist/extensions/ublock-origin/uBlock0.chromium.tar.xz +0 -0
  157. package/node_modules/@octopus/engine/dist/extensions/ublock-origin-lite/uBOLite.chromium.tar.xz +0 -0
  158. package/node_modules/@octopus/engine/dist/index.d.ts +169 -0
  159. package/node_modules/@octopus/engine/dist/index.js +1 -0
  160. package/node_modules/@octopus/engine/dist/models/actionItem.d.ts +16 -0
  161. package/node_modules/@octopus/engine/dist/models/actionItem.js +15 -0
  162. package/node_modules/@octopus/engine/dist/models/conditionCheckArgs.d.ts +11 -0
  163. package/node_modules/@octopus/engine/dist/models/conditionCheckArgs.js +11 -0
  164. package/node_modules/@octopus/engine/dist/models/customizeCookie.d.ts +14 -0
  165. package/node_modules/@octopus/engine/dist/models/customizeCookie.js +6 -0
  166. package/node_modules/@octopus/engine/dist/models/downloadFileConfig.d.ts +17 -0
  167. package/node_modules/@octopus/engine/dist/models/downloadFileConfig.js +26 -0
  168. package/node_modules/@octopus/engine/dist/models/elementNotFoundArgs.d.ts +8 -0
  169. package/node_modules/@octopus/engine/dist/models/elementNotFoundArgs.js +12 -0
  170. package/node_modules/@octopus/engine/dist/models/elementNotFoundError.d.ts +2 -0
  171. package/node_modules/@octopus/engine/dist/models/elementNotFoundError.js +6 -0
  172. package/node_modules/@octopus/engine/dist/models/extractItem.d.ts +37 -0
  173. package/node_modules/@octopus/engine/dist/models/extractItem.js +35 -0
  174. package/node_modules/@octopus/engine/dist/models/extractTemplate.d.ts +11 -0
  175. package/node_modules/@octopus/engine/dist/models/extractTemplate.js +48 -0
  176. package/node_modules/@octopus/engine/dist/models/extractTextItem.d.ts +10 -0
  177. package/node_modules/@octopus/engine/dist/models/extractTextItem.js +17 -0
  178. package/node_modules/@octopus/engine/dist/models/globalConfig.d.ts +5 -0
  179. package/node_modules/@octopus/engine/dist/models/globalConfig.js +1 -0
  180. package/node_modules/@octopus/engine/dist/models/httpHeader.d.ts +4 -0
  181. package/node_modules/@octopus/engine/dist/models/httpHeader.js +10 -0
  182. package/node_modules/@octopus/engine/dist/models/operation.d.ts +27 -0
  183. package/node_modules/@octopus/engine/dist/models/operation.js +242 -0
  184. package/node_modules/@octopus/engine/dist/models/retryCondition.d.ts +7 -0
  185. package/node_modules/@octopus/engine/dist/models/retryCondition.js +10 -0
  186. package/node_modules/@octopus/engine/dist/models/task.d.ts +89 -0
  187. package/node_modules/@octopus/engine/dist/models/task.js +120 -0
  188. package/node_modules/@octopus/engine/dist/models/trigger.d.ts +66 -0
  189. package/node_modules/@octopus/engine/dist/models/trigger.js +117 -0
  190. package/node_modules/@octopus/engine/dist/package.json +26 -0
  191. package/node_modules/@octopus/engine/dist/public-types.d.ts +13 -0
  192. package/node_modules/@octopus/engine/dist/public-types.js +2 -0
  193. package/node_modules/@octopus/engine/dist/settings.d.ts +41 -0
  194. package/node_modules/@octopus/engine/dist/settings.js +20 -0
  195. package/node_modules/@octopus/engine/dist/solvers/captcha/ClickCaptchaSolver.d.ts +6 -0
  196. package/node_modules/@octopus/engine/dist/solvers/captcha/ClickCaptchaSolver.js +1 -0
  197. package/node_modules/@octopus/engine/dist/solvers/captcha/HCaptchaSolver.d.ts +4 -0
  198. package/node_modules/@octopus/engine/dist/solvers/captcha/HCaptchaSolver.js +73 -0
  199. package/node_modules/@octopus/engine/dist/solvers/captcha/ImageCaptchaSolver.d.ts +2 -0
  200. package/node_modules/@octopus/engine/dist/solvers/captcha/ImageCaptchaSolver.js +74 -0
  201. package/node_modules/@octopus/engine/dist/solvers/captcha/RecaptchaSolver.d.ts +9 -0
  202. package/node_modules/@octopus/engine/dist/solvers/captcha/RecaptchaSolver.js +371 -0
  203. package/node_modules/@octopus/engine/dist/solvers/captcha/SliderCaptchaSolver.d.ts +6 -0
  204. package/node_modules/@octopus/engine/dist/solvers/captcha/SliderCaptchaSolver.js +184 -0
  205. package/node_modules/@octopus/engine/dist/solvers/captcha/SlidingTrajectory.d.ts +50 -0
  206. package/node_modules/@octopus/engine/dist/solvers/captcha/SlidingTrajectory.js +125 -0
  207. package/node_modules/@octopus/engine/dist/solvers/captcha/types.d.ts +68 -0
  208. package/node_modules/@octopus/engine/dist/solvers/captcha/types.js +34 -0
  209. package/node_modules/@octopus/engine/dist/solvers/captcha/utils.d.ts +2 -0
  210. package/node_modules/@octopus/engine/dist/solvers/captcha/utils.js +15 -0
  211. package/node_modules/@octopus/engine/dist/translator/actionFactory.d.ts +6 -0
  212. package/node_modules/@octopus/engine/dist/translator/actionFactory.js +1 -0
  213. package/node_modules/@octopus/engine/dist/translator/activityTypeEnum.d.ts +22 -0
  214. package/node_modules/@octopus/engine/dist/translator/activityTypeEnum.js +1 -0
  215. package/node_modules/@octopus/engine/dist/translator/backPreWebPageAction.d.ts +5 -0
  216. package/node_modules/@octopus/engine/dist/translator/backPreWebPageAction.js +1 -0
  217. package/node_modules/@octopus/engine/dist/translator/baseAction.d.ts +31 -0
  218. package/node_modules/@octopus/engine/dist/translator/baseAction.js +1 -0
  219. package/node_modules/@octopus/engine/dist/translator/breakActivity.d.ts +5 -0
  220. package/node_modules/@octopus/engine/dist/translator/breakActivity.js +1 -0
  221. package/node_modules/@octopus/engine/dist/translator/clickAction.d.ts +5 -0
  222. package/node_modules/@octopus/engine/dist/translator/clickAction.js +1 -0
  223. package/node_modules/@octopus/engine/dist/translator/completeWF.d.ts +5 -0
  224. package/node_modules/@octopus/engine/dist/translator/completeWF.js +1 -0
  225. package/node_modules/@octopus/engine/dist/translator/conditionAction.d.ts +6 -0
  226. package/node_modules/@octopus/engine/dist/translator/conditionAction.js +1 -0
  227. package/node_modules/@octopus/engine/dist/translator/emptyAction.d.ts +5 -0
  228. package/node_modules/@octopus/engine/dist/translator/emptyAction.js +1 -0
  229. package/node_modules/@octopus/engine/dist/translator/enterCapachaAction.d.ts +5 -0
  230. package/node_modules/@octopus/engine/dist/translator/enterCapachaAction.js +1 -0
  231. package/node_modules/@octopus/engine/dist/translator/enterTextAction.d.ts +5 -0
  232. package/node_modules/@octopus/engine/dist/translator/enterTextAction.js +1 -0
  233. package/node_modules/@octopus/engine/dist/translator/extractDataAction.d.ts +13 -0
  234. package/node_modules/@octopus/engine/dist/translator/extractDataAction.js +1 -0
  235. package/node_modules/@octopus/engine/dist/translator/loopAction.d.ts +5 -0
  236. package/node_modules/@octopus/engine/dist/translator/loopAction.js +1 -0
  237. package/node_modules/@octopus/engine/dist/translator/mouseOverAction.d.ts +5 -0
  238. package/node_modules/@octopus/engine/dist/translator/mouseOverAction.js +19 -0
  239. package/node_modules/@octopus/engine/dist/translator/navigateAction.d.ts +5 -0
  240. package/node_modules/@octopus/engine/dist/translator/navigateAction.js +117 -0
  241. package/node_modules/@octopus/engine/dist/translator/rootAction.d.ts +6 -0
  242. package/node_modules/@octopus/engine/dist/translator/rootAction.js +80 -0
  243. package/node_modules/@octopus/engine/dist/translator/switchCombo2Action.d.ts +5 -0
  244. package/node_modules/@octopus/engine/dist/translator/switchCombo2Action.js +19 -0
  245. package/node_modules/@octopus/engine/dist/translator/translator.d.ts +1 -0
  246. package/node_modules/@octopus/engine/dist/translator/translator.js +36 -0
  247. package/node_modules/@octopus/engine/dist/type.d.ts +25 -0
  248. package/node_modules/@octopus/engine/dist/type.js +2 -0
  249. package/node_modules/@octopus/engine/dist/types/browser.d.ts +191 -0
  250. package/node_modules/@octopus/engine/dist/types/browser.js +1 -0
  251. package/node_modules/@octopus/engine/dist/types/browserManager.d.ts +41 -0
  252. package/node_modules/@octopus/engine/dist/types/browserManager.js +1 -0
  253. package/node_modules/@octopus/engine/dist/types/index.d.ts +40 -0
  254. package/node_modules/@octopus/engine/dist/types/index.js +2 -0
  255. package/node_modules/@octopus/engine/dist/types/plugin.d.ts +29 -0
  256. package/node_modules/@octopus/engine/dist/types/plugin.js +2 -0
  257. package/node_modules/@octopus/engine/dist/utils/AsyncEmitter.d.ts +15 -0
  258. package/node_modules/@octopus/engine/dist/utils/AsyncEmitter.js +1 -0
  259. package/node_modules/@octopus/engine/dist/utils/DataStore.d.ts +58 -0
  260. package/node_modules/@octopus/engine/dist/utils/DataStore.js +1 -0
  261. package/node_modules/@octopus/engine/dist/utils/DateTimeFormatHelper.d.ts +22 -0
  262. package/node_modules/@octopus/engine/dist/utils/DateTimeFormatHelper.js +173 -0
  263. package/node_modules/@octopus/engine/dist/utils/FileDownloader.d.ts +108 -0
  264. package/node_modules/@octopus/engine/dist/utils/FileDownloader.js +1 -0
  265. package/node_modules/@octopus/engine/dist/utils/HttpRequester.d.ts +43 -0
  266. package/node_modules/@octopus/engine/dist/utils/HttpRequester.js +174 -0
  267. package/node_modules/@octopus/engine/dist/utils/JsonParser.d.ts +95 -0
  268. package/node_modules/@octopus/engine/dist/utils/JsonParser.js +439 -0
  269. package/node_modules/@octopus/engine/dist/utils/Operations.d.ts +27 -0
  270. package/node_modules/@octopus/engine/dist/utils/Operations.js +115 -0
  271. package/node_modules/@octopus/engine/dist/utils/index.d.ts +28 -0
  272. package/node_modules/@octopus/engine/dist/utils/index.js +356 -0
  273. package/node_modules/@octopus/engine/package.json +58 -0
  274. package/package.json +79 -0
  275. package/schemas/capabilities-v1.schema.json +234 -0
  276. package/schemas/detached-bootstrap-v1.schema.json +42 -0
  277. package/schemas/json-envelope-v1.schema.json +39 -0
  278. package/schemas/run-event-v1.schema.json +47 -0
@@ -0,0 +1,1559 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const events_1 = require("events");
7
+ const puppeteer_proxy_1 = require("puppeteer-proxy");
8
+ const BaseConfig_1 = __importDefault(require("../configs/BaseConfig"));
9
+ const enums_1 = require("../enums");
10
+ const actionItem_1 = require("../models/actionItem");
11
+ const utils_1 = require("../utils");
12
+ const Operations_1 = require("../utils/Operations");
13
+ class BaseAction {
14
+ get id() {
15
+ return this.activity.id;
16
+ }
17
+ /** 步骤名 */
18
+ get name() {
19
+ return this.config.caption;
20
+ }
21
+ get isOpenProxyIp() {
22
+ var _a, _b;
23
+ if (!this.browserProxy.brokerSettings) {
24
+ return false;
25
+ }
26
+ return (((_b = (_a = this.browserProxy.brokerSettings) === null || _a === void 0 ? void 0 : _a.ipProxySettings) === null || _b === void 0 ? void 0 : _b.ipProxyFromType) !==
27
+ enums_1.IpProxyFromType.None);
28
+ }
29
+ get proxyIpSwitchPeriod() {
30
+ var _a, _b, _c;
31
+ return (((_c = (_b = (_a = this.browserProxy.brokerSettings) === null || _a === void 0 ? void 0 : _a.ipProxySettings) === null || _b === void 0 ? void 0 : _b.strongIpProxySettings) === null || _c === void 0 ? void 0 : _c.period) * 1000 || 5 * 60 * 1000);
32
+ }
33
+ constructor(browserProxy, activity, execution, parent) {
34
+ var _a, _b;
35
+ /** 单个步骤最长执行时间,超过默认最大时间自动结束当前步骤 (毫秒) */
36
+ this.executeTimeMax = 3 * 60 * 1000;
37
+ this.navigateType = "None" /* NavigateType.None */;
38
+ // ─────────────────────────────────────────────────────────────
39
+ // Extension Bridge 辅助
40
+ // ─────────────────────────────────────────────────────────────
41
+ /** 首次解析成功后缓存 Page → tabId,后续无需再查 URL */
42
+ this.tabIdCache = new WeakMap();
43
+ this.loopXpathStrategyMap = new Map();
44
+ this.browserProxy = browserProxy;
45
+ this.activity = activity;
46
+ this.execution = execution;
47
+ this.parent = parent;
48
+ this.variables = ((_a = execution.context) === null || _a === void 0 ? void 0 : _a.variables) || execution.variables;
49
+ const attrs = ((_b = activity.activity) === null || _b === void 0 ? void 0 : _b.$attrs) || activity.$attrs;
50
+ this.type = attrs.actionType;
51
+ this.config = this.parseConfig(attrs);
52
+ this.event = new events_1.EventEmitter();
53
+ }
54
+ emit(eventName, ...args) {
55
+ this.event.emit(eventName, ...args);
56
+ }
57
+ on(eventName, listener) {
58
+ this.event.on(eventName, listener);
59
+ }
60
+ once(eventName, listener) {
61
+ this.event.once(eventName, listener);
62
+ }
63
+ log(key, ...args) {
64
+ this.emit('log', enums_1.LogType.Info, key, args);
65
+ }
66
+ error(key, ...args) {
67
+ this.emit('log', enums_1.LogType.Error, key, args);
68
+ }
69
+ resource(key, ...args) {
70
+ this.emit('log', enums_1.LogType.Resource, key, args);
71
+ }
72
+ debug(key, ...args) {
73
+ this.emit('log', enums_1.LogType.DebugLogger, key, args);
74
+ }
75
+ removeListeners() {
76
+ this.event.removeAllListeners();
77
+ }
78
+ async checkPause() {
79
+ // this.emit('checkPause')
80
+ await new Promise((resolve) => {
81
+ this.emit('checkPause', resolve);
82
+ });
83
+ }
84
+ async screenshot() {
85
+ var _a;
86
+ const page = await this.browserProxy.resolveCurrentPage();
87
+ const tabId = this.useExtensionBridge
88
+ ? await this.getTabIdForPage(page)
89
+ : undefined;
90
+ if (tabId !== undefined) {
91
+ try {
92
+ const screenshotResult = await this.browserProxy.extensionBridge.sendActionCommand({
93
+ action: 'screenshot',
94
+ tabId,
95
+ frame: { isIframe: false },
96
+ payload: {
97
+ format: 'jpeg',
98
+ encoding: 'base64',
99
+ fullPage: true,
100
+ quality: 30,
101
+ maxBytes: 1024 * 1024
102
+ }
103
+ });
104
+ if (screenshotResult.success) {
105
+ const screenshotArtifact = (_a = screenshotResult.artifacts) === null || _a === void 0 ? void 0 : _a.find((artifact) => artifact.type === 'screenshot');
106
+ if (screenshotArtifact === null || screenshotArtifact === void 0 ? void 0 : screenshotArtifact.data) {
107
+ const screenshot = Buffer.from(screenshotArtifact.data, 'base64');
108
+ if (screenshot.length > 1024 * 1024) {
109
+ this.debug('截图大小超过1MB,已裁剪为当前可视区域');
110
+ }
111
+ return screenshot;
112
+ }
113
+ }
114
+ }
115
+ catch {
116
+ // fallback 到旧 Puppeteer 逻辑
117
+ return;
118
+ }
119
+ }
120
+ // 先尝试全屏截图
121
+ let screenshot = await page.screenshot({
122
+ fullPage: true,
123
+ type: 'jpeg',
124
+ quality: 30
125
+ });
126
+ // 检查截图大小是否超过 1MB (1024 * 1024 bytes)
127
+ const maxSize = 1024 * 1024; // 1MB
128
+ if (screenshot.length > maxSize) {
129
+ // 如果超过 1MB,则只截取当前可视区域
130
+ this.debug('截图大小超过1MB,已裁剪为当前可视区域');
131
+ screenshot = await page.screenshot({
132
+ fullPage: false, // 只截取当前可视区域
133
+ type: 'jpeg',
134
+ quality: 30
135
+ });
136
+ }
137
+ return screenshot;
138
+ }
139
+ async getCurrentPageUrl() {
140
+ const page = await this.browserProxy.resolveCurrentPage();
141
+ return page.url();
142
+ }
143
+ async waitForTarget(timeout, options) {
144
+ return new Promise((resolve, reject) => {
145
+ var _a, _b;
146
+ let timer = null;
147
+ const rejectWithCleanup = (error) => {
148
+ cleanup();
149
+ reject(error);
150
+ };
151
+ const cleanup = () => {
152
+ var _a;
153
+ this.browserProxy.removeTargetChanged(handler);
154
+ this.browserProxy.removeTargetCreated(handler);
155
+ (_a = options === null || options === void 0 ? void 0 : options.signal) === null || _a === void 0 ? void 0 : _a.removeEventListener('abort', handleAbort);
156
+ if (timer) {
157
+ clearTimeout(timer);
158
+ timer = null;
159
+ }
160
+ };
161
+ const handler = (target) => {
162
+ if (target.type() === 'page') {
163
+ cleanup();
164
+ return resolve(true);
165
+ }
166
+ };
167
+ this.browserProxy.onTargetChanged(handler);
168
+ this.browserProxy.onTargetCreated(handler);
169
+ const handleAbort = () => {
170
+ rejectWithCleanup(new Error('waitForTarget aborted'));
171
+ };
172
+ if ((_a = options === null || options === void 0 ? void 0 : options.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
173
+ handleAbort();
174
+ return;
175
+ }
176
+ (_b = options === null || options === void 0 ? void 0 : options.signal) === null || _b === void 0 ? void 0 : _b.addEventListener('abort', handleAbort, { once: true });
177
+ if (timeout > 0) {
178
+ timer = setTimeout(() => {
179
+ rejectWithCleanup(new Error('waitForTarget timeout'));
180
+ }, timeout);
181
+ }
182
+ });
183
+ }
184
+ async setProxy(page) {
185
+ if (!this.isOpenProxyIp)
186
+ return;
187
+ const now = Date.now();
188
+ const period = this.proxyIpSwitchPeriod; // 代理切换周期(毫秒)
189
+ // 如果已经有正在进行的代理请求,等待它完成
190
+ if (this.browserProxy.pendingProxyRequest) {
191
+ await this.browserProxy.pendingProxyRequest;
192
+ return;
193
+ }
194
+ if (!this.browserProxy.isSetedProxy ||
195
+ (period > 0 && now - this.browserProxy.latestSetProxyTime >= period)) {
196
+ // 提前更新标志和时间戳,防止并发请求
197
+ this.browserProxy.isSetedProxy = true;
198
+ this.browserProxy.latestSetProxyTime = now;
199
+ const proxyIp = await this.getProxyIp();
200
+ if (proxyIp && proxyIp.ip && proxyIp.port) {
201
+ // 清除上一次ip设置
202
+ page.removeAllListeners('request');
203
+ await page.setRequestInterception(true);
204
+ this.browserProxy.proxyInfo = { ...proxyIp };
205
+ // 切换了代理IP,重置代理日志IP上传状态
206
+ this.browserProxy.isUploadedProxyInfoOpenedPage = false;
207
+ page.on('request', async (request) => {
208
+ if (request.interceptResolutionState().action === 'already-handled')
209
+ return;
210
+ // 构建包含认证信息的代理 URL
211
+ let proxyUrl = `http://${proxyIp.ip}:${proxyIp.port}`;
212
+ if (proxyIp.account && proxyIp.password) {
213
+ proxyUrl = `http://${proxyIp.account}:${proxyIp.password}@${proxyIp.ip}:${proxyIp.port}`;
214
+ }
215
+ await (0, puppeteer_proxy_1.proxyRequest)({
216
+ page,
217
+ proxyUrl,
218
+ request
219
+ });
220
+ if (request.interceptResolutionState().action === 'already-handled')
221
+ return;
222
+ request.continue();
223
+ });
224
+ }
225
+ }
226
+ }
227
+ async collectProxyLog(reason, success) {
228
+ if (!this.browserProxy.proxyInfo)
229
+ return;
230
+ let snapshotKey;
231
+ try {
232
+ snapshotKey = await this.screenshot();
233
+ }
234
+ catch (error) {
235
+ }
236
+ const data = {
237
+ ...this.browserProxy.proxyInfo,
238
+ reason,
239
+ snapshotKey,
240
+ success
241
+ };
242
+ this.emit('collect-proxy-log' + this.id, data);
243
+ }
244
+ get shouldWait() {
245
+ return this.browserProxy.shouldWait;
246
+ }
247
+ set shouldWait(flag) {
248
+ this.browserProxy.shouldWait = flag;
249
+ }
250
+ /** 当前可见页面 */
251
+ async getCurrentPage() {
252
+ try {
253
+ const page = await this.browserProxy.resolveCurrentPage();
254
+ await this.setProxy(page);
255
+ const ready = await this.waitForReady(page);
256
+ if (!ready)
257
+ this.error(enums_1.LogKey.Click.NewWindow.Failure, this.name, page.url());
258
+ page.setDefaultTimeout(10 * 1000);
259
+ return page;
260
+ }
261
+ catch (error) {
262
+ console.log('获取当前页面失败', error);
263
+ this.debug(`获取当前页面失败:${error}`);
264
+ }
265
+ }
266
+ async waitForDocumentReady(page) {
267
+ try {
268
+ await page.evaluate(() => document);
269
+ await page.waitForFunction('document.readyState === "complete"', {
270
+ timeout: 15000
271
+ });
272
+ return true;
273
+ }
274
+ catch {
275
+ return false;
276
+ }
277
+ }
278
+ async waitForReady(page) {
279
+ var _a;
280
+ const bridgeReady = this.shouldWait
281
+ ? await this.runBridgeReadyCheck(page, { timeoutMs: 15000 })
282
+ : undefined;
283
+ if (bridgeReady !== undefined) {
284
+ this.debug(`bridge-ready-debug state=${bridgeReady ? 'ready' : 'not-ready'} fallback=skipped`);
285
+ this.shouldWait = false;
286
+ return bridgeReady;
287
+ }
288
+ if ((_a = this.browserProxy.extensionBridge) === null || _a === void 0 ? void 0 : _a.isConnected) {
289
+ const ready = this.shouldWait
290
+ ? await this.waitForDocumentReady(page)
291
+ : true;
292
+ this.debug(`bridge-ready-debug state=unavailable fallback=background-document-ready result=${ready ? 'ready' : 'not-ready'}`);
293
+ this.shouldWait = false;
294
+ return ready;
295
+ }
296
+ const [, ready] = await Promise.allSettled([
297
+ page.bringToFront(),
298
+ this.shouldWait ? this.waitForDocumentReady(page) : Promise.resolve(true)
299
+ ]);
300
+ this.debug('bridge-ready-debug state=disabled fallback=bring-to-front');
301
+ this.shouldWait = false;
302
+ return ready.status == 'fulfilled' ? ready.value : false;
303
+ }
304
+ getContext() {
305
+ return this.browserProxy.resolveContext();
306
+ }
307
+ async getProxyIp() {
308
+ // 如果已经有正在进行的代理请求,直接返回该 Promise
309
+ if (this.browserProxy.pendingProxyRequest) {
310
+ return this.browserProxy.pendingProxyRequest;
311
+ }
312
+ // 创建新的代理请求 Promise
313
+ const proxyPromise = new Promise((resolve) => {
314
+ this.once('send-proxy' + this.id, (data) => {
315
+ const { proxyIp } = data || {};
316
+ // 请求完成后清除缓存
317
+ this.browserProxy.pendingProxyRequest = null;
318
+ resolve(proxyIp);
319
+ });
320
+ this.emit('get-proxy');
321
+ });
322
+ // 缓存这个 Promise
323
+ this.browserProxy.pendingProxyRequest = proxyPromise;
324
+ return proxyPromise;
325
+ }
326
+ /** 解析步骤配置 */
327
+ parseConfig(config) {
328
+ return new BaseConfig_1.default(config);
329
+ }
330
+ /** 是否应优先使用插件桥接执行操作 */
331
+ get useExtensionBridge() {
332
+ var _a;
333
+ return !!((_a = this.browserProxy.extensionBridge) === null || _a === void 0 ? void 0 : _a.isConnected);
334
+ }
335
+ /**
336
+ * 获取当前页面对应的 Extension tabId
337
+ * 首次通过 URL 解析,之后从 WeakMap 缓存读取
338
+ */
339
+ async getTabId() {
340
+ return this.getTabIdForPage();
341
+ }
342
+ async getTabIdForPage(page) {
343
+ const bridge = this.browserProxy.extensionBridge;
344
+ if (!bridge)
345
+ return undefined;
346
+ const resolvedPage = page !== null && page !== void 0 ? page : await this.getCurrentPage();
347
+ if (!resolvedPage)
348
+ return undefined;
349
+ if (this.tabIdCache.has(resolvedPage))
350
+ return this.tabIdCache.get(resolvedPage);
351
+ const tabId = bridge.resolveTabId(resolvedPage.url());
352
+ if (tabId !== undefined) {
353
+ this.tabIdCache.set(resolvedPage, tabId);
354
+ }
355
+ return tabId;
356
+ }
357
+ async runBridgeReadyCheck(page, options) {
358
+ const bridge = this.browserProxy.extensionBridge;
359
+ if (!(bridge === null || bridge === void 0 ? void 0 : bridge.isConnected)) {
360
+ return undefined;
361
+ }
362
+ const tabId = await this.getTabIdForPage(page);
363
+ if (tabId === undefined) {
364
+ return undefined;
365
+ }
366
+ const actionItem = options === null || options === void 0 ? void 0 : options.actionItem;
367
+ const timeoutMs = options === null || options === void 0 ? void 0 : options.timeoutMs;
368
+ try {
369
+ const result = await bridge.sendActionCommand({
370
+ action: 'ready-check',
371
+ tabId,
372
+ frame: (actionItem === null || actionItem === void 0 ? void 0 : actionItem.IsIFrame)
373
+ ? {
374
+ isIframe: true,
375
+ iframeXpath: actionItem.IFrameAbsXPath
376
+ }
377
+ : { isIframe: false },
378
+ target: (actionItem === null || actionItem === void 0 ? void 0 : actionItem.AbsXpath)
379
+ ? {
380
+ type: 'xpath',
381
+ xpath: actionItem.AbsXpath
382
+ }
383
+ : undefined,
384
+ waitPolicy: (actionItem === null || actionItem === void 0 ? void 0 : actionItem.AbsXpath)
385
+ ? {
386
+ strategy: 'selector',
387
+ timeoutMs,
388
+ backgroundSafe: true
389
+ }
390
+ : {
391
+ strategy: 'base-load',
392
+ timeoutMs,
393
+ backgroundSafe: true
394
+ },
395
+ timeoutMs,
396
+ payload: {
397
+ mode: (actionItem === null || actionItem === void 0 ? void 0 : actionItem.AbsXpath) ? 'selector' : 'base-load'
398
+ }
399
+ });
400
+ return result.success;
401
+ }
402
+ catch {
403
+ return undefined;
404
+ }
405
+ }
406
+ async bridgeElementExists(page, actionItem, timeoutMs = 1500) {
407
+ const bridge = this.browserProxy.extensionBridge;
408
+ if (!(bridge === null || bridge === void 0 ? void 0 : bridge.isConnected)) {
409
+ return undefined;
410
+ }
411
+ const tabId = await this.getTabIdForPage(page);
412
+ if (tabId === undefined) {
413
+ return undefined;
414
+ }
415
+ try {
416
+ const result = await bridge.sendActionCommand({
417
+ action: 'ready-check',
418
+ tabId,
419
+ frame: actionItem.IsIFrame
420
+ ? {
421
+ isIframe: true,
422
+ iframeXpath: actionItem.IFrameAbsXPath
423
+ }
424
+ : { isIframe: false },
425
+ target: {
426
+ type: 'xpath',
427
+ xpath: actionItem.AbsXpath
428
+ },
429
+ waitPolicy: {
430
+ strategy: 'selector',
431
+ timeoutMs,
432
+ backgroundSafe: true
433
+ },
434
+ timeoutMs,
435
+ payload: { mode: 'selector' }
436
+ });
437
+ return result.success;
438
+ }
439
+ catch {
440
+ return undefined;
441
+ }
442
+ }
443
+ async locator(page, actionItem) {
444
+ if (!actionItem.IsIFrame) {
445
+ const { AbsXpath } = actionItem;
446
+ return page.locator(`::-p-xpath(${AbsXpath})`);
447
+ }
448
+ const { AbsXpath, IFrameAbsXPath } = actionItem;
449
+ const iframeElement = await page.$(`::-p-xpath(${IFrameAbsXPath})`);
450
+ const iframe = await iframeElement.contentFrame();
451
+ return iframe.locator(`::-p-xpath(${AbsXpath})`);
452
+ }
453
+ getBridgeScrollMode(scrollXPath, scrollType) {
454
+ return scrollXPath
455
+ ? scrollType == 1 /* ScrollType.ScrollOneScreen */
456
+ ? 'element-by-screen'
457
+ : 'element-to-bottom'
458
+ : scrollType == 1 /* ScrollType.ScrollOneScreen */
459
+ ? 'window-by-screen'
460
+ : 'window-to-bottom';
461
+ }
462
+ getScrollLogKey(scrollXPath, scrollType) {
463
+ return scrollXPath
464
+ ? scrollType == 1 /* ScrollType.ScrollOneScreen */
465
+ ? enums_1.LogKey.Common.Scroll.Local.Screen
466
+ : enums_1.LogKey.Common.Scroll.Local.Bottom
467
+ : scrollType == 1 /* ScrollType.ScrollOneScreen */
468
+ ? enums_1.LogKey.Common.Scroll.Global.Screen
469
+ : enums_1.LogKey.Common.Scroll.Global.Bottom;
470
+ }
471
+ buildScrollDebugContext(args) {
472
+ var _a, _b, _c;
473
+ return `bridge-scroll-debug tabId=${(_a = args.tabId) !== null && _a !== void 0 ? _a : 'unknown'} scope=${((_b = args.scrollXPath) === null || _b === void 0 ? void 0 : _b.AbsXpath) ? 'local' : 'global'} mode=${args.scrollMode} iteration=${args.iteration}${((_c = args.scrollXPath) === null || _c === void 0 ? void 0 : _c.AbsXpath) ? ` xpath=${args.scrollXPath.AbsXpath}` : ''}`;
474
+ }
475
+ normalizeBridgeScrollReason(reason) {
476
+ const reasonDetail = reason instanceof Error ? reason.message : String(reason);
477
+ if (reasonDetail.includes('No extension connected')) {
478
+ return { reasonCode: 'no_extension', reasonDetail };
479
+ }
480
+ if (reasonDetail.includes('Command timeout')) {
481
+ return { reasonCode: 'command_timeout', reasonDetail };
482
+ }
483
+ if (reasonDetail.includes('Element not found')) {
484
+ return { reasonCode: 'element_not_found', reasonDetail };
485
+ }
486
+ if (reason instanceof Error) {
487
+ return { reasonCode: 'command_failed', reasonDetail };
488
+ }
489
+ return { reasonCode: 'unknown', reasonDetail };
490
+ }
491
+ /** 休眠指定时间 */
492
+ sleep(delay) {
493
+ return (0, utils_1.sleep)(delay);
494
+ }
495
+ /** 结束当前步骤 */
496
+ finish() {
497
+ var _a, _b;
498
+ // setTimeout(() => {
499
+ ((_a = this.activity) === null || _a === void 0 ? void 0 : _a.waiting) && ((_b = this.activity) === null || _b === void 0 ? void 0 : _b.signal());
500
+ // }, 500)
501
+ }
502
+ /** 切换代理 IP */
503
+ async switchIP(page) {
504
+ const { enableSwitchIp, iPType } = this.config;
505
+ if (iPType === 1) {
506
+ return;
507
+ }
508
+ if (enableSwitchIp) {
509
+ const proxyIp = await this.getProxyIp();
510
+ if (proxyIp && proxyIp.ip && proxyIp.port) {
511
+ page.removeAllListeners('request');
512
+ await page.setRequestInterception(true);
513
+ this.browserProxy.proxyInfo = proxyIp;
514
+ // Reset after fetching a proxy so the next successful page load uploads once.
515
+ this.browserProxy.isUploadedProxyInfoOpenedPage = false;
516
+ page.on('request', async (request) => {
517
+ if (request.interceptResolutionState().action === 'already-handled')
518
+ return;
519
+ // 构建包含认证信息的代理 URL
520
+ let proxyUrl = `http://${proxyIp.ip}:${proxyIp.port}`;
521
+ if (proxyIp.account && proxyIp.password) {
522
+ proxyUrl = `http://${proxyIp.account}:${proxyIp.password}@${proxyIp.ip}:${proxyIp.port}`;
523
+ }
524
+ await (0, puppeteer_proxy_1.proxyRequest)({
525
+ page,
526
+ proxyUrl,
527
+ request
528
+ });
529
+ if (request.interceptResolutionState().action === 'already-handled')
530
+ return;
531
+ request.continue();
532
+ });
533
+ }
534
+ this.resource(enums_1.LogKey.Common.SwitchIP, this.name);
535
+ await this.checkPause();
536
+ }
537
+ }
538
+ /** 切换浏览器 UA */
539
+ switchUA() {
540
+ // const { enableSwitchUserAgent, userAgents } = this.config as NavigateConfig | ClickConfig
541
+ // if (enableSwitchUserAgent) {
542
+ // const ua = this.workflow.plugin.switchUA(this.workflow.browser, userAgents)
543
+ // this.log(LogKey.Common.SwitchUA, this.name, ua)
544
+ // }
545
+ }
546
+ /** 等待当前网页还在加载的请求完成,每隔 100ms 判定一次,最多判定 100 次,最长等待 10s */
547
+ async waitRequest() {
548
+ const waitingTimes = 100;
549
+ // while (this.workflow.browser.isWaitRequest()) {
550
+ // await this.sleep(100)
551
+ // await this.checkPause()
552
+ // if (--waitingTimes <= 0) break
553
+ // }
554
+ }
555
+ /** 等待 Ajax 请求完成 */
556
+ async ajax() {
557
+ const { ajaxLoad, ajaxTimeout } = this.config;
558
+ if (ajaxLoad && ajaxTimeout > 0) {
559
+ this.log(enums_1.LogKey.Common.Ajax.Action, this.name);
560
+ const time = ajaxTimeout * 1000000;
561
+ // while (this.workflow.browser.isWaitRequest()) {
562
+ // await this.sleep(100)
563
+ // await this.checkPause()
564
+ // time -= 100
565
+ // if (time <= 0) {
566
+ // this.workflow.error(LogKey.Common.Ajax.Failure, this.name, ajaxTimeout)
567
+ // break
568
+ // }
569
+ // }
570
+ // time > 0 && this.log(LogKey.Common.Ajax.Success, this.name)
571
+ }
572
+ }
573
+ /** 执行滚动网页 */
574
+ async scroll() {
575
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
576
+ const page = await this.getCurrentPage();
577
+ const { scrollDown, scrollType, scrollTime, scrollInterval, scrollXPath, IfStopScroll } = this.config;
578
+ if (!scrollDown) {
579
+ return;
580
+ }
581
+ let scrollHeight = 0;
582
+ let checkTimes = 1;
583
+ const tabId = this.useExtensionBridge
584
+ ? await this.getTabIdForPage(page)
585
+ : undefined;
586
+ const scrollMode = this.getBridgeScrollMode(scrollXPath, scrollType);
587
+ const scrollLogKey = this.getScrollLogKey(scrollXPath, scrollType);
588
+ for (let i = 0; i < scrollTime; i++) {
589
+ if (i && scrollInterval > 0) {
590
+ await this.sleep(scrollInterval);
591
+ await this.checkPause();
592
+ }
593
+ if (tabId !== undefined) {
594
+ const debugContext = this.buildScrollDebugContext({
595
+ tabId,
596
+ scrollXPath,
597
+ scrollMode,
598
+ iteration: i + 1
599
+ });
600
+ try {
601
+ const scrollResult = await this.browserProxy.extensionBridge.sendActionCommand({
602
+ action: 'scroll',
603
+ tabId,
604
+ frame: (scrollXPath === null || scrollXPath === void 0 ? void 0 : scrollXPath.IsIFrame)
605
+ ? {
606
+ isIframe: true,
607
+ iframeXpath: scrollXPath.IFrameAbsXPath
608
+ }
609
+ : { isIframe: false },
610
+ target: (scrollXPath === null || scrollXPath === void 0 ? void 0 : scrollXPath.AbsXpath)
611
+ ? {
612
+ type: 'xpath',
613
+ xpath: scrollXPath.AbsXpath
614
+ }
615
+ : undefined,
616
+ waitPolicy: scrollXPath
617
+ ? undefined
618
+ : {
619
+ strategy: 'network-idle',
620
+ timeoutMs: 1000,
621
+ idleTimeMs: 300,
622
+ concurrency: 3,
623
+ backgroundSafe: true
624
+ },
625
+ payload: {
626
+ mode: scrollMode,
627
+ behavior: 'auto'
628
+ }
629
+ });
630
+ if (!scrollResult.success) {
631
+ throw new Error('error' in scrollResult
632
+ ? scrollResult.error
633
+ : 'bridge scroll failed');
634
+ }
635
+ const successResult = scrollResult;
636
+ const data = successResult.data;
637
+ const positionChanged = (scrollXPath === null || scrollXPath === void 0 ? void 0 : scrollXPath.AbsXpath)
638
+ ? ((_a = data === null || data === void 0 ? void 0 : data.targetChanged) !== null && _a !== void 0 ? _a : ((_c = (_b = data === null || data === void 0 ? void 0 : data.before) === null || _b === void 0 ? void 0 : _b.target) === null || _c === void 0 ? void 0 : _c.scrollTop) !==
639
+ ((_e = (_d = data === null || data === void 0 ? void 0 : data.after) === null || _d === void 0 ? void 0 : _d.target) === null || _e === void 0 ? void 0 : _e.scrollTop))
640
+ : ((_f = data === null || data === void 0 ? void 0 : data.windowChanged) !== null && _f !== void 0 ? _f : ((_g = data === null || data === void 0 ? void 0 : data.before) === null || _g === void 0 ? void 0 : _g.scrollY) !== ((_h = data === null || data === void 0 ? void 0 : data.after) === null || _h === void 0 ? void 0 : _h.scrollY));
641
+ this.debug(`bridge scroll success ${debugContext} bridgeState=success positionState=${positionChanged ? 'changed' : 'unchanged'} beforeY=${(_k = (_j = data === null || data === void 0 ? void 0 : data.before) === null || _j === void 0 ? void 0 : _j.scrollY) !== null && _k !== void 0 ? _k : 'unknown'} afterY=${(_m = (_l = data === null || data === void 0 ? void 0 : data.after) === null || _l === void 0 ? void 0 : _l.scrollY) !== null && _m !== void 0 ? _m : 'unknown'} beforeTarget=${(_q = (_p = (_o = data === null || data === void 0 ? void 0 : data.before) === null || _o === void 0 ? void 0 : _o.target) === null || _p === void 0 ? void 0 : _p.scrollTop) !== null && _q !== void 0 ? _q : 'unknown'} afterTarget=${(_t = (_s = (_r = data === null || data === void 0 ? void 0 : data.after) === null || _r === void 0 ? void 0 : _r.target) === null || _s === void 0 ? void 0 : _s.scrollTop) !== null && _t !== void 0 ? _t : 'unknown'}`);
642
+ this.log(scrollLogKey, this.name, i + 1);
643
+ if (IfStopScroll) {
644
+ const currentScrollTop = (scrollXPath === null || scrollXPath === void 0 ? void 0 : scrollXPath.AbsXpath)
645
+ ? ((_w = (_v = (_u = data === null || data === void 0 ? void 0 : data.after) === null || _u === void 0 ? void 0 : _u.target) === null || _v === void 0 ? void 0 : _v.scrollTop) !== null && _w !== void 0 ? _w : scrollHeight)
646
+ : ((_y = (_x = data === null || data === void 0 ? void 0 : data.after) === null || _x === void 0 ? void 0 : _x.scrollY) !== null && _y !== void 0 ? _y : scrollHeight);
647
+ if (scrollHeight == currentScrollTop && checkTimes-- < 0) {
648
+ break;
649
+ }
650
+ scrollHeight = currentScrollTop;
651
+ }
652
+ continue;
653
+ }
654
+ catch (error) {
655
+ const { reasonCode, reasonDetail } = this.normalizeBridgeScrollReason(error);
656
+ this.debug(`bridge scroll failed ${debugContext} bridgeState=failed positionState=unknown reason=${reasonCode} detail=${reasonDetail}`);
657
+ }
658
+ }
659
+ if (scrollXPath) {
660
+ // 局部滚动
661
+ const [isExist] = await Promise.allSettled([
662
+ this.locator(page, scrollXPath).then((locator) => locator.setTimeout(2000).wait()),
663
+ (0, Operations_1.processElement)(scrollXPath, page, '$eval', (ele, scrollScreen) => {
664
+ scrollScreen
665
+ ? ele.scrollBy(0, ele.offsetHeight)
666
+ : ele.scrollTo({ top: ele.scrollHeight });
667
+ }, scrollType == 1 /* ScrollType.ScrollOneScreen */)
668
+ ]);
669
+ if (isExist.status === 'rejected') {
670
+ break;
671
+ }
672
+ this.log(scrollLogKey, this.name, i + 1);
673
+ }
674
+ else {
675
+ // 全局滚动
676
+ const [, scroll] = await Promise.allSettled([
677
+ page.waitForNetworkIdle({
678
+ concurrency: 3,
679
+ idleTime: 300,
680
+ timeout: 1000
681
+ }),
682
+ page.evaluate((scrollScreen) => new Promise((resolve) => {
683
+ scrollScreen
684
+ ? document.scrollingElement.scrollBy(0, globalThis.window.innerHeight)
685
+ : document.scrollingElement.scrollTo({
686
+ top: globalThis.document.scrollingElement.scrollHeight,
687
+ behavior: 'smooth'
688
+ });
689
+ resolve(true);
690
+ }), scrollType == 1 /* ScrollType.ScrollOneScreen */)
691
+ ]);
692
+ if (scroll.status === 'rejected') {
693
+ break;
694
+ }
695
+ this.log(scrollLogKey, this.name, i + 1);
696
+ }
697
+ if (!IfStopScroll) {
698
+ // 继续滚动,不检查是否内容是否有更新
699
+ continue;
700
+ }
701
+ // 检查滚动位移是否变化,判断内容是否更新
702
+ const scrollTop = await ((scrollXPath === null || scrollXPath === void 0 ? void 0 : scrollXPath.AbsXpath)
703
+ ? (0, Operations_1.processElement)(scrollXPath, page, '$eval', (ele) => ele.scrollTop)
704
+ : page.evaluate(() => document.scrollingElement.scrollTop));
705
+ if (scrollHeight == scrollTop && checkTimes-- < 0) {
706
+ break;
707
+ }
708
+ scrollHeight = scrollTop;
709
+ }
710
+ this.log(enums_1.LogKey.Common.Scroll.Finish, this.name);
711
+ }
712
+ onPageLoading(url) {
713
+ //
714
+ }
715
+ async onPageLoaded(url, isTimeout) {
716
+ //
717
+ }
718
+ onPageFailLoad(url) {
719
+ //
720
+ }
721
+ async onJsonResponse(url) {
722
+ //
723
+ }
724
+ onJsonError(url) {
725
+ //
726
+ }
727
+ enter() {
728
+ // 获取当前循环的值
729
+ this.config.loopItem = this.getCurrentLoopValue();
730
+ }
731
+ start() {
732
+ if (!this.getIsSkipCurrentLoop() ||
733
+ !this.getIsSkipActionUtilNextLoop(this.getNodeId())) {
734
+ // this.workflow.browser.switchPage(this.config.pageIndex)
735
+ }
736
+ }
737
+ async wait(skipUseLoop) {
738
+ let timerSeconds = 0;
739
+ const page = await this.getCurrentPage();
740
+ let item = new actionItem_1.ActionItem('', false);
741
+ if (this.config.isRandomWait) {
742
+ timerSeconds = (0, utils_1.random)(3, 15);
743
+ }
744
+ else {
745
+ timerSeconds = this.config.waitSeconds;
746
+ }
747
+ timerSeconds > 0 && this.log(enums_1.LogKey.Common.BeforeWaitTime, timerSeconds);
748
+ if (this.config.waitItem) {
749
+ (0, utils_1.parseXML)(this.config.waitItem, async (err, result) => {
750
+ if (!err) {
751
+ item = Object.assign(item, result.ActionItem);
752
+ }
753
+ });
754
+ }
755
+ if (item.AbsXpath) {
756
+ // 配置了xpath,等待元素出现
757
+ try {
758
+ const timeoutMs = (timerSeconds || 30) * 1000;
759
+ const usedBridge = (await this.runBridgeReadyCheck(page, {
760
+ actionItem: item,
761
+ timeoutMs
762
+ })) === true;
763
+ if (!usedBridge) {
764
+ await page.waitForSelector(`xpath/${item.AbsXpath}`, {
765
+ timeout: timeoutMs
766
+ });
767
+ }
768
+ this.log(enums_1.LogKey.Common.BeforeWaitXPath, item.AbsXpath);
769
+ }
770
+ catch (error) {
771
+ await this.checkPause();
772
+ console.log('等待元素超时', error);
773
+ }
774
+ }
775
+ else {
776
+ // 没有配置xpath,等待timerSeconds执行下一步
777
+ await this.sleep(timerSeconds * 1000);
778
+ }
779
+ await this.checkPause();
780
+ return;
781
+ }
782
+ // 执行后等待
783
+ async waitAfter() {
784
+ let timerSeconds = 0;
785
+ const page = await this.getCurrentPage();
786
+ let item = new actionItem_1.ActionItem('', false);
787
+ if (this.config.IsRandomWaitAfter) {
788
+ timerSeconds = (0, utils_1.random)(3, 15);
789
+ }
790
+ else {
791
+ timerSeconds = this.config.WaitAfterSeconds;
792
+ }
793
+ timerSeconds > 0 && this.log(enums_1.LogKey.Common.BeforeWaitTime, timerSeconds);
794
+ if (this.config.WaitAfterItem) {
795
+ (0, utils_1.parseXML)(this.config.WaitAfterItem, async (err, result) => {
796
+ if (!err) {
797
+ item = Object.assign(item, result.ActionItem);
798
+ }
799
+ });
800
+ }
801
+ if (item.AbsXpath) {
802
+ // 配置了xpath,等待元素出现
803
+ try {
804
+ const timeoutMs = (timerSeconds || 30) * 1000;
805
+ const usedBridge = (await this.runBridgeReadyCheck(page, {
806
+ actionItem: item,
807
+ timeoutMs
808
+ })) === true;
809
+ if (!usedBridge) {
810
+ await page.waitForSelector(`xpath/${item.AbsXpath}`, {
811
+ timeout: timeoutMs
812
+ });
813
+ }
814
+ this.log(enums_1.LogKey.Common.BeforeWaitXPath, item.AbsXpath);
815
+ }
816
+ catch (error) {
817
+ await this.checkPause();
818
+ console.log('等待元素超时', error);
819
+ }
820
+ }
821
+ else {
822
+ // 没有配置xpath,等待timerSeconds执行下一步
823
+ await this.sleep(timerSeconds * 1000);
824
+ }
825
+ await this.checkPause();
826
+ return;
827
+ }
828
+ /** 根据验证码类型获取超时时间(毫秒) */
829
+ getCaptchaTimeout(captchaType) {
830
+ switch (captchaType) {
831
+ case enums_1.LocalCaptchaType.reCAPTCHA_V2:
832
+ case enums_1.LocalCaptchaType.reCAPTCHA_V2_Callback:
833
+ case enums_1.LocalCaptchaType.ReCAPTCHA_V3:
834
+ case enums_1.LocalCaptchaType.reCAPTCHA_V3_Callback:
835
+ case enums_1.LocalCaptchaType.HCaptcha:
836
+ case enums_1.LocalCaptchaType.HCaptcha_Callback:
837
+ case enums_1.LocalCaptchaType.Cloudflare:
838
+ return 120 * 1000;
839
+ case enums_1.LocalCaptchaType.Silder:
840
+ case enums_1.LocalCaptchaType.SilderWithoutImage:
841
+ case enums_1.LocalCaptchaType.Click:
842
+ return 60 * 1000;
843
+ default:
844
+ return 30 * 1000;
845
+ }
846
+ }
847
+ // 获取验证码token
848
+ async getCaptchaToken(data) {
849
+ const type = data.captchaType;
850
+ // 有些验证码解析时间较长,需要动态配置超时时间
851
+ const timeout = this.getCaptchaTimeout(type);
852
+ return new Promise((resolve) => {
853
+ let settled = false;
854
+ const eventName = `${enums_1.CaptchaEventType.DeliverCaptchaToken}_${this.id}`;
855
+ const timer = setTimeout(async () => {
856
+ if (settled)
857
+ return;
858
+ await this.checkPause();
859
+ settled = true;
860
+ this.event.removeAllListeners(eventName);
861
+ console.log(`验证码获取超时 (${timeout / 1000}s), captchaType: ${type}`);
862
+ switch (type) {
863
+ case enums_1.LocalCaptchaType.Silder: {
864
+ resolve({ distance: 0, status: 0, isAvailable: true });
865
+ break;
866
+ }
867
+ case enums_1.LocalCaptchaType.Click: {
868
+ resolve({ clickArea: [], status: 0, isAvailable: true });
869
+ break;
870
+ }
871
+ default: {
872
+ resolve('');
873
+ break;
874
+ }
875
+ }
876
+ }, timeout);
877
+ this.on(eventName, (data) => {
878
+ if (settled)
879
+ return;
880
+ settled = true;
881
+ clearTimeout(timer);
882
+ const { token = '', distance, status, isAvailable, clickArea } = data || {};
883
+ switch (type) {
884
+ case enums_1.LocalCaptchaType.Silder: {
885
+ resolve({ distance, status, isAvailable });
886
+ break;
887
+ }
888
+ case enums_1.LocalCaptchaType.Click: {
889
+ resolve({ status, clickArea, isAvailable });
890
+ break;
891
+ }
892
+ default: {
893
+ resolve(token);
894
+ break;
895
+ }
896
+ }
897
+ });
898
+ this.emit(`${enums_1.CaptchaEventType.RequestCaptchaToken}_${this.id}`, data);
899
+ });
900
+ }
901
+ end() {
902
+ //
903
+ }
904
+ leave() {
905
+ //
906
+ }
907
+ async executeCaptcha(data) {
908
+ //
909
+ }
910
+ /** @todo 以下是旧的代码直接迁移过来,待重构 */
911
+ getCurrentLoopValue() {
912
+ const nodeId = this.config.targetQueue || this.activity.parentContext.id;
913
+ return this.getLoopValue(nodeId);
914
+ }
915
+ /**
916
+ * 获取指定循环的当前值
917
+ * @param nodeId 这个属性的名称
918
+ */
919
+ getLoopValue(nodeId) {
920
+ const actualCurrentLoopValueKey = nodeId + "_current_loop_value" /* BaseActionQueueType.CurrentLoopValue */;
921
+ if (this.variables.globalContext[actualCurrentLoopValueKey]) {
922
+ return this.variables.globalContext[actualCurrentLoopValueKey];
923
+ }
924
+ return null;
925
+ }
926
+ /**
927
+ * 获取设置当前loop的url
928
+ * @param nodeId
929
+ * @param val
930
+ */
931
+ setCurrentLoopUrl(nodeId, val) {
932
+ const currentLoopurl = nodeId + "_currentloopurl" /* BaseActionQueueType.CurrentLoopUrl */;
933
+ this.variables.globalContext[currentLoopurl] = val;
934
+ }
935
+ /**
936
+ * 获取当前loop所在的url
937
+ * @param nodeId
938
+ * @param val
939
+ */
940
+ getCurrentLoopUrl(nodeId) {
941
+ const currentLoopurl = nodeId + "_currentloopurl" /* BaseActionQueueType.CurrentLoopUrl */;
942
+ if (this.variables.globalContext[currentLoopurl]) {
943
+ return this.variables.globalContext[currentLoopurl];
944
+ }
945
+ return undefined;
946
+ }
947
+ /**
948
+ * 设置指定循环的当前值
949
+ * @param nodeId
950
+ * @param val
951
+ */
952
+ setCurrentLoopValue(nodeId, val) {
953
+ const actualCurrentLoopValueKey = nodeId + "_current_loop_value" /* BaseActionQueueType.CurrentLoopValue */;
954
+ this.variables.globalContext[actualCurrentLoopValueKey] = val;
955
+ }
956
+ /**
957
+ * 从循环中取出一个对象
958
+ * @param nodeId
959
+ */
960
+ popLoopValue(nodeId) {
961
+ const actualLoopValuesKey = nodeId + "_loop_values" /* BaseActionQueueType.LoopValueArray */;
962
+ if (this.variables.globalContext[actualLoopValuesKey]) {
963
+ return this.variables.globalContext[actualLoopValuesKey].pop();
964
+ }
965
+ return null;
966
+ }
967
+ /**
968
+ * 设置该循环数组的值
969
+ * @param nodeId
970
+ * @param dic
971
+ */
972
+ setLoopValues(nodeId, dic) {
973
+ //查看配置的选项
974
+ const actualLoopValuesKey = nodeId + "_loop_values" /* BaseActionQueueType.LoopValueArray */;
975
+ this.variables.globalContext[actualLoopValuesKey] = dic;
976
+ }
977
+ /**
978
+ * 获取指定循环队列中,已推入的所有内容
979
+ * @param nodeId 指定循环的节点 id
980
+ */
981
+ getLoopValueArray(nodeId) {
982
+ const actualLoopValuesKey = nodeId + "_loop_values" /* BaseActionQueueType.LoopValueArray */;
983
+ if (this.variables.globalContext[actualLoopValuesKey]) {
984
+ return this.variables.globalContext[actualLoopValuesKey];
985
+ }
986
+ return null;
987
+ }
988
+ pushLoopValue(nodeId, val) {
989
+ const actualLoopValuesKey = nodeId + "_loop_values" /* BaseActionQueueType.LoopValueArray */;
990
+ this.variables.globalContext[actualLoopValuesKey].unshift(val);
991
+ }
992
+ saveSampedLoopRecord(info) {
993
+ if (!this.variables.globalContext['samped_loop_record']) {
994
+ this.initSampedLoopRecord();
995
+ }
996
+ if (!(info.parentid in this.variables.globalContext['samped_loop_record'])) {
997
+ this.variables.globalContext['samped_loop_record'][info.parentid] = info;
998
+ }
999
+ }
1000
+ initSampedLoopRecord() {
1001
+ if (this.variables.globalContext['samped_loop_record'])
1002
+ return;
1003
+ this.variables.globalContext['samped_loop_record'] = {};
1004
+ }
1005
+ getSampedLoopRecord() {
1006
+ return this.variables.globalContext['samped_loop_record'] || {};
1007
+ }
1008
+ /**
1009
+ * 统计指定循环列表提取数据步骤,当前已导出的数据条目
1010
+ * @param nodeId
1011
+ */
1012
+ countSomeLoopExtractDataNum(nodeId) {
1013
+ const actualLoopValuesKey = nodeId + "_identified_loop_extract_data_count" /* BaseActionQueueType.IdentifiedLoopExtractDataCount */;
1014
+ if (this.variables.globalContext[actualLoopValuesKey] == undefined) {
1015
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1016
+ }
1017
+ this.variables.globalContext[actualLoopValuesKey] += 1;
1018
+ }
1019
+ /**
1020
+ * 初始化指定循环列表提取数据步骤,当前已导出的数据条目为0
1021
+ * @param nodeId
1022
+ */
1023
+ initSomeLoopExtractDataCount(nodeId) {
1024
+ const actualLoopValuesKey = nodeId + "_identified_loop_extract_data_count" /* BaseActionQueueType.IdentifiedLoopExtractDataCount */;
1025
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1026
+ }
1027
+ /**
1028
+ * 获取指定循环列表提取数据步骤,当前已导出的数据条目
1029
+ * @param nodeId
1030
+ */
1031
+ getSomeLoopExtractDataCount(nodeId) {
1032
+ const actualLoopValuesKey = nodeId + "_identified_loop_extract_data_count" /* BaseActionQueueType.IdentifiedLoopExtractDataCount */;
1033
+ if (this.variables.globalContext[actualLoopValuesKey] == undefined) {
1034
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1035
+ }
1036
+ return this.variables.globalContext[actualLoopValuesKey];
1037
+ }
1038
+ /**
1039
+ * 设置指定循环列表提取数据步骤,存储的历史采样数据
1040
+ * @param nodeId
1041
+ * @param val
1042
+ */
1043
+ setSamplingElementsMap(nodeId, val) {
1044
+ const actualLoopValuesKey = nodeId + "_sampling_elements_map" /* BaseActionQueueType.SamplingElementsMap */;
1045
+ if (this.variables.globalContext[actualLoopValuesKey] == undefined) {
1046
+ this.variables.globalContext[actualLoopValuesKey] = new Map();
1047
+ }
1048
+ this.variables.globalContext[actualLoopValuesKey] = val;
1049
+ }
1050
+ /**
1051
+ * 读取指定循环列表提取数据步骤,存储的历史采样数据
1052
+ * @param nodeId
1053
+ * @param val
1054
+ */
1055
+ getSamplingElementsMap(nodeId) {
1056
+ const actualLoopValuesKey = nodeId + "_sampling_elements_map" /* BaseActionQueueType.SamplingElementsMap */;
1057
+ if (this.variables.globalContext[actualLoopValuesKey] == undefined) {
1058
+ this.variables.globalContext[actualLoopValuesKey] = new Map();
1059
+ }
1060
+ return this.variables.globalContext[actualLoopValuesKey];
1061
+ }
1062
+ /**
1063
+ * 初始化指定循环列表提取数据步骤,存储的历史采样数据
1064
+ * @param nodeId
1065
+ * @param val
1066
+ */
1067
+ initSamplingElementsMap(nodeId) {
1068
+ const actualLoopValuesKey = nodeId + "_sampling_elements_map" /* BaseActionQueueType.SamplingElementsMap */;
1069
+ this.variables.globalContext[actualLoopValuesKey] = new Map();
1070
+ }
1071
+ /**
1072
+ * 初始化指定循环列表提取数据步骤,当轮循环提取数据步骤完成后,已采集到的数据条目,用于生成特定的Xpath偏移量
1073
+ * @param nodeId
1074
+ * @param val
1075
+ */
1076
+ initIdentifiedEachLoopExtractDataCount(nodeId) {
1077
+ const actualLoopValuesKey = nodeId + "_identified_each_loop_extract_data_count" /* BaseActionQueueType.IdentifiedEachLoopExtractDataCount */;
1078
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1079
+ }
1080
+ /**
1081
+ * 设置指定循环列表提取数据步骤,当轮循环提取数据步骤完成后,已采集到的数据条目,用于生成特定的Xpath偏移量
1082
+ * @param nodeId
1083
+ * @param val
1084
+ */
1085
+ setIdentifiedEachLoopExtractDataCount(nodeId) {
1086
+ const actualLoopValuesKey = nodeId + "_identified_each_loop_extract_data_count" /* BaseActionQueueType.IdentifiedEachLoopExtractDataCount */;
1087
+ this.variables.globalContext[actualLoopValuesKey] =
1088
+ this.getSomeLoopExtractDataCount(nodeId);
1089
+ }
1090
+ /**
1091
+ * 读取指定循环列表提取数据步骤,当轮循环提取数据步骤完成后,已采集到的数据条目,用于生成特定的Xpath偏移量
1092
+ * @param nodeId
1093
+ * @param val
1094
+ */
1095
+ getIdentifiedEachLoopExtractDataCount(nodeId) {
1096
+ const actualLoopValuesKey = nodeId + "_identified_each_loop_extract_data_count" /* BaseActionQueueType.IdentifiedEachLoopExtractDataCount */;
1097
+ if (this.variables.globalContext[actualLoopValuesKey] == undefined) {
1098
+ this.variables.globalContext[actualLoopValuesKey] =
1099
+ this.getSomeLoopExtractDataCount(nodeId);
1100
+ }
1101
+ return this.variables.globalContext[actualLoopValuesKey];
1102
+ }
1103
+ setNextLoopOffset(nodeId, val) {
1104
+ const key = nodeId + "NextLoopOffset" /* BaseActionQueueType.NextLoopOffset */;
1105
+ this.variables.globalContext[key] = val;
1106
+ }
1107
+ getNextLoopOffset(nodeId) {
1108
+ const key = nodeId + "NextLoopOffset" /* BaseActionQueueType.NextLoopOffset */;
1109
+ return this.variables.globalContext[key];
1110
+ }
1111
+ resetNextLoopOffset(nodeId) {
1112
+ const key = nodeId + "NextLoopOffset" /* BaseActionQueueType.NextLoopOffset */;
1113
+ delete this.variables.globalContext[key];
1114
+ }
1115
+ /**
1116
+ * 初始化循环次数
1117
+ * @param nodeId 节点id
1118
+ */
1119
+ initLoopCount(nodeId) {
1120
+ const actualLoopValuesKey = nodeId + "_loop_count" /* BaseActionQueueType.LoopCount */;
1121
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1122
+ }
1123
+ /**
1124
+ * 累加循环次数
1125
+ * @param nodeId 节点id
1126
+ */
1127
+ addLoopCount(nodeId) {
1128
+ const actualLoopValuesKey = nodeId + "_loop_count" /* BaseActionQueueType.LoopCount */;
1129
+ if (this.variables.globalContext[actualLoopValuesKey] === undefined) {
1130
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1131
+ }
1132
+ this.variables.globalContext[actualLoopValuesKey] += 1;
1133
+ }
1134
+ /**
1135
+ * 获取循环次数
1136
+ * @param nodeId 节点id
1137
+ */
1138
+ getLoopCount(nodeId) {
1139
+ const actualLoopValuesKey = nodeId + "_loop_count" /* BaseActionQueueType.LoopCount */;
1140
+ if (this.variables.globalContext[actualLoopValuesKey] == undefined) {
1141
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1142
+ }
1143
+ return this.variables.globalContext[actualLoopValuesKey];
1144
+ }
1145
+ /**
1146
+ * 初始化连续无效翻页计数
1147
+ * @param nodeId 节点id
1148
+ */
1149
+ initContinuousInvalidPageCount(nodeId) {
1150
+ const actualLoopValuesKey = nodeId + "_continuous_invalid_page_count" /* BaseActionQueueType.ContinuousInvalidPageCount */;
1151
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1152
+ }
1153
+ /**
1154
+ * 添加连续无效翻页计数
1155
+ * @param nodeId 节点id
1156
+ */
1157
+ addContinuousInvalidPageCount(nodeId) {
1158
+ const actualLoopValuesKey = nodeId + "_continuous_invalid_page_count" /* BaseActionQueueType.ContinuousInvalidPageCount */;
1159
+ if (this.variables.globalContext[actualLoopValuesKey] === undefined) {
1160
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1161
+ }
1162
+ this.variables.globalContext[actualLoopValuesKey] += 1;
1163
+ }
1164
+ /**
1165
+ * 获取连续无效翻页计数
1166
+ * @param nodeId 节点id
1167
+ */
1168
+ getContinuousInvalidPageCount(nodeId) {
1169
+ const actualLoopValuesKey = nodeId + "_continuous_invalid_page_count" /* BaseActionQueueType.ContinuousInvalidPageCount */;
1170
+ if (this.variables.globalContext[actualLoopValuesKey] == undefined) {
1171
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1172
+ }
1173
+ return this.variables.globalContext[actualLoopValuesKey];
1174
+ }
1175
+ /**
1176
+ * 初始化,连续循环点击加载更多按钮,一直没有新数据的循环次数
1177
+ * @param nodeId 节点id
1178
+ */
1179
+ initContinuousClickLoadNoNewDataCount(nodeId) {
1180
+ const actualLoopValuesKey = nodeId + "_continuous_click_load_no_new_data_count" /* BaseActionQueueType.ContinuousClickLoadNoNewDataCount */;
1181
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1182
+ }
1183
+ /**
1184
+ * 累加,连续循环点击加载更多按钮,一直没有新数据的循环次数
1185
+ * @param nodeId 节点id
1186
+ */
1187
+ addContinuousClickLoadNoNewDataCount(nodeId) {
1188
+ const actualLoopValuesKey = nodeId + "_continuous_click_load_no_new_data_count" /* BaseActionQueueType.ContinuousClickLoadNoNewDataCount */;
1189
+ if (this.variables.globalContext[actualLoopValuesKey] === undefined) {
1190
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1191
+ }
1192
+ this.variables.globalContext[actualLoopValuesKey] += 1;
1193
+ }
1194
+ /**
1195
+ * 获取,连续循环点击加载更多按钮,一直没有新数据的循环次数
1196
+ * @param nodeId 节点id
1197
+ */
1198
+ getContinuousClickLoadNoNewDataCount(nodeId) {
1199
+ const actualLoopValuesKey = nodeId + "_continuous_click_load_no_new_data_count" /* BaseActionQueueType.ContinuousClickLoadNoNewDataCount */;
1200
+ if (this.variables.globalContext[actualLoopValuesKey] == undefined) {
1201
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1202
+ }
1203
+ return this.variables.globalContext[actualLoopValuesKey];
1204
+ }
1205
+ /**
1206
+ * 初始化,连续滚动网页,滚动条高度一只没有变化的循环次数
1207
+ * @param nodeId 节点id
1208
+ */
1209
+ initContinuousScrollTopFixedWebCount(nodeId) {
1210
+ const actualLoopValuesKey = nodeId + "_continuous_scroll_top_fixed_web_count" /* BaseActionQueueType.ContinuousScrollTopFixedWebCount */;
1211
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1212
+ }
1213
+ /**
1214
+ * 累加,连续滚动网页,滚动条高度一只没有变化的循环次数
1215
+ * @param nodeId 节点id
1216
+ */
1217
+ addContinuousScrollTopFixedWebCount(nodeId, num) {
1218
+ const actualLoopValuesKey = nodeId + "_continuous_scroll_top_fixed_web_count" /* BaseActionQueueType.ContinuousScrollTopFixedWebCount */;
1219
+ if (this.variables.globalContext[actualLoopValuesKey] === undefined) {
1220
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1221
+ }
1222
+ if (!num) {
1223
+ num = 1;
1224
+ }
1225
+ this.variables.globalContext[actualLoopValuesKey] += num;
1226
+ }
1227
+ /**
1228
+ * 获取,连续滚动网页,滚动条高度一只没有变化的循环次数
1229
+ * @param nodeId 节点id
1230
+ */
1231
+ getContinuousScrollTopFixedWebCount(nodeId) {
1232
+ const actualLoopValuesKey = nodeId + "_continuous_scroll_top_fixed_web_count" /* BaseActionQueueType.ContinuousScrollTopFixedWebCount */;
1233
+ if (this.variables.globalContext[actualLoopValuesKey] == undefined) {
1234
+ this.variables.globalContext[actualLoopValuesKey] = 0;
1235
+ }
1236
+ return this.variables.globalContext[actualLoopValuesKey];
1237
+ }
1238
+ /**
1239
+ * 缓存网页滚动条距离顶部的高度
1240
+ * @param nodeId 节点id
1241
+ * @param top 网页滚动条距离顶部的高度
1242
+ */
1243
+ setWebScrollTopTemp(nodeId, top) {
1244
+ const actualLoopValuesKey = nodeId + "_web_scroll_top_temp" /* BaseActionQueueType.WebScrollTopTemp */;
1245
+ this.variables.globalContext[actualLoopValuesKey] = top;
1246
+ }
1247
+ /**
1248
+ * 获取网页滚动条距离顶部的高度
1249
+ * @param nodeId 节点id
1250
+ */
1251
+ getWebScrollTopTemp(nodeId) {
1252
+ const actualLoopValuesKey = nodeId + "_web_scroll_top_temp" /* BaseActionQueueType.WebScrollTopTemp */;
1253
+ return this.variables.globalContext[actualLoopValuesKey];
1254
+ }
1255
+ /**
1256
+ *
1257
+ * @param nodeId
1258
+ */
1259
+ setWebDocumentHeightTemp(nodeId, height) {
1260
+ const actualLoopValuesKey = nodeId + "_web_document_height_temp" /* BaseActionQueueType.WebDocumentHeight */;
1261
+ this.variables.globalContext[actualLoopValuesKey] = height;
1262
+ }
1263
+ /**
1264
+ * 获取到网页高度
1265
+ * @param nodeId 节点id
1266
+ */
1267
+ getWebDocumentHeightTemp(nodeId) {
1268
+ const actualLoopValuesKey = nodeId + "_web_document_height_temp" /* BaseActionQueueType.WebDocumentHeight */;
1269
+ return this.variables.globalContext[actualLoopValuesKey];
1270
+ }
1271
+ /**
1272
+ * 设置当前循环是否需要跳过
1273
+ * @param nodeId
1274
+ * @param isSkip
1275
+ * @param isOnlySkipOneLoop
1276
+ * @param isClickNotFound
1277
+ */
1278
+ setIsSkipCurrentLoop(nodeId, isSkip, isOnlySkipOneLoop = false, isClickNotFound = false) {
1279
+ const actualCurrentLoopIsSkip = nodeId + "_current_loop_isskip" /* BaseActionQueueType.CurrentLoopIsSkipFlag */;
1280
+ this.variables.globalContext[actualCurrentLoopIsSkip] = isSkip;
1281
+ const actualIsOnlySkipOneLoop = nodeId + "_is_only_skip_one_loop" /* BaseActionQueueType.IsOnlySkipOneLoopFlag */;
1282
+ this.variables.globalContext[actualIsOnlySkipOneLoop] = isOnlySkipOneLoop;
1283
+ const actualIsClickNotFound = nodeId + "_is_click_not_found" /* BaseActionQueueType.IsClickNotFoundFlag */;
1284
+ // 是否是因为点击步骤未找到而跳过的
1285
+ this.variables.globalContext[actualIsClickNotFound] = isClickNotFound;
1286
+ if (isSkip && !isOnlySkipOneLoop) {
1287
+ this.setLoopValues(nodeId, []);
1288
+ }
1289
+ }
1290
+ // 获取当前循环是否要因为点击步骤未找到点击元素而跳过
1291
+ getIsClickNotFound() {
1292
+ const nodeId = this.config.targetQueue || this.activity.parentContext.id;
1293
+ let isClickNotFound = this.variables.globalContext[nodeId + "_is_click_not_found" /* BaseActionQueueType.IsClickNotFoundFlag */];
1294
+ if (isClickNotFound == undefined) {
1295
+ isClickNotFound = false;
1296
+ }
1297
+ return isClickNotFound;
1298
+ }
1299
+ deleteIsSkipCurrentLoop(nodeId) {
1300
+ const actualCurrentLoopIsSkip = nodeId + "_current_loop_isskip" /* BaseActionQueueType.CurrentLoopIsSkipFlag */;
1301
+ if (this.variables.globalContext[actualCurrentLoopIsSkip]) {
1302
+ delete this.variables.globalContext[actualCurrentLoopIsSkip];
1303
+ }
1304
+ }
1305
+ // 设置跳过当前之后所有的action(除了循环),直到下一次该循环下一个项的时候才重置
1306
+ setIsSkipActionUtilNextLoop(nodeId, isSkip = false) {
1307
+ this.variables.globalContext[nodeId + "_current_is_skip_action_util_next_loop" /* BaseActionQueueType.CurrentIsSkipActionUtilNextLoopFlag */] = isSkip;
1308
+ }
1309
+ getIsSkipActionUtilNextLoop(nodeId) {
1310
+ return this.variables.globalContext[nodeId + "_current_is_skip_action_util_next_loop" /* BaseActionQueueType.CurrentIsSkipActionUtilNextLoopFlag */];
1311
+ }
1312
+ //获取是否跳过指定循环
1313
+ getIsSkiptLoop(nodeId) {
1314
+ let isSkip = this.variables.globalContext[nodeId + "_current_loop_isskip" /* BaseActionQueueType.CurrentLoopIsSkipFlag */];
1315
+ if (isSkip == undefined) {
1316
+ isSkip = false;
1317
+ }
1318
+ return isSkip;
1319
+ }
1320
+ getIsSkipCurrentLoop() {
1321
+ const nodeId = this.config.targetQueue || this.activity.parentContext.id;
1322
+ return this.getIsSkiptLoop(nodeId);
1323
+ }
1324
+ getIsOnlySkipOneLoop() {
1325
+ const nodeId = this.config.targetQueue || this.activity.parentContext.id;
1326
+ let isOnlySkipOneLoop = this.variables.globalContext[nodeId + "_is_only_skip_one_loop" /* BaseActionQueueType.IsOnlySkipOneLoopFlag */];
1327
+ if (isOnlySkipOneLoop == undefined) {
1328
+ isOnlySkipOneLoop = false;
1329
+ }
1330
+ return isOnlySkipOneLoop;
1331
+ }
1332
+ resetIsOnlySkipOneLoop() {
1333
+ const nodeId = this.config.targetQueue || this.activity.parentContext.id;
1334
+ this.variables.globalContext[nodeId + "_is_only_skip_one_loop" /* BaseActionQueueType.IsOnlySkipOneLoopFlag */] = undefined;
1335
+ this.variables.globalContext[nodeId + "_is_click_not_found" /* BaseActionQueueType.IsClickNotFoundFlag */] = undefined;
1336
+ }
1337
+ getNodeId() {
1338
+ return this.config.targetQueue || this.activity.parentContext.id;
1339
+ }
1340
+ /**
1341
+ * 加载新页面后设置值(非ajax),为了后面为加载超时做判断依据
1342
+ * @param type 当前的状态
1343
+ */
1344
+ setRetryTypeState(type) {
1345
+ this.variables.globalContext['current_retryType'] = type;
1346
+ }
1347
+ /**
1348
+ * 获取是否加载的状态,获取后删除存储的状态
1349
+ */
1350
+ popIsLoadedState() {
1351
+ const r = this.variables.globalContext['current_retryType'];
1352
+ delete this.variables.globalContext['current_retryType'];
1353
+ return r;
1354
+ }
1355
+ /**
1356
+ * @param waitItemXpath 等待的xpath
1357
+ * @param waitTimeMS 等待的时间 默认20秒
1358
+ */
1359
+ setPageActionWaitXpathTime(waitItemXpath, waitTimeMS = 20000) {
1360
+ // const url = this.workflow.browser.getURL()
1361
+ // const urlHash = Math.abs(hashCode(url)).toString()
1362
+ // const xpathHash = Math.abs(hashCode(waitItemXpath)).toString()
1363
+ // const key = `page_${urlHash}_action_${this.id}_waitxpath_${xpathHash}_waittime`
1364
+ // this.variables.globalContext[key] = waitTimeMS.toString()
1365
+ }
1366
+ getPageActionWaitXpathTime(waitItemXpath) {
1367
+ // const url = this.workflow.browser.getURL()
1368
+ // const urlHash = Math.abs(hashCode(url)).toString()
1369
+ // const xpathHash = Math.abs(hashCode(waitItemXpath)).toString()
1370
+ // const key = `page_${urlHash}_action_${this.id}_waitxpath_${xpathHash}_waittime`
1371
+ // const r = this.variables.globalContext[key]
1372
+ // return isNullOrEmpty(r) ? 0 : Number(r)
1373
+ }
1374
+ getXpathStrategy(key) {
1375
+ if (!key) {
1376
+ return undefined;
1377
+ }
1378
+ let item = this.loopXpathStrategyMap.get(key);
1379
+ if (!item) {
1380
+ item = 100;
1381
+ this.loopXpathStrategyMap.set(key, item);
1382
+ }
1383
+ return item;
1384
+ }
1385
+ setXpathStratey(key, xpathItem) {
1386
+ if (xpathItem > 100) {
1387
+ xpathItem = 100;
1388
+ }
1389
+ this.loopXpathStrategyMap.set(key, xpathItem);
1390
+ }
1391
+ //等待一些元素,尽可能原则
1392
+ async awaitElement(elementXPath) {
1393
+ const exist = false;
1394
+ // //等待200毫秒后在做处理
1395
+ // let num = this.getXpathStrategy(elementXPath.AbsXpath)
1396
+ // if (num != 0) {
1397
+ // for (let i = 0; i < num; i++) {
1398
+ // if (!this.workflow.browser.isWaitRequest()) {
1399
+ // //马上进行一次检测
1400
+ // exist = await this.workflow.browser.existElement(elementXPath)
1401
+ // if (!exist) {
1402
+ // //结束后还不存在,那么可以进行消减原则
1403
+ // num = num / 4
1404
+ // if (num < 10) {
1405
+ // num = 0
1406
+ // }
1407
+ // this.setXpathStratey(elementXPath.AbsXpath, num)
1408
+ // }
1409
+ // break
1410
+ // }
1411
+ // //500毫秒检测一次
1412
+ // if (i % 5 == 0) {
1413
+ // exist = await this.workflow.browser.existElement(elementXPath)
1414
+ // if (exist) {
1415
+ // break
1416
+ // }
1417
+ // }
1418
+ // await this.sleep(100)
1419
+ // }
1420
+ // }
1421
+ // //如果还是不存在,那么再次等200ms
1422
+ // if (!exist) {
1423
+ // await this.sleep(200)
1424
+ // exist = await this.workflow.browser.existElement(elementXPath)
1425
+ // }
1426
+ // if (exist) {
1427
+ // //重置原则
1428
+ // this.setXpathStratey(elementXPath.AbsXpath, 100)
1429
+ // }
1430
+ return exist;
1431
+ }
1432
+ //skip 的意思是没有使用loopitem这么一说,只有condition 有这么一说
1433
+ async conditionCheck(e, page, skip = false) {
1434
+ //可能存在还没有步骤打开过网页,浏览器page不存在的情况
1435
+ // if (e.navigateType !== NavigateType.OpenJson && this.workflow.browser.getPageCount() == 0) {
1436
+ // return false
1437
+ // }
1438
+ if (e.checkType == "ContainItem" /* RetryConditionType.ContainItem */ ||
1439
+ e.checkType == "ContainText" /* RetryConditionType.ContainText */ ||
1440
+ e.checkType == "URLContain" /* RetryConditionType.URLContain */) {
1441
+ if (!e.checkValue) {
1442
+ return false;
1443
+ }
1444
+ }
1445
+ let isMatch = false;
1446
+ if (e.checkType == "ContainItem" /* RetryConditionType.ContainItem */) {
1447
+ const currentItem = this.config.getElementXPath(e.checkValue);
1448
+ if (e.actionConfig.useLoopItem && !skip) {
1449
+ if (currentItem && !(0, utils_1.isNullOrEmpty)(currentItem.AbsXpath)) {
1450
+ const loopItem = e.actionConfig.loopItem;
1451
+ const absXpath = loopItem.AbsXpath + currentItem.AbsXpath;
1452
+ isMatch =
1453
+ !!(await (0, Operations_1.getElement)(new actionItem_1.ActionItem(absXpath, loopItem.IsIFrame, loopItem.IFrameAbsXPath), page)) ||
1454
+ !!(await (0, Operations_1.getElement)(new actionItem_1.ActionItem(currentItem.AbsXpath, loopItem.IsIFrame, loopItem.IFrameAbsXPath), page));
1455
+ }
1456
+ }
1457
+ else {
1458
+ isMatch = !!(await (0, Operations_1.getElement)(currentItem, page));
1459
+ }
1460
+ }
1461
+ else if (e.checkType == "ContainText" /* RetryConditionType.ContainText */) {
1462
+ let content = '';
1463
+ if (e.actionConfig.useLoopItem && !skip) {
1464
+ const loopItem = e.actionConfig.loopItem;
1465
+ if (loopItem)
1466
+ content = await this.extractElementData(loopItem, (ele) => ele.innerText, page);
1467
+ }
1468
+ else {
1469
+ content = await page.$eval('body', (element) => element.innerText);
1470
+ }
1471
+ isMatch = content && content.indexOf(e.checkValue) > -1;
1472
+ }
1473
+ else if (e.checkType == "URLContain" /* RetryConditionType.URLContain */) {
1474
+ const url = page.url();
1475
+ isMatch = url.indexOf(e.checkValue) > -1;
1476
+ }
1477
+ else if (e.checkType == "Multiple" /* RetryConditionType.Multiple */ &&
1478
+ e.retryConditions) {
1479
+ for (const con of e.retryConditions) {
1480
+ isMatch =
1481
+ e.navigateType == "OpenJson" /* NavigateType.OpenJson */
1482
+ ? this.checkJSONContains(con)
1483
+ : await this.checkPageContains(con, page);
1484
+ if (!con.containsOrNot) {
1485
+ isMatch = !isMatch;
1486
+ }
1487
+ if (isMatch) {
1488
+ break;
1489
+ }
1490
+ }
1491
+ }
1492
+ return isMatch;
1493
+ }
1494
+ async extractElementData(actionItem, extractFn, page) {
1495
+ var _a;
1496
+ try {
1497
+ // 统一复用 Operations 里的元素执行入口:
1498
+ // 1. 主文档 / iframe 走同一套路径
1499
+ // 2. 瞬时 execution context 错误会触发轻量重试
1500
+ // 3. 这里仍保持旧语义,非瞬时错误最终按空字符串处理;
1501
+ // 但瞬时 context 错误必须继续往上抛,不能在这里被吞成“空字段”。
1502
+ return ((_a = (await (0, Operations_1.processElement)(actionItem, page, '$eval', extractFn))) !== null && _a !== void 0 ? _a : '');
1503
+ }
1504
+ catch (error) {
1505
+ await this.checkPause();
1506
+ if ((0, Operations_1.isTransientContextError)(error)) {
1507
+ throw error;
1508
+ }
1509
+ return '';
1510
+ }
1511
+ }
1512
+ async checkPageContains({ conditionType, containsOrNot, mainValue, minorValue }, page) {
1513
+ let isMatch = false;
1514
+ switch (conditionType) {
1515
+ case "ContainText" /* RetryConditionType.ContainText */:
1516
+ this.log(enums_1.LogKey.Common.Retry.Text[containsOrNot ? 'Found' : 'NotFound'], this.name, mainValue);
1517
+ isMatch = await page.evaluate((searchText) => {
1518
+ return document.body.innerText.includes(searchText);
1519
+ }, mainValue);
1520
+ break;
1521
+ case "URLContain" /* RetryConditionType.URLContain */:
1522
+ this.log(enums_1.LogKey.Common.Retry.URL[containsOrNot ? 'Found' : 'NotFound'], this.name, mainValue);
1523
+ const url = page.url();
1524
+ isMatch = url && url.indexOf(mainValue) > -1;
1525
+ break;
1526
+ case "XPathContain" /* RetryConditionType.XPathContain */:
1527
+ this.log(enums_1.LogKey.Common.Retry.XPath[containsOrNot ? 'Found' : 'NotFound'], this.name, mainValue);
1528
+ isMatch = !!(await (0, Operations_1.getElement)(new actionItem_1.ActionItem(mainValue, !!minorValue, minorValue), page));
1529
+ break;
1530
+ }
1531
+ return isMatch;
1532
+ }
1533
+ checkJSONContains(retryCondition) {
1534
+ let contains = false;
1535
+ switch (retryCondition.conditionType) {
1536
+ case "ContainText" /* RetryConditionType.ContainText */:
1537
+ {
1538
+ const content = this.browserProxy.jsonParser.originText;
1539
+ contains = content && content.indexOf(retryCondition.mainValue) > -1;
1540
+ }
1541
+ break;
1542
+ case "URLContain" /* RetryConditionType.URLContain */:
1543
+ {
1544
+ const url = this.browserProxy.jsonParser.currentUrl;
1545
+ contains = url && url.indexOf(retryCondition.mainValue) > -1;
1546
+ }
1547
+ break;
1548
+ case "XPathContain" /* RetryConditionType.XPathContain */:
1549
+ {
1550
+ contains =
1551
+ this.browserProxy.jsonParser.getNode(retryCondition.mainValue) !=
1552
+ undefined;
1553
+ }
1554
+ break;
1555
+ }
1556
+ return contains;
1557
+ }
1558
+ }
1559
+ exports.default = BaseAction;