@epsilon-asi/actors 0.0.1

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 (381) hide show
  1. package/.ai/generators/_template.ts +37 -0
  2. package/.ai/generators/abstract.ts +24 -0
  3. package/.ai/generators/actor-task-form-filler.ts +140 -0
  4. package/.ai/generators/actor-task.ts +122 -0
  5. package/.ai/generators/auth-core.ts +126 -0
  6. package/.ai/generators/browser-runtime.ts +114 -0
  7. package/.ai/generators/cli-command.ts +96 -0
  8. package/.ai/generators/core-framework.ts +80 -0
  9. package/.ai/generators/docs.ts +92 -0
  10. package/.ai/generators/error-logging.ts +102 -0
  11. package/.ai/generators/extraction-helper.ts +96 -0
  12. package/.ai/generators/interaction-behavior.ts +129 -0
  13. package/.ai/generators/site-actor.ts +125 -0
  14. package/.ai/generators/site-login-flow.ts +117 -0
  15. package/.ai/generators/unit-test.ts +109 -0
  16. package/.ai/workflows/_template.ts +20 -0
  17. package/.ai/workflows/starter.ts +20 -0
  18. package/README.md +435 -0
  19. package/ai-gen.config.ts +67 -0
  20. package/dist/auth/AuthStateDetector.d.ts +6 -0
  21. package/dist/auth/AuthStateDetector.d.ts.map +1 -0
  22. package/dist/auth/AuthStateDetector.js +14 -0
  23. package/dist/auth/AuthStateDetector.js.map +1 -0
  24. package/dist/auth/CredentialsProvider.d.ts +22 -0
  25. package/dist/auth/CredentialsProvider.d.ts.map +1 -0
  26. package/dist/auth/CredentialsProvider.js +30 -0
  27. package/dist/auth/CredentialsProvider.js.map +1 -0
  28. package/dist/auth/LoginFlow.d.ts +27 -0
  29. package/dist/auth/LoginFlow.d.ts.map +1 -0
  30. package/dist/auth/LoginFlow.js +233 -0
  31. package/dist/auth/LoginFlow.js.map +1 -0
  32. package/dist/auth/LoginFlow.types.d.ts +123 -0
  33. package/dist/auth/LoginFlow.types.d.ts.map +1 -0
  34. package/dist/auth/LoginFlow.types.js +7 -0
  35. package/dist/auth/LoginFlow.types.js.map +1 -0
  36. package/dist/auth/SessionStore.d.ts +16 -0
  37. package/dist/auth/SessionStore.d.ts.map +1 -0
  38. package/dist/auth/SessionStore.js +8 -0
  39. package/dist/auth/SessionStore.js.map +1 -0
  40. package/dist/auth/index.d.ts +6 -0
  41. package/dist/auth/index.d.ts.map +1 -0
  42. package/dist/auth/index.js +6 -0
  43. package/dist/auth/index.js.map +1 -0
  44. package/dist/browser/BrowserFactory.d.ts +16 -0
  45. package/dist/browser/BrowserFactory.d.ts.map +1 -0
  46. package/dist/browser/BrowserFactory.js +209 -0
  47. package/dist/browser/BrowserFactory.js.map +1 -0
  48. package/dist/browser/BrowserSession.d.ts +15 -0
  49. package/dist/browser/BrowserSession.d.ts.map +1 -0
  50. package/dist/browser/BrowserSession.js +42 -0
  51. package/dist/browser/BrowserSession.js.map +1 -0
  52. package/dist/browser/PuppeteerLike.d.ts +45 -0
  53. package/dist/browser/PuppeteerLike.d.ts.map +1 -0
  54. package/dist/browser/PuppeteerLike.js +10 -0
  55. package/dist/browser/PuppeteerLike.js.map +1 -0
  56. package/dist/browser/RuntimeConfig.d.ts +82 -0
  57. package/dist/browser/RuntimeConfig.d.ts.map +1 -0
  58. package/dist/browser/RuntimeConfig.js +64 -0
  59. package/dist/browser/RuntimeConfig.js.map +1 -0
  60. package/dist/browser/index.d.ts +6 -0
  61. package/dist/browser/index.d.ts.map +1 -0
  62. package/dist/browser/index.js +6 -0
  63. package/dist/browser/index.js.map +1 -0
  64. package/dist/browser/profileValidation.d.ts +6 -0
  65. package/dist/browser/profileValidation.d.ts.map +1 -0
  66. package/dist/browser/profileValidation.js +59 -0
  67. package/dist/browser/profileValidation.js.map +1 -0
  68. package/dist/cli/run.d.ts +3 -0
  69. package/dist/cli/run.d.ts.map +1 -0
  70. package/dist/cli/run.js +103 -0
  71. package/dist/cli/run.js.map +1 -0
  72. package/dist/core/Actor.d.ts +54 -0
  73. package/dist/core/Actor.d.ts.map +1 -0
  74. package/dist/core/Actor.js +68 -0
  75. package/dist/core/Actor.js.map +1 -0
  76. package/dist/core/ActorContext.d.ts +32 -0
  77. package/dist/core/ActorContext.d.ts.map +1 -0
  78. package/dist/core/ActorContext.js +2 -0
  79. package/dist/core/ActorContext.js.map +1 -0
  80. package/dist/core/ActorRegistry.d.ts +8 -0
  81. package/dist/core/ActorRegistry.d.ts.map +1 -0
  82. package/dist/core/ActorRegistry.js +22 -0
  83. package/dist/core/ActorRegistry.js.map +1 -0
  84. package/dist/core/ActorRunner.d.ts +57 -0
  85. package/dist/core/ActorRunner.d.ts.map +1 -0
  86. package/dist/core/ActorRunner.js +157 -0
  87. package/dist/core/ActorRunner.js.map +1 -0
  88. package/dist/core/defineActor.d.ts +3 -0
  89. package/dist/core/defineActor.d.ts.map +1 -0
  90. package/dist/core/defineActor.js +4 -0
  91. package/dist/core/defineActor.js.map +1 -0
  92. package/dist/core/index.d.ts +6 -0
  93. package/dist/core/index.d.ts.map +1 -0
  94. package/dist/core/index.js +6 -0
  95. package/dist/core/index.js.map +1 -0
  96. package/dist/errors/AuthError.d.ts +5 -0
  97. package/dist/errors/AuthError.d.ts.map +1 -0
  98. package/dist/errors/AuthError.js +7 -0
  99. package/dist/errors/AuthError.js.map +1 -0
  100. package/dist/errors/AutomationError.d.ts +17 -0
  101. package/dist/errors/AutomationError.d.ts.map +1 -0
  102. package/dist/errors/AutomationError.js +17 -0
  103. package/dist/errors/AutomationError.js.map +1 -0
  104. package/dist/errors/ConfigError.d.ts +5 -0
  105. package/dist/errors/ConfigError.d.ts.map +1 -0
  106. package/dist/errors/ConfigError.js +7 -0
  107. package/dist/errors/ConfigError.js.map +1 -0
  108. package/dist/errors/ExtractionError.d.ts +5 -0
  109. package/dist/errors/ExtractionError.d.ts.map +1 -0
  110. package/dist/errors/ExtractionError.js +7 -0
  111. package/dist/errors/ExtractionError.js.map +1 -0
  112. package/dist/errors/NavigationError.d.ts +5 -0
  113. package/dist/errors/NavigationError.d.ts.map +1 -0
  114. package/dist/errors/NavigationError.js +7 -0
  115. package/dist/errors/NavigationError.js.map +1 -0
  116. package/dist/errors/SelectorError.d.ts +6 -0
  117. package/dist/errors/SelectorError.d.ts.map +1 -0
  118. package/dist/errors/SelectorError.js +9 -0
  119. package/dist/errors/SelectorError.js.map +1 -0
  120. package/dist/errors/index.d.ts +7 -0
  121. package/dist/errors/index.d.ts.map +1 -0
  122. package/dist/errors/index.js +7 -0
  123. package/dist/errors/index.js.map +1 -0
  124. package/dist/extraction/Extractor.d.ts +16 -0
  125. package/dist/extraction/Extractor.d.ts.map +1 -0
  126. package/dist/extraction/Extractor.js +54 -0
  127. package/dist/extraction/Extractor.js.map +1 -0
  128. package/dist/extraction/Pagination.d.ts +16 -0
  129. package/dist/extraction/Pagination.d.ts.map +1 -0
  130. package/dist/extraction/Pagination.js +36 -0
  131. package/dist/extraction/Pagination.js.map +1 -0
  132. package/dist/extraction/index.d.ts +3 -0
  133. package/dist/extraction/index.d.ts.map +1 -0
  134. package/dist/extraction/index.js +3 -0
  135. package/dist/extraction/index.js.map +1 -0
  136. package/dist/index.d.ts +10 -0
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +10 -0
  139. package/dist/index.js.map +1 -0
  140. package/dist/interaction/FieldClearer.d.ts +7 -0
  141. package/dist/interaction/FieldClearer.d.ts.map +1 -0
  142. package/dist/interaction/FieldClearer.js +53 -0
  143. package/dist/interaction/FieldClearer.js.map +1 -0
  144. package/dist/interaction/Forms.d.ts +13 -0
  145. package/dist/interaction/Forms.d.ts.map +1 -0
  146. package/dist/interaction/Forms.js +22 -0
  147. package/dist/interaction/Forms.js.map +1 -0
  148. package/dist/interaction/GhostCursorAdapter.d.ts +27 -0
  149. package/dist/interaction/GhostCursorAdapter.d.ts.map +1 -0
  150. package/dist/interaction/GhostCursorAdapter.js +51 -0
  151. package/dist/interaction/GhostCursorAdapter.js.map +1 -0
  152. package/dist/interaction/HumanInteractor.d.ts +29 -0
  153. package/dist/interaction/HumanInteractor.d.ts.map +1 -0
  154. package/dist/interaction/HumanInteractor.js +2 -0
  155. package/dist/interaction/HumanInteractor.js.map +1 -0
  156. package/dist/interaction/HumanTyping.d.ts +43 -0
  157. package/dist/interaction/HumanTyping.d.ts.map +1 -0
  158. package/dist/interaction/HumanTyping.js +85 -0
  159. package/dist/interaction/HumanTyping.js.map +1 -0
  160. package/dist/interaction/NativePuppeteerInteractor.d.ts +20 -0
  161. package/dist/interaction/NativePuppeteerInteractor.d.ts.map +1 -0
  162. package/dist/interaction/NativePuppeteerInteractor.js +47 -0
  163. package/dist/interaction/NativePuppeteerInteractor.js.map +1 -0
  164. package/dist/interaction/Navigation.d.ts +17 -0
  165. package/dist/interaction/Navigation.d.ts.map +1 -0
  166. package/dist/interaction/Navigation.js +28 -0
  167. package/dist/interaction/Navigation.js.map +1 -0
  168. package/dist/interaction/PageAdapter.d.ts +32 -0
  169. package/dist/interaction/PageAdapter.d.ts.map +1 -0
  170. package/dist/interaction/PageAdapter.js +62 -0
  171. package/dist/interaction/PageAdapter.js.map +1 -0
  172. package/dist/interaction/Waits.d.ts +3 -0
  173. package/dist/interaction/Waits.d.ts.map +1 -0
  174. package/dist/interaction/Waits.js +4 -0
  175. package/dist/interaction/Waits.js.map +1 -0
  176. package/dist/interaction/index.d.ts +10 -0
  177. package/dist/interaction/index.d.ts.map +1 -0
  178. package/dist/interaction/index.js +10 -0
  179. package/dist/interaction/index.js.map +1 -0
  180. package/dist/interaction/textToKeystrokeEvents.d.ts +13 -0
  181. package/dist/interaction/textToKeystrokeEvents.d.ts.map +1 -0
  182. package/dist/interaction/textToKeystrokeEvents.js +15 -0
  183. package/dist/interaction/textToKeystrokeEvents.js.map +1 -0
  184. package/dist/logging/ConsoleLogger.d.ts +12 -0
  185. package/dist/logging/ConsoleLogger.d.ts.map +1 -0
  186. package/dist/logging/ConsoleLogger.js +42 -0
  187. package/dist/logging/ConsoleLogger.js.map +1 -0
  188. package/dist/logging/Logger.d.ts +14 -0
  189. package/dist/logging/Logger.d.ts.map +1 -0
  190. package/dist/logging/Logger.js +2 -0
  191. package/dist/logging/Logger.js.map +1 -0
  192. package/dist/logging/MemoryLogger.d.ts +10 -0
  193. package/dist/logging/MemoryLogger.d.ts.map +1 -0
  194. package/dist/logging/MemoryLogger.js +28 -0
  195. package/dist/logging/MemoryLogger.js.map +1 -0
  196. package/dist/logging/NullLogger.d.ts +8 -0
  197. package/dist/logging/NullLogger.d.ts.map +1 -0
  198. package/dist/logging/NullLogger.js +7 -0
  199. package/dist/logging/NullLogger.js.map +1 -0
  200. package/dist/logging/index.d.ts +5 -0
  201. package/dist/logging/index.d.ts.map +1 -0
  202. package/dist/logging/index.js +5 -0
  203. package/dist/logging/index.js.map +1 -0
  204. package/dist/sites/example/example.actor.d.ts +6 -0
  205. package/dist/sites/example/example.actor.d.ts.map +1 -0
  206. package/dist/sites/example/example.actor.js +47 -0
  207. package/dist/sites/example/example.actor.js.map +1 -0
  208. package/dist/sites/example/example.selectors.d.ts +18 -0
  209. package/dist/sites/example/example.selectors.d.ts.map +1 -0
  210. package/dist/sites/example/example.selectors.js +18 -0
  211. package/dist/sites/example/example.selectors.js.map +1 -0
  212. package/dist/sites/example/example.types.d.ts +16 -0
  213. package/dist/sites/example/example.types.d.ts.map +1 -0
  214. package/dist/sites/example/example.types.js +2 -0
  215. package/dist/sites/example/example.types.js.map +1 -0
  216. package/dist/sites/example/index.d.ts +4 -0
  217. package/dist/sites/example/index.d.ts.map +1 -0
  218. package/dist/sites/example/index.js +4 -0
  219. package/dist/sites/example/index.js.map +1 -0
  220. package/dist/sites/index.d.ts +4 -0
  221. package/dist/sites/index.d.ts.map +1 -0
  222. package/dist/sites/index.js +4 -0
  223. package/dist/sites/index.js.map +1 -0
  224. package/dist/sites/myvistage-com/index.d.ts +4 -0
  225. package/dist/sites/myvistage-com/index.d.ts.map +1 -0
  226. package/dist/sites/myvistage-com/index.js +4 -0
  227. package/dist/sites/myvistage-com/index.js.map +1 -0
  228. package/dist/sites/myvistage-com/myvistage-com.actor.d.ts +6 -0
  229. package/dist/sites/myvistage-com/myvistage-com.actor.d.ts.map +1 -0
  230. package/dist/sites/myvistage-com/myvistage-com.actor.js +44 -0
  231. package/dist/sites/myvistage-com/myvistage-com.actor.js.map +1 -0
  232. package/dist/sites/myvistage-com/myvistage-com.selectors.d.ts +15 -0
  233. package/dist/sites/myvistage-com/myvistage-com.selectors.d.ts.map +1 -0
  234. package/dist/sites/myvistage-com/myvistage-com.selectors.js +15 -0
  235. package/dist/sites/myvistage-com/myvistage-com.selectors.js.map +1 -0
  236. package/dist/sites/myvistage-com/myvistage-com.types.d.ts +16 -0
  237. package/dist/sites/myvistage-com/myvistage-com.types.d.ts.map +1 -0
  238. package/dist/sites/myvistage-com/myvistage-com.types.js +2 -0
  239. package/dist/sites/myvistage-com/myvistage-com.types.js.map +1 -0
  240. package/dist/sites/upwork-com/index.d.ts +6 -0
  241. package/dist/sites/upwork-com/index.d.ts.map +1 -0
  242. package/dist/sites/upwork-com/index.js +6 -0
  243. package/dist/sites/upwork-com/index.js.map +1 -0
  244. package/dist/sites/upwork-com/upwork-com.actor.d.ts +6 -0
  245. package/dist/sites/upwork-com/upwork-com.actor.d.ts.map +1 -0
  246. package/dist/sites/upwork-com/upwork-com.actor.js +82 -0
  247. package/dist/sites/upwork-com/upwork-com.actor.js.map +1 -0
  248. package/dist/sites/upwork-com/upwork-com.runner.d.ts +2 -0
  249. package/dist/sites/upwork-com/upwork-com.runner.d.ts.map +1 -0
  250. package/dist/sites/upwork-com/upwork-com.runner.js +14 -0
  251. package/dist/sites/upwork-com/upwork-com.runner.js.map +1 -0
  252. package/dist/sites/upwork-com/upwork-com.selectors.d.ts +11 -0
  253. package/dist/sites/upwork-com/upwork-com.selectors.d.ts.map +1 -0
  254. package/dist/sites/upwork-com/upwork-com.selectors.js +11 -0
  255. package/dist/sites/upwork-com/upwork-com.selectors.js.map +1 -0
  256. package/dist/sites/upwork-com/upwork-com.types.d.ts +88 -0
  257. package/dist/sites/upwork-com/upwork-com.types.d.ts.map +1 -0
  258. package/dist/sites/upwork-com/upwork-com.types.js +63 -0
  259. package/dist/sites/upwork-com/upwork-com.types.js.map +1 -0
  260. package/dist/sites/upwork-com/upwork-com.util.d.ts +4 -0
  261. package/dist/sites/upwork-com/upwork-com.util.d.ts.map +1 -0
  262. package/dist/sites/upwork-com/upwork-com.util.js +43 -0
  263. package/dist/sites/upwork-com/upwork-com.util.js.map +1 -0
  264. package/dist/utils/delay.d.ts +2 -0
  265. package/dist/utils/delay.d.ts.map +1 -0
  266. package/dist/utils/delay.js +6 -0
  267. package/dist/utils/delay.js.map +1 -0
  268. package/dist/utils/index.d.ts +6 -0
  269. package/dist/utils/index.d.ts.map +1 -0
  270. package/dist/utils/index.js +6 -0
  271. package/dist/utils/index.js.map +1 -0
  272. package/dist/utils/invariant.d.ts +2 -0
  273. package/dist/utils/invariant.d.ts.map +1 -0
  274. package/dist/utils/invariant.js +7 -0
  275. package/dist/utils/invariant.js.map +1 -0
  276. package/dist/utils/redact.d.ts +6 -0
  277. package/dist/utils/redact.d.ts.map +1 -0
  278. package/dist/utils/redact.js +40 -0
  279. package/dist/utils/redact.js.map +1 -0
  280. package/dist/utils/retry.d.ts +8 -0
  281. package/dist/utils/retry.d.ts.map +1 -0
  282. package/dist/utils/retry.js +23 -0
  283. package/dist/utils/retry.js.map +1 -0
  284. package/dist/utils/url.d.ts +2 -0
  285. package/dist/utils/url.d.ts.map +1 -0
  286. package/dist/utils/url.js +9 -0
  287. package/dist/utils/url.js.map +1 -0
  288. package/package.json +39 -0
  289. package/src/auth/AuthStateDetector.ts +18 -0
  290. package/src/auth/CredentialsProvider.ts +48 -0
  291. package/src/auth/LoginFlow.ts +332 -0
  292. package/src/auth/LoginFlow.types.ts +141 -0
  293. package/src/auth/SessionStore.ts +21 -0
  294. package/src/auth/index.ts +5 -0
  295. package/src/browser/BrowserFactory.ts +253 -0
  296. package/src/browser/BrowserSession.ts +50 -0
  297. package/src/browser/PuppeteerLike.ts +65 -0
  298. package/src/browser/RuntimeConfig.ts +152 -0
  299. package/src/browser/index.ts +5 -0
  300. package/src/browser/profileValidation.ts +73 -0
  301. package/src/cli/run.ts +112 -0
  302. package/src/core/Actor.ts +167 -0
  303. package/src/core/ActorContext.ts +34 -0
  304. package/src/core/ActorRegistry.ts +26 -0
  305. package/src/core/ActorRunner.ts +240 -0
  306. package/src/core/defineActor.ts +5 -0
  307. package/src/core/index.ts +5 -0
  308. package/src/errors/AuthError.ts +7 -0
  309. package/src/errors/AutomationError.ts +26 -0
  310. package/src/errors/ConfigError.ts +7 -0
  311. package/src/errors/ExtractionError.ts +7 -0
  312. package/src/errors/NavigationError.ts +7 -0
  313. package/src/errors/SelectorError.ts +10 -0
  314. package/src/errors/index.ts +6 -0
  315. package/src/extraction/Extractor.ts +65 -0
  316. package/src/extraction/Pagination.ts +47 -0
  317. package/src/extraction/index.ts +2 -0
  318. package/src/index.ts +9 -0
  319. package/src/interaction/FieldClearer.ts +73 -0
  320. package/src/interaction/Forms.ts +27 -0
  321. package/src/interaction/GhostCursorAdapter.ts +79 -0
  322. package/src/interaction/HumanInteractor.ts +32 -0
  323. package/src/interaction/HumanTyping.ts +157 -0
  324. package/src/interaction/NativePuppeteerInteractor.ts +68 -0
  325. package/src/interaction/Navigation.ts +37 -0
  326. package/src/interaction/PageAdapter.ts +86 -0
  327. package/src/interaction/Waits.ts +5 -0
  328. package/src/interaction/index.ts +9 -0
  329. package/src/logging/ConsoleLogger.ts +44 -0
  330. package/src/logging/Logger.ts +15 -0
  331. package/src/logging/MemoryLogger.ts +34 -0
  332. package/src/logging/NullLogger.ts +8 -0
  333. package/src/logging/index.ts +4 -0
  334. package/src/sites/example/example.actor.ts +53 -0
  335. package/src/sites/example/example.selectors.ts +17 -0
  336. package/src/sites/example/example.types.ts +18 -0
  337. package/src/sites/example/index.ts +3 -0
  338. package/src/sites/index.ts +3 -0
  339. package/src/sites/myvistage-com/index.ts +3 -0
  340. package/src/sites/myvistage-com/login-action-list.json +349 -0
  341. package/src/sites/myvistage-com/myvistage-com.actor.ts +50 -0
  342. package/src/sites/myvistage-com/myvistage-com.selectors.ts +14 -0
  343. package/src/sites/myvistage-com/myvistage-com.types.ts +18 -0
  344. package/src/sites/myvistage-com/post-comment-action.json +81 -0
  345. package/src/sites/upwork-com/index.ts +6 -0
  346. package/src/sites/upwork-com/upwork-com.actor.ts +97 -0
  347. package/src/sites/upwork-com/upwork-com.runner.ts +17 -0
  348. package/src/sites/upwork-com/upwork-com.selectors.ts +10 -0
  349. package/src/sites/upwork-com/upwork-com.types.ts +102 -0
  350. package/src/sites/upwork-com/upwork-com.util.ts +41 -0
  351. package/src/utils/delay.ts +4 -0
  352. package/src/utils/index.ts +5 -0
  353. package/src/utils/invariant.ts +7 -0
  354. package/src/utils/redact.ts +53 -0
  355. package/src/utils/retry.ts +31 -0
  356. package/src/utils/url.ts +7 -0
  357. package/tests/fixtures/FakeCredentialsProvider.ts +12 -0
  358. package/tests/fixtures/FakeCursor.ts +48 -0
  359. package/tests/fixtures/FakePage.ts +266 -0
  360. package/tests/fixtures/makeContext.ts +76 -0
  361. package/tests/unit/auth/AuthStateDetector.test.ts +80 -0
  362. package/tests/unit/auth/LoginFlow.test.ts +296 -0
  363. package/tests/unit/browser/BrowserFactory.test.ts +370 -0
  364. package/tests/unit/core/ActorRunner.test.ts +370 -0
  365. package/tests/unit/core/defineActor.test.ts +112 -0
  366. package/tests/unit/extraction/Extractor.test.ts +48 -0
  367. package/tests/unit/extraction/Pagination.test.ts +54 -0
  368. package/tests/unit/interaction/FieldClearer.test.ts +29 -0
  369. package/tests/unit/interaction/Forms.test.ts +35 -0
  370. package/tests/unit/interaction/GhostCursorAdapter.test.ts +68 -0
  371. package/tests/unit/interaction/HumanTyping.test.ts +54 -0
  372. package/tests/unit/interaction/NativePuppeteerInteractor.test.ts +22 -0
  373. package/tests/unit/interaction/PageAdapter.test.ts +25 -0
  374. package/tests/unit/logging/redact.test.ts +36 -0
  375. package/tests/unit/sites/myvistage-com.actor.test.ts +19 -0
  376. package/tests/unit/sites/myvistage-com.login.test.ts +22 -0
  377. package/tests/unit/sites/myvistage-com.postComment.test.ts +70 -0
  378. package/tests/unit/sites/upwork-com.login.test.ts +52 -0
  379. package/tsconfig.build.json +9 -0
  380. package/tsconfig.json +22 -0
  381. package/vitest.config.ts +12 -0
@@ -0,0 +1,86 @@
1
+ import type { WaitForOptions, WaitForSelectorOptions } from 'puppeteer-core';
2
+ import { SelectorError } from '../errors/SelectorError.js';
3
+ import type { PageLike } from '../browser/PuppeteerLike.js';
4
+
5
+ export interface PageAdapter {
6
+ goto(url: string, options?: WaitForOptions): Promise<void>;
7
+ waitFor(selector: string, options?: WaitForSelectorOptions): Promise<void>;
8
+ waitForNavigation(options?: WaitForOptions): Promise<void>;
9
+ exists(selector: string, options?: WaitForSelectorOptions): Promise<boolean>;
10
+ text(selector: string): Promise<string>;
11
+ textAll(selector: string): Promise<string[]>;
12
+ attr(selector: string, name: string): Promise<string | null>;
13
+ html(): Promise<string>;
14
+ url(): string;
15
+ title(): Promise<string>;
16
+ raw(): PageLike;
17
+ }
18
+
19
+ export class PuppeteerPageAdapter implements PageAdapter {
20
+ constructor(private readonly page: PageLike) {}
21
+
22
+ async goto(url: string, options: WaitForOptions = { waitUntil: 'domcontentloaded' }): Promise<void> {
23
+ await this.page.goto(url, options);
24
+ }
25
+
26
+ async waitFor(selector: string, options?: WaitForSelectorOptions): Promise<void> {
27
+ await this.page.waitForSelector(selector, options);
28
+ }
29
+
30
+ async waitForNavigation(options?: WaitForOptions): Promise<void> {
31
+ await this.page.waitForNavigation(options);
32
+ }
33
+
34
+ async exists(selector: string, options: WaitForSelectorOptions = { timeout: 1_000 }): Promise<boolean> {
35
+ try {
36
+ await this.page.waitForSelector(selector, options);
37
+ return true;
38
+ } catch {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ async text(selector: string): Promise<string> {
44
+ try {
45
+ const value = await this.page.$eval(selector, element => element.textContent ?? '');
46
+ return normalizeWhitespace(value);
47
+ } catch (error) {
48
+ throw new SelectorError(`Could not read text from selector: ${selector}`, selector, { cause: error });
49
+ }
50
+ }
51
+
52
+ async textAll(selector: string): Promise<string[]> {
53
+ const values = await this.page.$$eval(selector, elements =>
54
+ elements.map(element => element.textContent ?? '')
55
+ );
56
+ return values.map(normalizeWhitespace).filter(value => value.length > 0);
57
+ }
58
+
59
+ async attr(selector: string, name: string): Promise<string | null> {
60
+ try {
61
+ return await this.page.$eval(selector, (element, attrName) => element.getAttribute(String(attrName)), name);
62
+ } catch (error) {
63
+ throw new SelectorError(`Could not read attribute ${name} from selector: ${selector}`, selector, { cause: error });
64
+ }
65
+ }
66
+
67
+ async html(): Promise<string> {
68
+ return this.page.content();
69
+ }
70
+
71
+ url(): string {
72
+ return this.page.url();
73
+ }
74
+
75
+ title(): Promise<string> {
76
+ return this.page.title();
77
+ }
78
+
79
+ raw(): PageLike {
80
+ return this.page;
81
+ }
82
+ }
83
+
84
+ export function normalizeWhitespace(value: string): string {
85
+ return value.replace(/\s+/g, ' ').trim();
86
+ }
@@ -0,0 +1,5 @@
1
+ import type { PageAdapter } from './PageAdapter.js';
2
+
3
+ export async function waitUntilVisible(page: PageAdapter, selector: string, timeoutMs = 15_000): Promise<void> {
4
+ await page.waitFor(selector, { timeout: timeoutMs, visible: true });
5
+ }
@@ -0,0 +1,9 @@
1
+ export * from './HumanTyping.js';
2
+ export * from './FieldClearer.js';
3
+ export * from './Forms.js';
4
+ export * from './GhostCursorAdapter.js';
5
+ export * from './HumanInteractor.js';
6
+ export * from './NativePuppeteerInteractor.js';
7
+ export * from './Navigation.js';
8
+ export * from './PageAdapter.js';
9
+ export * from './Waits.js';
@@ -0,0 +1,44 @@
1
+ import { redact } from '../utils/redact.js';
2
+ import type { Logger, LogLevel } from './Logger.js';
3
+
4
+ export class ConsoleLogger implements Logger {
5
+ constructor(private readonly minimumLevel: LogLevel = 'info') {}
6
+
7
+ debug(message: string, meta?: Record<string, unknown>): void {
8
+ this.write('debug', message, meta);
9
+ }
10
+
11
+ info(message: string, meta?: Record<string, unknown>): void {
12
+ this.write('info', message, meta);
13
+ }
14
+
15
+ warn(message: string, meta?: Record<string, unknown>): void {
16
+ this.write('warn', message, meta);
17
+ }
18
+
19
+ error(message: string, meta?: Record<string, unknown>): void {
20
+ this.write('error', message, meta);
21
+ }
22
+
23
+ private write(level: LogLevel, message: string, meta?: Record<string, unknown>): void {
24
+ if (!this.shouldWrite(level)) return;
25
+
26
+ const safeMeta = meta === undefined ? undefined : redact(meta);
27
+ const payload = safeMeta === undefined ? '' : ` ${JSON.stringify(safeMeta)}`;
28
+ const line = `[${new Date().toISOString()}] ${level.toUpperCase()} ${message}${payload}`;
29
+
30
+ if (level === 'error') console.error(line);
31
+ else if (level === 'warn') console.warn(line);
32
+ else console.log(line);
33
+ }
34
+
35
+ private shouldWrite(level: LogLevel): boolean {
36
+ const weights: Record<LogLevel, number> = {
37
+ debug: 0,
38
+ info: 1,
39
+ warn: 2,
40
+ error: 3
41
+ };
42
+ return weights[level] >= weights[this.minimumLevel];
43
+ }
44
+ }
@@ -0,0 +1,15 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+
3
+ export interface LogRecord {
4
+ level: LogLevel;
5
+ message: string;
6
+ meta?: Record<string, unknown>;
7
+ timestamp: string;
8
+ }
9
+
10
+ export interface Logger {
11
+ debug(message: string, meta?: Record<string, unknown>): void;
12
+ info(message: string, meta?: Record<string, unknown>): void;
13
+ warn(message: string, meta?: Record<string, unknown>): void;
14
+ error(message: string, meta?: Record<string, unknown>): void;
15
+ }
@@ -0,0 +1,34 @@
1
+ import { redact } from '../utils/redact.js';
2
+ import type { Logger, LogLevel, LogRecord } from './Logger.js';
3
+
4
+ export class MemoryLogger implements Logger {
5
+ readonly records: LogRecord[] = [];
6
+
7
+ debug(message: string, meta?: Record<string, unknown>): void {
8
+ this.write('debug', message, meta);
9
+ }
10
+
11
+ info(message: string, meta?: Record<string, unknown>): void {
12
+ this.write('info', message, meta);
13
+ }
14
+
15
+ warn(message: string, meta?: Record<string, unknown>): void {
16
+ this.write('warn', message, meta);
17
+ }
18
+
19
+ error(message: string, meta?: Record<string, unknown>): void {
20
+ this.write('error', message, meta);
21
+ }
22
+
23
+ private write(level: LogLevel, message: string, meta?: Record<string, unknown>): void {
24
+ const record: LogRecord = {
25
+ level,
26
+ message,
27
+ timestamp: new Date().toISOString()
28
+ };
29
+ if (meta !== undefined) {
30
+ record.meta = redact(meta);
31
+ }
32
+ this.records.push(record);
33
+ }
34
+ }
@@ -0,0 +1,8 @@
1
+ import type { Logger } from './Logger.js';
2
+
3
+ export class NullLogger implements Logger {
4
+ debug(): void {}
5
+ info(): void {}
6
+ warn(): void {}
7
+ error(): void {}
8
+ }
@@ -0,0 +1,4 @@
1
+ export * from './ConsoleLogger.js';
2
+ export * from './Logger.js';
3
+ export * from './MemoryLogger.js';
4
+ export * from './NullLogger.js';
@@ -0,0 +1,53 @@
1
+ import { defineLoginFlow } from '../../auth/LoginFlow.types.js';
2
+ import { defineActor } from '../../core/defineActor.js';
3
+ import { defineFormFillerTask } from '../../core/Actor.js';
4
+ import { exampleSelectors } from './example.selectors.js';
5
+ import type {
6
+ DashboardRow,
7
+ ScrapeDashboardInput,
8
+ SubmitContactFormInput,
9
+ SubmitContactFormOutput
10
+ } from './example.types.js';
11
+
12
+ export const exampleActor = defineActor({
13
+ id: 'example',
14
+ baseUrl: 'https://example.com',
15
+ auth: defineLoginFlow({
16
+ loginUrl: '/login',
17
+ selectors: exampleSelectors.login,
18
+ credentials: { id: 'example' },
19
+ behavior: {
20
+ authCheckUrl: '/',
21
+ submitCausesNavigation: true,
22
+ loggedInTimeoutMs: 3_000,
23
+ clearFieldBeforeTyping: true,
24
+ typing: {
25
+ targetWordsPerMinute: 65,
26
+ intervalJitterMs: 18
27
+ }
28
+ }
29
+ }),
30
+ tasks: {
31
+ scrapeDashboard: async (context, input: ScrapeDashboardInput = {}): Promise<DashboardRow[]> => {
32
+ await context.nav.goto('/dashboard');
33
+ const rows = await context.extract.textList(exampleSelectors.dashboardRows);
34
+ return rows.slice(0, input.limit ?? rows.length).map(text => ({ text }));
35
+ },
36
+ submitContactForm: defineFormFillerTask<SubmitContactFormInput, SubmitContactFormOutput>({
37
+ url: '/contact',
38
+ fields: [
39
+ { selector: exampleSelectors.contactForm.name, inputKey: 'name' },
40
+ { selector: exampleSelectors.contactForm.email, inputKey: 'email' },
41
+ { selector: exampleSelectors.contactForm.company, inputKey: 'company', required: false },
42
+ { selector: exampleSelectors.contactForm.message, inputKey: 'message' }
43
+ ],
44
+ submit: {
45
+ selector: exampleSelectors.contactForm.submit,
46
+ waitForNavigation: true
47
+ },
48
+ onComplete: (_context, input) => ({
49
+ submittedEmail: input.email
50
+ })
51
+ })
52
+ }
53
+ });
@@ -0,0 +1,17 @@
1
+ export const exampleSelectors = {
2
+ login: {
3
+ username: '#email',
4
+ password: '#password',
5
+ submit: 'button[type="submit"]',
6
+ loggedInSignal: '[data-testid="account-menu"]',
7
+ errorMessage: '[data-testid="login-error"]'
8
+ },
9
+ dashboardRows: '[data-testid="dashboard-row"]',
10
+ contactForm: {
11
+ name: '#name',
12
+ email: '#email',
13
+ company: '#company',
14
+ message: '#message',
15
+ submit: 'button[type="submit"]'
16
+ }
17
+ } as const;
@@ -0,0 +1,18 @@
1
+ export interface ScrapeDashboardInput {
2
+ limit?: number;
3
+ }
4
+
5
+ export interface DashboardRow {
6
+ text: string;
7
+ }
8
+
9
+ export interface SubmitContactFormInput extends Record<string, string| undefined> {
10
+ name: string;
11
+ email: string;
12
+ company?: string;
13
+ message: string;
14
+ }
15
+
16
+ export interface SubmitContactFormOutput {
17
+ submittedEmail: string;
18
+ }
@@ -0,0 +1,3 @@
1
+ export * from './example.actor.js';
2
+ export * from './example.selectors.js';
3
+ export * from './example.types.js';
@@ -0,0 +1,3 @@
1
+ export * from './example/index.js';
2
+ export * from './myvistage-com/index.js';
3
+ export * from './upwork-com/index.js';
@@ -0,0 +1,3 @@
1
+ export * from './myvistage-com.actor.js';
2
+ export * from './myvistage-com.selectors.js';
3
+ export * from './myvistage-com.types.js';
@@ -0,0 +1,349 @@
1
+ [
2
+ {
3
+ "actionType": "click",
4
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
5
+ "id": "evt_1779455531515_6wy31i7k",
6
+ "input": null,
7
+ "metadata": {
8
+ "ariaLabel": null,
9
+ "button": 0,
10
+ "buttons": 0,
11
+ "clientX": 803,
12
+ "clientY": 812,
13
+ "id": null,
14
+ "inputType": "text",
15
+ "label": null,
16
+ "name": "username",
17
+ "pageX": 803,
18
+ "pageY": 812,
19
+ "role": null,
20
+ "sensitive": false,
21
+ "tagName": "input"
22
+ },
23
+ "selector": "[name=\"username\"]",
24
+ "sessionId": "session_1779455530258_v14hspgc",
25
+ "tagName": "input",
26
+ "text": null,
27
+ "timestamp": "2026-05-22T13:12:11.514Z",
28
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
29
+ },
30
+ {
31
+ "actionType": "input",
32
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
33
+ "id": "evt_1779455534236_cgkqak02",
34
+ "input": null,
35
+ "metadata": {
36
+ "ariaLabel": null,
37
+ "id": null,
38
+ "inputType": "text",
39
+ "label": null,
40
+ "name": "username",
41
+ "role": null,
42
+ "sensitive": false,
43
+ "tagName": "input",
44
+ "valueLength": null
45
+ },
46
+ "selector": "[name=\"username\"]",
47
+ "sessionId": "session_1779455530258_v14hspgc",
48
+ "tagName": "input",
49
+ "text": null,
50
+ "timestamp": "2026-05-22T13:12:13.882Z",
51
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
52
+ },
53
+ {
54
+ "actionType": "click",
55
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
56
+ "id": "evt_1779455535599_75xa0rlb",
57
+ "input": null,
58
+ "metadata": {
59
+ "ariaLabel": null,
60
+ "button": 0,
61
+ "buttons": 0,
62
+ "clientX": 744,
63
+ "clientY": 879,
64
+ "id": null,
65
+ "inputType": "password",
66
+ "label": null,
67
+ "name": "password",
68
+ "pageX": 744,
69
+ "pageY": 879,
70
+ "role": null,
71
+ "sensitive": true,
72
+ "tagName": "input"
73
+ },
74
+ "selector": "[name=\"password\"]",
75
+ "sessionId": "session_1779455530258_v14hspgc",
76
+ "tagName": "input",
77
+ "text": null,
78
+ "timestamp": "2026-05-22T13:12:15.598Z",
79
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
80
+ },
81
+ {
82
+ "actionType": "input",
83
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
84
+ "id": "evt_1779455538099_w9ie18ax",
85
+ "input": "[REDACTED_PASSWORD]",
86
+ "metadata": {
87
+ "ariaLabel": null,
88
+ "id": null,
89
+ "inputType": "password",
90
+ "label": null,
91
+ "name": "password",
92
+ "role": null,
93
+ "sensitive": true,
94
+ "tagName": "input",
95
+ "valueLength": 19
96
+ },
97
+ "selector": "[name=\"password\"]",
98
+ "sessionId": "session_1779455530258_v14hspgc",
99
+ "tagName": "input",
100
+ "text": null,
101
+ "timestamp": "2026-05-22T13:12:17.746Z",
102
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
103
+ },
104
+ {
105
+ "actionType": "click",
106
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
107
+ "id": "evt_1779455541057_1he6q8pn",
108
+ "input": null,
109
+ "metadata": {
110
+ "ariaLabel": null,
111
+ "button": 0,
112
+ "buttons": 0,
113
+ "clientX": 573,
114
+ "clientY": 987,
115
+ "id": "remember",
116
+ "inputType": "checkbox",
117
+ "label": "Remember Me",
118
+ "name": "remember",
119
+ "pageX": 573,
120
+ "pageY": 987,
121
+ "role": null,
122
+ "sensitive": false,
123
+ "tagName": "input"
124
+ },
125
+ "selector": "#remember",
126
+ "sessionId": "session_1779455530258_v14hspgc",
127
+ "tagName": "input",
128
+ "text": null,
129
+ "timestamp": "2026-05-22T13:12:21.055Z",
130
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
131
+ },
132
+ {
133
+ "actionType": "change",
134
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
135
+ "id": "evt_1779455541066_39y4uucs",
136
+ "input": {
137
+ "checked": true,
138
+ "value": "on"
139
+ },
140
+ "metadata": {
141
+ "ariaLabel": null,
142
+ "id": "remember",
143
+ "inputType": "checkbox",
144
+ "label": "Remember Me",
145
+ "name": "remember",
146
+ "role": null,
147
+ "sensitive": false,
148
+ "tagName": "input"
149
+ },
150
+ "selector": "#remember",
151
+ "sessionId": "session_1779455530258_v14hspgc",
152
+ "tagName": "input",
153
+ "text": null,
154
+ "timestamp": "2026-05-22T13:12:21.065Z",
155
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
156
+ },
157
+ {
158
+ "actionType": "click",
159
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
160
+ "id": "evt_1779455547807_eubpz6ir",
161
+ "input": null,
162
+ "metadata": {
163
+ "ariaLabel": null,
164
+ "button": 0,
165
+ "buttons": 0,
166
+ "clientX": 914,
167
+ "clientY": 424,
168
+ "id": "mv3login",
169
+ "inputType": null,
170
+ "label": "Username or email address Password Sign In Remember Me Forgot Username or Passwo…",
171
+ "name": null,
172
+ "pageX": 914,
173
+ "pageY": 424,
174
+ "role": null,
175
+ "sensitive": false,
176
+ "tagName": "section"
177
+ },
178
+ "selector": "#mv3login",
179
+ "sessionId": "session_1779455530258_v14hspgc",
180
+ "tagName": "section",
181
+ "text": "Username or email address Password Sign In Remember Me Forgot Username or Password? OR Sign in with Apple Sign in with G…",
182
+ "timestamp": "2026-05-22T13:12:27.806Z",
183
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
184
+ },
185
+ {
186
+ "actionType": "click",
187
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
188
+ "id": "evt_1779455551655_qfq2ca4a",
189
+ "input": null,
190
+ "metadata": {
191
+ "ariaLabel": null,
192
+ "button": 0,
193
+ "buttons": 0,
194
+ "clientX": 22,
195
+ "clientY": 20,
196
+ "id": "mv3login",
197
+ "inputType": null,
198
+ "label": "Username or email address Password Sign In Remember Me Forgot Username or Passwo…",
199
+ "name": null,
200
+ "pageX": 22,
201
+ "pageY": 20,
202
+ "role": null,
203
+ "sensitive": false,
204
+ "tagName": "section"
205
+ },
206
+ "selector": "#mv3login",
207
+ "sessionId": "session_1779455530258_v14hspgc",
208
+ "tagName": "section",
209
+ "text": "Username or email address Password Sign In Remember Me Forgot Username or Password? OR Sign in with Apple Sign in with G…",
210
+ "timestamp": "2026-05-22T13:12:31.654Z",
211
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
212
+ },
213
+ {
214
+ "actionType": "click",
215
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
216
+ "id": "evt_1779455552923_9h3cf6w9",
217
+ "input": null,
218
+ "metadata": {
219
+ "ariaLabel": null,
220
+ "button": 0,
221
+ "buttons": 0,
222
+ "clientX": 1349,
223
+ "clientY": 1523,
224
+ "id": "mv3login",
225
+ "inputType": null,
226
+ "label": "Username or email address Password Sign In Remember Me Forgot Username or Passwo…",
227
+ "name": null,
228
+ "pageX": 1349,
229
+ "pageY": 1523,
230
+ "role": null,
231
+ "sensitive": false,
232
+ "tagName": "section"
233
+ },
234
+ "selector": "#mv3login",
235
+ "sessionId": "session_1779455530258_v14hspgc",
236
+ "tagName": "section",
237
+ "text": "Username or email address Password Sign In Remember Me Forgot Username or Password? OR Sign in with Apple Sign in with G…",
238
+ "timestamp": "2026-05-22T13:12:32.922Z",
239
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
240
+ },
241
+ {
242
+ "actionType": "click",
243
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
244
+ "id": "evt_1779455553503_7rnjxvsu",
245
+ "input": null,
246
+ "metadata": {
247
+ "ariaLabel": null,
248
+ "button": 0,
249
+ "buttons": 0,
250
+ "clientX": 1357,
251
+ "clientY": 431,
252
+ "id": "mv3login",
253
+ "inputType": null,
254
+ "label": "Username or email address Password Sign In Remember Me Forgot Username or Passwo…",
255
+ "name": null,
256
+ "pageX": 1357,
257
+ "pageY": 431,
258
+ "role": null,
259
+ "sensitive": false,
260
+ "tagName": "section"
261
+ },
262
+ "selector": "#mv3login",
263
+ "sessionId": "session_1779455530258_v14hspgc",
264
+ "tagName": "section",
265
+ "text": "Username or email address Password Sign In Remember Me Forgot Username or Password? OR Sign in with Apple Sign in with G…",
266
+ "timestamp": "2026-05-22T13:12:33.501Z",
267
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
268
+ },
269
+ {
270
+ "actionType": "click",
271
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
272
+ "id": "evt_1779455554199_six37yxq",
273
+ "input": null,
274
+ "metadata": {
275
+ "ariaLabel": null,
276
+ "button": 0,
277
+ "buttons": 0,
278
+ "clientX": 128,
279
+ "clientY": 1767,
280
+ "id": "mv3login",
281
+ "inputType": null,
282
+ "label": "Username or email address Password Sign In Remember Me Forgot Username or Passwo…",
283
+ "name": null,
284
+ "pageX": 128,
285
+ "pageY": 1767,
286
+ "role": null,
287
+ "sensitive": false,
288
+ "tagName": "section"
289
+ },
290
+ "selector": "#mv3login",
291
+ "sessionId": "session_1779455530258_v14hspgc",
292
+ "tagName": "section",
293
+ "text": "Username or email address Password Sign In Remember Me Forgot Username or Password? OR Sign in with Apple Sign in with G…",
294
+ "timestamp": "2026-05-22T13:12:34.197Z",
295
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
296
+ },
297
+ {
298
+ "actionType": "click",
299
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
300
+ "id": "evt_1779455555501_qqkigiv2",
301
+ "input": null,
302
+ "metadata": {
303
+ "ariaLabel": null,
304
+ "button": 0,
305
+ "buttons": 0,
306
+ "clientX": 788,
307
+ "clientY": 938,
308
+ "id": null,
309
+ "inputType": "submit",
310
+ "label": "Sign In",
311
+ "name": null,
312
+ "pageX": 788,
313
+ "pageY": 938,
314
+ "role": null,
315
+ "sensitive": false,
316
+ "tagName": "button"
317
+ },
318
+ "selector": "div:nth-of-type(4) > button:nth-of-type(1)",
319
+ "sessionId": "session_1779455530258_v14hspgc",
320
+ "tagName": "button",
321
+ "text": "Sign In",
322
+ "timestamp": "2026-05-22T13:12:35.499Z",
323
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
324
+ },
325
+ {
326
+ "actionType": "submit",
327
+ "frameUrl": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1",
328
+ "id": "evt_1779455555507_cqah7sb6",
329
+ "input": null,
330
+ "metadata": {
331
+ "action": null,
332
+ "ariaLabel": null,
333
+ "id": "form-login",
334
+ "inputType": null,
335
+ "label": "Username or email address Password Sign In Remember Me Forgot Username or Passwo…",
336
+ "method": "post",
337
+ "name": "login",
338
+ "role": null,
339
+ "sensitive": false,
340
+ "tagName": "form"
341
+ },
342
+ "selector": "#form-login",
343
+ "sessionId": "session_1779455530258_v14hspgc",
344
+ "tagName": "form",
345
+ "text": "Username or email address Password Sign In Remember Me Forgot Username or Password? OR Sign in with Apple Sign in with G…",
346
+ "timestamp": "2026-05-22T13:12:35.506Z",
347
+ "url": "https://myvistage.com/?redirect_to=https%3A%2F%2Fmyvistage.com%2F%3Floggedout%3Dtrue%26wp_lang%3Den_US&reauth=1"
348
+ }
349
+ ]