@lhremote/core 0.8.0 → 0.10.0

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 (480) hide show
  1. package/dist/cdp/app-discovery.d.ts +57 -0
  2. package/dist/cdp/app-discovery.d.ts.map +1 -1
  3. package/dist/cdp/app-discovery.js +90 -7
  4. package/dist/cdp/app-discovery.js.map +1 -1
  5. package/dist/cdp/app-discovery.test.js +180 -9
  6. package/dist/cdp/app-discovery.test.js.map +1 -1
  7. package/dist/cdp/client.d.ts +8 -1
  8. package/dist/cdp/client.d.ts.map +1 -1
  9. package/dist/cdp/client.js +8 -1
  10. package/dist/cdp/client.js.map +1 -1
  11. package/dist/cdp/discovery.d.ts.map +1 -1
  12. package/dist/cdp/discovery.js +5 -1
  13. package/dist/cdp/discovery.js.map +1 -1
  14. package/dist/cdp/discovery.test.js +7 -0
  15. package/dist/cdp/discovery.test.js.map +1 -1
  16. package/dist/cdp/index.d.ts +1 -1
  17. package/dist/cdp/index.d.ts.map +1 -1
  18. package/dist/cdp/index.js +1 -1
  19. package/dist/cdp/index.js.map +1 -1
  20. package/dist/cdp/instance-discovery.d.ts.map +1 -1
  21. package/dist/cdp/instance-discovery.js +25 -10
  22. package/dist/cdp/instance-discovery.js.map +1 -1
  23. package/dist/cdp/instance-discovery.test.js +17 -0
  24. package/dist/cdp/instance-discovery.test.js.map +1 -1
  25. package/dist/cdp/testing/launch-chromium.d.ts +1 -1
  26. package/dist/cdp/testing/launch-chromium.js +2 -2
  27. package/dist/db/client.d.ts.map +1 -1
  28. package/dist/db/client.js +3 -0
  29. package/dist/db/client.js.map +1 -1
  30. package/dist/db/repositories/campaign-hard-delete.integration.test.js +4 -1
  31. package/dist/db/repositories/campaign-hard-delete.integration.test.js.map +1 -1
  32. package/dist/db/repositories/campaign.d.ts.map +1 -1
  33. package/dist/db/repositories/campaign.js +81 -33
  34. package/dist/db/repositories/campaign.js.map +1 -1
  35. package/dist/db/repositories/campaign.test.js +2 -2
  36. package/dist/db/repositories/collection-list.d.ts +11 -0
  37. package/dist/db/repositories/collection-list.d.ts.map +1 -1
  38. package/dist/db/repositories/collection-list.integration.test.js +6 -4
  39. package/dist/db/repositories/collection-list.integration.test.js.map +1 -1
  40. package/dist/db/repositories/collection-list.js +92 -2
  41. package/dist/db/repositories/collection-list.js.map +1 -1
  42. package/dist/db/testing/create-fixture.js +36 -2
  43. package/dist/db/testing/create-fixture.js.map +1 -1
  44. package/dist/index.d.ts +6 -6
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +6 -6
  47. package/dist/index.js.map +1 -1
  48. package/dist/linkedin/dom-automation-retry.test.d.ts +2 -0
  49. package/dist/linkedin/dom-automation-retry.test.d.ts.map +1 -0
  50. package/dist/linkedin/dom-automation-retry.test.js +51 -0
  51. package/dist/linkedin/dom-automation-retry.test.js.map +1 -0
  52. package/dist/linkedin/dom-automation.d.ts +166 -6
  53. package/dist/linkedin/dom-automation.d.ts.map +1 -1
  54. package/dist/linkedin/dom-automation.js +496 -21
  55. package/dist/linkedin/dom-automation.js.map +1 -1
  56. package/dist/linkedin/humanized-mouse.d.ts +69 -0
  57. package/dist/linkedin/humanized-mouse.d.ts.map +1 -0
  58. package/dist/linkedin/humanized-mouse.js +109 -0
  59. package/dist/linkedin/humanized-mouse.js.map +1 -0
  60. package/dist/linkedin/index.d.ts +3 -2
  61. package/dist/linkedin/index.d.ts.map +1 -1
  62. package/dist/linkedin/index.js +3 -2
  63. package/dist/linkedin/index.js.map +1 -1
  64. package/dist/linkedin/selectors.d.ts +74 -48
  65. package/dist/linkedin/selectors.d.ts.map +1 -1
  66. package/dist/linkedin/selectors.js +64 -41
  67. package/dist/linkedin/selectors.js.map +1 -1
  68. package/dist/operations/add-people-to-collection.d.ts +1 -1
  69. package/dist/operations/add-people-to-collection.d.ts.map +1 -1
  70. package/dist/operations/add-people-to-collection.js +3 -6
  71. package/dist/operations/add-people-to-collection.js.map +1 -1
  72. package/dist/operations/build-linkedin-url.test.d.ts +2 -0
  73. package/dist/operations/build-linkedin-url.test.d.ts.map +1 -0
  74. package/dist/operations/build-linkedin-url.test.js +158 -0
  75. package/dist/operations/build-linkedin-url.test.js.map +1 -0
  76. package/dist/operations/campaign-add-action.d.ts +1 -1
  77. package/dist/operations/campaign-add-action.d.ts.map +1 -1
  78. package/dist/operations/campaign-add-action.js +3 -6
  79. package/dist/operations/campaign-add-action.js.map +1 -1
  80. package/dist/operations/campaign-create.d.ts +1 -1
  81. package/dist/operations/campaign-create.d.ts.map +1 -1
  82. package/dist/operations/campaign-create.js +3 -6
  83. package/dist/operations/campaign-create.js.map +1 -1
  84. package/dist/operations/campaign-delete.d.ts +1 -1
  85. package/dist/operations/campaign-delete.d.ts.map +1 -1
  86. package/dist/operations/campaign-delete.js +3 -6
  87. package/dist/operations/campaign-delete.js.map +1 -1
  88. package/dist/operations/campaign-erase.d.ts +1 -1
  89. package/dist/operations/campaign-erase.d.ts.map +1 -1
  90. package/dist/operations/campaign-erase.js +3 -6
  91. package/dist/operations/campaign-erase.js.map +1 -1
  92. package/dist/operations/campaign-exclude-add.d.ts +1 -1
  93. package/dist/operations/campaign-exclude-add.d.ts.map +1 -1
  94. package/dist/operations/campaign-exclude-add.js +3 -6
  95. package/dist/operations/campaign-exclude-add.js.map +1 -1
  96. package/dist/operations/campaign-exclude-list.d.ts +1 -1
  97. package/dist/operations/campaign-exclude-list.d.ts.map +1 -1
  98. package/dist/operations/campaign-exclude-list.js +3 -6
  99. package/dist/operations/campaign-exclude-list.js.map +1 -1
  100. package/dist/operations/campaign-exclude-remove.d.ts +1 -1
  101. package/dist/operations/campaign-exclude-remove.d.ts.map +1 -1
  102. package/dist/operations/campaign-exclude-remove.js +3 -6
  103. package/dist/operations/campaign-exclude-remove.js.map +1 -1
  104. package/dist/operations/campaign-export.d.ts +1 -1
  105. package/dist/operations/campaign-export.d.ts.map +1 -1
  106. package/dist/operations/campaign-export.js +3 -6
  107. package/dist/operations/campaign-export.js.map +1 -1
  108. package/dist/operations/campaign-get.d.ts +1 -1
  109. package/dist/operations/campaign-get.d.ts.map +1 -1
  110. package/dist/operations/campaign-get.js +3 -6
  111. package/dist/operations/campaign-get.js.map +1 -1
  112. package/dist/operations/campaign-list-people.d.ts +1 -1
  113. package/dist/operations/campaign-list-people.d.ts.map +1 -1
  114. package/dist/operations/campaign-list-people.js +3 -6
  115. package/dist/operations/campaign-list-people.js.map +1 -1
  116. package/dist/operations/campaign-list.d.ts +1 -1
  117. package/dist/operations/campaign-list.d.ts.map +1 -1
  118. package/dist/operations/campaign-list.js +3 -6
  119. package/dist/operations/campaign-list.js.map +1 -1
  120. package/dist/operations/campaign-move-next.d.ts +1 -1
  121. package/dist/operations/campaign-move-next.d.ts.map +1 -1
  122. package/dist/operations/campaign-move-next.js +3 -6
  123. package/dist/operations/campaign-move-next.js.map +1 -1
  124. package/dist/operations/campaign-remove-action.d.ts +1 -1
  125. package/dist/operations/campaign-remove-action.d.ts.map +1 -1
  126. package/dist/operations/campaign-remove-action.js +3 -6
  127. package/dist/operations/campaign-remove-action.js.map +1 -1
  128. package/dist/operations/campaign-remove-people.d.ts +1 -1
  129. package/dist/operations/campaign-remove-people.d.ts.map +1 -1
  130. package/dist/operations/campaign-remove-people.js +3 -6
  131. package/dist/operations/campaign-remove-people.js.map +1 -1
  132. package/dist/operations/campaign-reorder-actions.d.ts +1 -1
  133. package/dist/operations/campaign-reorder-actions.d.ts.map +1 -1
  134. package/dist/operations/campaign-reorder-actions.js +3 -6
  135. package/dist/operations/campaign-reorder-actions.js.map +1 -1
  136. package/dist/operations/campaign-retry.d.ts +1 -1
  137. package/dist/operations/campaign-retry.d.ts.map +1 -1
  138. package/dist/operations/campaign-retry.js +3 -6
  139. package/dist/operations/campaign-retry.js.map +1 -1
  140. package/dist/operations/campaign-start.d.ts +1 -1
  141. package/dist/operations/campaign-start.d.ts.map +1 -1
  142. package/dist/operations/campaign-start.js +3 -6
  143. package/dist/operations/campaign-start.js.map +1 -1
  144. package/dist/operations/campaign-statistics.d.ts +1 -1
  145. package/dist/operations/campaign-statistics.d.ts.map +1 -1
  146. package/dist/operations/campaign-statistics.js +3 -6
  147. package/dist/operations/campaign-statistics.js.map +1 -1
  148. package/dist/operations/campaign-status.d.ts +1 -1
  149. package/dist/operations/campaign-status.d.ts.map +1 -1
  150. package/dist/operations/campaign-status.js +3 -6
  151. package/dist/operations/campaign-status.js.map +1 -1
  152. package/dist/operations/campaign-stop.d.ts +1 -1
  153. package/dist/operations/campaign-stop.d.ts.map +1 -1
  154. package/dist/operations/campaign-stop.js +3 -6
  155. package/dist/operations/campaign-stop.js.map +1 -1
  156. package/dist/operations/campaign-update-action.d.ts +1 -1
  157. package/dist/operations/campaign-update-action.d.ts.map +1 -1
  158. package/dist/operations/campaign-update-action.js +3 -6
  159. package/dist/operations/campaign-update-action.js.map +1 -1
  160. package/dist/operations/campaign-update.d.ts +1 -1
  161. package/dist/operations/campaign-update.d.ts.map +1 -1
  162. package/dist/operations/campaign-update.js +3 -6
  163. package/dist/operations/campaign-update.js.map +1 -1
  164. package/dist/operations/check-replies.d.ts +3 -1
  165. package/dist/operations/check-replies.d.ts.map +1 -1
  166. package/dist/operations/check-replies.js +124 -17
  167. package/dist/operations/check-replies.js.map +1 -1
  168. package/dist/operations/check-replies.test.js +152 -17
  169. package/dist/operations/check-replies.test.js.map +1 -1
  170. package/dist/operations/collect-people.d.ts +1 -1
  171. package/dist/operations/collect-people.d.ts.map +1 -1
  172. package/dist/operations/collect-people.js +18 -12
  173. package/dist/operations/collect-people.js.map +1 -1
  174. package/dist/operations/collect-people.test.js +21 -5
  175. package/dist/operations/collect-people.test.js.map +1 -1
  176. package/dist/operations/comment-on-post.d.ts +4 -1
  177. package/dist/operations/comment-on-post.d.ts.map +1 -1
  178. package/dist/operations/comment-on-post.js +15 -19
  179. package/dist/operations/comment-on-post.js.map +1 -1
  180. package/dist/operations/comment-on-post.test.js +8 -6
  181. package/dist/operations/comment-on-post.test.js.map +1 -1
  182. package/dist/operations/create-collection.d.ts +1 -1
  183. package/dist/operations/create-collection.d.ts.map +1 -1
  184. package/dist/operations/create-collection.js +5 -7
  185. package/dist/operations/create-collection.js.map +1 -1
  186. package/dist/operations/create-collection.test.js +3 -1
  187. package/dist/operations/create-collection.test.js.map +1 -1
  188. package/dist/operations/delete-collection.d.ts +1 -1
  189. package/dist/operations/delete-collection.d.ts.map +1 -1
  190. package/dist/operations/delete-collection.js +3 -6
  191. package/dist/operations/delete-collection.js.map +1 -1
  192. package/dist/operations/dismiss-errors.d.ts +11 -5
  193. package/dist/operations/dismiss-errors.d.ts.map +1 -1
  194. package/dist/operations/dismiss-errors.js +68 -34
  195. package/dist/operations/dismiss-errors.js.map +1 -1
  196. package/dist/operations/dismiss-errors.test.js +129 -8
  197. package/dist/operations/dismiss-errors.test.js.map +1 -1
  198. package/dist/operations/endorse-skills.test.d.ts +2 -0
  199. package/dist/operations/endorse-skills.test.d.ts.map +1 -0
  200. package/dist/operations/endorse-skills.test.js +70 -0
  201. package/dist/operations/endorse-skills.test.js.map +1 -0
  202. package/dist/operations/enrich-profile.test.d.ts +2 -0
  203. package/dist/operations/enrich-profile.test.d.ts.map +1 -0
  204. package/dist/operations/enrich-profile.test.js +73 -0
  205. package/dist/operations/enrich-profile.test.js.map +1 -0
  206. package/dist/operations/ephemeral-action.d.ts +2 -1
  207. package/dist/operations/ephemeral-action.d.ts.map +1 -1
  208. package/dist/operations/ephemeral-action.js +5 -7
  209. package/dist/operations/ephemeral-action.js.map +1 -1
  210. package/dist/operations/ephemeral-action.test.d.ts +2 -0
  211. package/dist/operations/ephemeral-action.test.d.ts.map +1 -0
  212. package/dist/operations/ephemeral-action.test.js +159 -0
  213. package/dist/operations/ephemeral-action.test.js.map +1 -0
  214. package/dist/operations/follow-person.test.d.ts +2 -0
  215. package/dist/operations/follow-person.test.d.ts.map +1 -0
  216. package/dist/operations/follow-person.test.js +57 -0
  217. package/dist/operations/follow-person.test.js.map +1 -0
  218. package/dist/operations/get-action-budget.d.ts +1 -1
  219. package/dist/operations/get-action-budget.d.ts.map +1 -1
  220. package/dist/operations/get-action-budget.js +3 -6
  221. package/dist/operations/get-action-budget.js.map +1 -1
  222. package/dist/operations/get-errors.d.ts +5 -1
  223. package/dist/operations/get-errors.d.ts.map +1 -1
  224. package/dist/operations/get-errors.js +55 -33
  225. package/dist/operations/get-errors.js.map +1 -1
  226. package/dist/operations/get-errors.test.js +54 -55
  227. package/dist/operations/get-errors.test.js.map +1 -1
  228. package/dist/operations/get-feed.d.ts +83 -4
  229. package/dist/operations/get-feed.d.ts.map +1 -1
  230. package/dist/operations/get-feed.js +400 -153
  231. package/dist/operations/get-feed.js.map +1 -1
  232. package/dist/operations/get-feed.test.js +416 -190
  233. package/dist/operations/get-feed.test.js.map +1 -1
  234. package/dist/operations/get-post-engagers.d.ts +6 -3
  235. package/dist/operations/get-post-engagers.d.ts.map +1 -1
  236. package/dist/operations/get-post-engagers.js +278 -78
  237. package/dist/operations/get-post-engagers.js.map +1 -1
  238. package/dist/operations/get-post-engagers.test.js +292 -14
  239. package/dist/operations/get-post-engagers.test.js.map +1 -1
  240. package/dist/operations/get-post-stats.d.ts +8 -3
  241. package/dist/operations/get-post-stats.d.ts.map +1 -1
  242. package/dist/operations/get-post-stats.js +101 -37
  243. package/dist/operations/get-post-stats.js.map +1 -1
  244. package/dist/operations/get-post-stats.test.js +137 -2
  245. package/dist/operations/get-post-stats.test.js.map +1 -1
  246. package/dist/operations/get-post.d.ts +9 -150
  247. package/dist/operations/get-post.d.ts.map +1 -1
  248. package/dist/operations/get-post.js +356 -210
  249. package/dist/operations/get-post.js.map +1 -1
  250. package/dist/operations/get-post.test.js +210 -387
  251. package/dist/operations/get-post.test.js.map +1 -1
  252. package/dist/operations/get-profile-activity.d.ts +13 -92
  253. package/dist/operations/get-profile-activity.d.ts.map +1 -1
  254. package/dist/operations/get-profile-activity.js +305 -105
  255. package/dist/operations/get-profile-activity.js.map +1 -1
  256. package/dist/operations/get-profile-activity.test.js +277 -158
  257. package/dist/operations/get-profile-activity.test.js.map +1 -1
  258. package/dist/operations/get-throttle-status.d.ts +1 -1
  259. package/dist/operations/get-throttle-status.d.ts.map +1 -1
  260. package/dist/operations/get-throttle-status.js +4 -10
  261. package/dist/operations/get-throttle-status.js.map +1 -1
  262. package/dist/operations/import-people-from-collection.d.ts +1 -1
  263. package/dist/operations/import-people-from-collection.d.ts.map +1 -1
  264. package/dist/operations/import-people-from-collection.js +3 -6
  265. package/dist/operations/import-people-from-collection.js.map +1 -1
  266. package/dist/operations/import-people-from-urls.d.ts +1 -1
  267. package/dist/operations/import-people-from-urls.d.ts.map +1 -1
  268. package/dist/operations/import-people-from-urls.js +3 -6
  269. package/dist/operations/import-people-from-urls.js.map +1 -1
  270. package/dist/operations/index.d.ts +2 -2
  271. package/dist/operations/index.d.ts.map +1 -1
  272. package/dist/operations/index.js +2 -1
  273. package/dist/operations/index.js.map +1 -1
  274. package/dist/operations/like-person-posts.test.d.ts +2 -0
  275. package/dist/operations/like-person-posts.test.d.ts.map +1 -0
  276. package/dist/operations/like-person-posts.test.js +103 -0
  277. package/dist/operations/like-person-posts.test.js.map +1 -0
  278. package/dist/operations/list-collections.d.ts +1 -1
  279. package/dist/operations/list-collections.d.ts.map +1 -1
  280. package/dist/operations/list-collections.js +3 -6
  281. package/dist/operations/list-collections.js.map +1 -1
  282. package/dist/operations/message-person.test.d.ts +2 -0
  283. package/dist/operations/message-person.test.d.ts.map +1 -0
  284. package/dist/operations/message-person.test.js +108 -0
  285. package/dist/operations/message-person.test.js.map +1 -0
  286. package/dist/operations/navigate-away.d.ts +14 -0
  287. package/dist/operations/navigate-away.d.ts.map +1 -0
  288. package/dist/operations/navigate-away.js +24 -0
  289. package/dist/operations/navigate-away.js.map +1 -0
  290. package/dist/operations/navigate-away.test.d.ts +2 -0
  291. package/dist/operations/navigate-away.test.d.ts.map +1 -0
  292. package/dist/operations/navigate-away.test.js +51 -0
  293. package/dist/operations/navigate-away.test.js.map +1 -0
  294. package/dist/operations/query-messages.d.ts +1 -1
  295. package/dist/operations/query-messages.d.ts.map +1 -1
  296. package/dist/operations/query-messages.js +3 -6
  297. package/dist/operations/query-messages.js.map +1 -1
  298. package/dist/operations/react-to-post.d.ts +16 -4
  299. package/dist/operations/react-to-post.d.ts.map +1 -1
  300. package/dist/operations/react-to-post.js +86 -24
  301. package/dist/operations/react-to-post.js.map +1 -1
  302. package/dist/operations/react-to-post.test.js +55 -5
  303. package/dist/operations/react-to-post.test.js.map +1 -1
  304. package/dist/operations/remove-connection.test.d.ts +2 -0
  305. package/dist/operations/remove-connection.test.d.ts.map +1 -0
  306. package/dist/operations/remove-connection.test.js +45 -0
  307. package/dist/operations/remove-connection.test.js.map +1 -0
  308. package/dist/operations/remove-people-from-collection.d.ts +1 -1
  309. package/dist/operations/remove-people-from-collection.d.ts.map +1 -1
  310. package/dist/operations/remove-people-from-collection.js +3 -6
  311. package/dist/operations/remove-people-from-collection.js.map +1 -1
  312. package/dist/operations/resolve-linkedin-entity.d.ts.map +1 -1
  313. package/dist/operations/resolve-linkedin-entity.js +2 -2
  314. package/dist/operations/resolve-linkedin-entity.js.map +1 -1
  315. package/dist/operations/resolve-linkedin-entity.test.d.ts +2 -0
  316. package/dist/operations/resolve-linkedin-entity.test.d.ts.map +1 -0
  317. package/dist/operations/resolve-linkedin-entity.test.js +343 -0
  318. package/dist/operations/resolve-linkedin-entity.test.js.map +1 -0
  319. package/dist/operations/scrape-messaging-history.d.ts +2 -1
  320. package/dist/operations/scrape-messaging-history.d.ts.map +1 -1
  321. package/dist/operations/scrape-messaging-history.js +113 -18
  322. package/dist/operations/scrape-messaging-history.js.map +1 -1
  323. package/dist/operations/scrape-messaging-history.test.js +109 -12
  324. package/dist/operations/scrape-messaging-history.test.js.map +1 -1
  325. package/dist/operations/search-posts.d.ts +20 -112
  326. package/dist/operations/search-posts.d.ts.map +1 -1
  327. package/dist/operations/search-posts.js +369 -170
  328. package/dist/operations/search-posts.js.map +1 -1
  329. package/dist/operations/search-posts.test.js +273 -234
  330. package/dist/operations/search-posts.test.js.map +1 -1
  331. package/dist/operations/send-inmail.test.d.ts +2 -0
  332. package/dist/operations/send-inmail.test.d.ts.map +1 -0
  333. package/dist/operations/send-inmail.test.js +108 -0
  334. package/dist/operations/send-inmail.test.js.map +1 -0
  335. package/dist/operations/send-invite.test.d.ts +2 -0
  336. package/dist/operations/send-invite.test.d.ts.map +1 -0
  337. package/dist/operations/send-invite.test.js +59 -0
  338. package/dist/operations/send-invite.test.js.map +1 -0
  339. package/dist/operations/types.d.ts +27 -1
  340. package/dist/operations/types.d.ts.map +1 -1
  341. package/dist/operations/types.js +14 -1
  342. package/dist/operations/types.js.map +1 -1
  343. package/dist/operations/visit-profile.d.ts +1 -1
  344. package/dist/operations/visit-profile.d.ts.map +1 -1
  345. package/dist/operations/visit-profile.js +3 -6
  346. package/dist/operations/visit-profile.js.map +1 -1
  347. package/dist/services/account-resolution.d.ts +10 -4
  348. package/dist/services/account-resolution.d.ts.map +1 -1
  349. package/dist/services/account-resolution.js +63 -5
  350. package/dist/services/account-resolution.js.map +1 -1
  351. package/dist/services/app.d.ts +6 -2
  352. package/dist/services/app.d.ts.map +1 -1
  353. package/dist/services/app.js +18 -6
  354. package/dist/services/app.js.map +1 -1
  355. package/dist/services/app.test.js +41 -7
  356. package/dist/services/app.test.js.map +1 -1
  357. package/dist/services/campaign.d.ts +40 -4
  358. package/dist/services/campaign.d.ts.map +1 -1
  359. package/dist/services/campaign.js +176 -10
  360. package/dist/services/campaign.js.map +1 -1
  361. package/dist/services/campaign.test.js +53 -15
  362. package/dist/services/campaign.test.js.map +1 -1
  363. package/dist/services/collection.d.ts +16 -21
  364. package/dist/services/collection.d.ts.map +1 -1
  365. package/dist/services/collection.js +34 -47
  366. package/dist/services/collection.js.map +1 -1
  367. package/dist/services/collection.test.js +30 -91
  368. package/dist/services/collection.test.js.map +1 -1
  369. package/dist/services/ephemeral-campaign.d.ts +6 -0
  370. package/dist/services/ephemeral-campaign.d.ts.map +1 -1
  371. package/dist/services/ephemeral-campaign.js +54 -10
  372. package/dist/services/ephemeral-campaign.js.map +1 -1
  373. package/dist/services/ephemeral-campaign.test.js +23 -10
  374. package/dist/services/ephemeral-campaign.test.js.map +1 -1
  375. package/dist/services/errors.d.ts +2 -1
  376. package/dist/services/errors.d.ts.map +1 -1
  377. package/dist/services/errors.js +6 -3
  378. package/dist/services/errors.js.map +1 -1
  379. package/dist/services/index.d.ts +1 -2
  380. package/dist/services/index.d.ts.map +1 -1
  381. package/dist/services/index.js +1 -2
  382. package/dist/services/index.js.map +1 -1
  383. package/dist/services/instance-context.d.ts +5 -1
  384. package/dist/services/instance-context.d.ts.map +1 -1
  385. package/dist/services/instance-context.js +87 -28
  386. package/dist/services/instance-context.js.map +1 -1
  387. package/dist/services/instance-context.test.js +5 -1
  388. package/dist/services/instance-context.test.js.map +1 -1
  389. package/dist/services/instance-lifecycle.d.ts.map +1 -1
  390. package/dist/services/instance-lifecycle.js +32 -1
  391. package/dist/services/instance-lifecycle.js.map +1 -1
  392. package/dist/services/instance-lifecycle.test.js +52 -1
  393. package/dist/services/instance-lifecycle.test.js.map +1 -1
  394. package/dist/services/instance.d.ts +37 -9
  395. package/dist/services/instance.d.ts.map +1 -1
  396. package/dist/services/instance.js +100 -25
  397. package/dist/services/instance.js.map +1 -1
  398. package/dist/services/instance.test.js +157 -0
  399. package/dist/services/instance.test.js.map +1 -1
  400. package/dist/services/launcher.d.ts +47 -3
  401. package/dist/services/launcher.d.ts.map +1 -1
  402. package/dist/services/launcher.js +205 -33
  403. package/dist/services/launcher.js.map +1 -1
  404. package/dist/services/launcher.test.js +133 -6
  405. package/dist/services/launcher.test.js.map +1 -1
  406. package/dist/services/source-type-registry.d.ts +8 -0
  407. package/dist/services/source-type-registry.d.ts.map +1 -1
  408. package/dist/services/source-type-registry.js +39 -0
  409. package/dist/services/source-type-registry.js.map +1 -1
  410. package/dist/services/source-type-registry.test.js +31 -1
  411. package/dist/services/source-type-registry.test.js.map +1 -1
  412. package/dist/services/status.d.ts +6 -2
  413. package/dist/services/status.d.ts.map +1 -1
  414. package/dist/services/status.js +67 -34
  415. package/dist/services/status.js.map +1 -1
  416. package/dist/services/status.test.js +9 -2
  417. package/dist/services/status.test.js.map +1 -1
  418. package/dist/testing/e2e-helpers.d.ts +47 -1
  419. package/dist/testing/e2e-helpers.d.ts.map +1 -1
  420. package/dist/testing/e2e-helpers.js +244 -7
  421. package/dist/testing/e2e-helpers.js.map +1 -1
  422. package/dist/testing/index.d.ts +1 -1
  423. package/dist/testing/index.d.ts.map +1 -1
  424. package/dist/testing/index.js +1 -1
  425. package/dist/testing/index.js.map +1 -1
  426. package/dist/types/account.d.ts +1 -1
  427. package/dist/types/campaign.d.ts +1 -1
  428. package/dist/types/campaign.d.ts.map +1 -1
  429. package/dist/types/feed.d.ts +1 -3
  430. package/dist/types/feed.d.ts.map +1 -1
  431. package/dist/types/index.d.ts +0 -1
  432. package/dist/types/index.d.ts.map +1 -1
  433. package/dist/utils/cdp-port.d.ts.map +1 -1
  434. package/dist/utils/cdp-port.js +3 -1
  435. package/dist/utils/cdp-port.js.map +1 -1
  436. package/dist/utils/cdp-port.test.js +1 -1
  437. package/dist/utils/cdp-port.test.js.map +1 -1
  438. package/dist/utils/delay.d.ts +79 -0
  439. package/dist/utils/delay.d.ts.map +1 -1
  440. package/dist/utils/delay.js +118 -0
  441. package/dist/utils/delay.js.map +1 -1
  442. package/dist/utils/delay.test.js +111 -1
  443. package/dist/utils/delay.test.js.map +1 -1
  444. package/dist/utils/index.d.ts +2 -1
  445. package/dist/utils/index.d.ts.map +1 -1
  446. package/dist/utils/index.js +2 -1
  447. package/dist/utils/index.js.map +1 -1
  448. package/dist/utils/session-pacer.d.ts +27 -0
  449. package/dist/utils/session-pacer.d.ts.map +1 -0
  450. package/dist/utils/session-pacer.js +55 -0
  451. package/dist/utils/session-pacer.js.map +1 -0
  452. package/dist/utils/session-pacer.test.d.ts +2 -0
  453. package/dist/utils/session-pacer.test.d.ts.map +1 -0
  454. package/dist/utils/session-pacer.test.js +111 -0
  455. package/dist/utils/session-pacer.test.js.map +1 -0
  456. package/package.json +1 -1
  457. package/dist/linkedin/__tests__/selectors.integration.test.d.ts +0 -2
  458. package/dist/linkedin/__tests__/selectors.integration.test.d.ts.map +0 -1
  459. package/dist/linkedin/__tests__/selectors.integration.test.js +0 -258
  460. package/dist/linkedin/__tests__/selectors.integration.test.js.map +0 -1
  461. package/dist/types/search-posts.d.ts +0 -22
  462. package/dist/types/search-posts.d.ts.map +0 -1
  463. package/dist/types/search-posts.js +0 -4
  464. package/dist/types/search-posts.js.map +0 -1
  465. package/dist/voyager/index.d.ts +0 -2
  466. package/dist/voyager/index.d.ts.map +0 -1
  467. package/dist/voyager/index.js +0 -4
  468. package/dist/voyager/index.js.map +0 -1
  469. package/dist/voyager/interceptor.d.ts +0 -100
  470. package/dist/voyager/interceptor.d.ts.map +0 -1
  471. package/dist/voyager/interceptor.integration.test.d.ts +0 -2
  472. package/dist/voyager/interceptor.integration.test.d.ts.map +0 -1
  473. package/dist/voyager/interceptor.integration.test.js +0 -89
  474. package/dist/voyager/interceptor.integration.test.js.map +0 -1
  475. package/dist/voyager/interceptor.js +0 -235
  476. package/dist/voyager/interceptor.js.map +0 -1
  477. package/dist/voyager/interceptor.test.d.ts +0 -2
  478. package/dist/voyager/interceptor.test.d.ts.map +0 -1
  479. package/dist/voyager/interceptor.test.js +0 -372
  480. package/dist/voyager/interceptor.test.js.map +0 -1
@@ -7,375 +7,51 @@ vi.mock("../cdp/discovery.js", () => ({
7
7
  vi.mock("../cdp/client.js", () => ({
8
8
  CDPClient: vi.fn(),
9
9
  }));
10
- vi.mock("../voyager/interceptor.js", () => ({
11
- VoyagerInterceptor: vi.fn(),
10
+ vi.mock("../utils/delay.js", () => ({
11
+ gaussianDelay: vi.fn().mockResolvedValue(undefined),
12
+ }));
13
+ vi.mock("./navigate-away.js", () => ({
14
+ navigateAwayIf: vi.fn().mockResolvedValue(undefined),
15
+ }));
16
+ vi.mock("./get-feed.js", () => ({
17
+ delay: vi.fn().mockResolvedValue(undefined),
18
+ parseTimestamp: vi.fn((raw) => {
19
+ if (!raw)
20
+ return null;
21
+ const asDate = Date.parse(raw);
22
+ if (!isNaN(asDate))
23
+ return asDate;
24
+ return null;
25
+ }),
12
26
  }));
13
27
  import { discoverTargets } from "../cdp/discovery.js";
14
28
  import { CDPClient } from "../cdp/client.js";
15
- import { VoyagerInterceptor } from "../voyager/interceptor.js";
16
- import { getPost, parseCommentsResponse, parseFeedUpdateResponse, resolveTextValue, } from "./get-post.js";
17
- describe("resolveTextValue", () => {
18
- it("returns empty string for undefined", () => {
19
- expect(resolveTextValue(undefined)).toBe("");
20
- });
21
- it("returns empty string for null", () => {
22
- expect(resolveTextValue(null)).toBe("");
23
- });
24
- it("returns string value as-is", () => {
25
- expect(resolveTextValue("hello")).toBe("hello");
26
- });
27
- it("extracts text from object with text field", () => {
28
- expect(resolveTextValue({ text: "hello" })).toBe("hello");
29
- });
30
- it("returns empty string for object without text field", () => {
31
- expect(resolveTextValue({})).toBe("");
32
- });
33
- });
34
- describe("parseFeedUpdateResponse", () => {
35
- const postUrn = "urn:li:activity:1234567890";
36
- it("parses flat response with inline actor", () => {
37
- const raw = {
38
- actor: {
39
- name: { text: "John Doe" },
40
- description: { text: "Software Engineer" },
41
- navigationUrl: "https://www.linkedin.com/in/johndoe",
42
- },
43
- commentary: { text: { text: "Hello world!" } },
44
- publishedAt: 1700000000000,
45
- socialDetail: {
46
- totalSocialActivityCounts: {
47
- numLikes: 42,
48
- numComments: 5,
49
- numShares: 3,
50
- },
51
- },
52
- };
53
- const result = parseFeedUpdateResponse(raw, postUrn, []);
54
- expect(result).toEqual({
55
- postUrn,
56
- authorName: "John Doe",
57
- authorHeadline: "Software Engineer",
58
- authorPublicId: "johndoe",
59
- text: "Hello world!",
60
- publishedAt: 1700000000000,
61
- reactionCount: 42,
62
- commentCount: 5,
63
- shareCount: 3,
64
- });
65
- });
66
- it("parses nested data response", () => {
67
- const raw = {
68
- data: {
69
- actor: {
70
- name: { text: "Jane Smith" },
71
- description: { text: "Product Manager" },
72
- publicIdentifier: "janesmith",
73
- },
74
- commentary: { text: { text: "Great post!" } },
75
- publishedAt: 1700001000000,
76
- socialDetail: {
77
- totalSocialActivityCounts: {
78
- numLikes: 10,
79
- numComments: 2,
80
- numShares: 1,
81
- },
82
- },
83
- },
84
- };
85
- const result = parseFeedUpdateResponse(raw, postUrn, []);
86
- expect(result.authorName).toBe("Jane Smith");
87
- expect(result.authorPublicId).toBe("janesmith");
88
- expect(result.text).toBe("Great post!");
89
- expect(result.publishedAt).toBe(1700001000000);
90
- });
91
- it("parses data.elements array response", () => {
92
- const raw = {
93
- data: {
94
- elements: [
95
- {
96
- actor: {
97
- name: { text: "Bob Johnson" },
98
- description: { text: "Developer" },
99
- },
100
- commentary: { text: { text: "First element" } },
101
- publishedAt: 1700002000000,
102
- socialDetail: {
103
- totalSocialActivityCounts: {
104
- numLikes: 5,
105
- numComments: 1,
106
- numShares: 0,
107
- },
108
- },
109
- },
110
- ],
111
- },
112
- };
113
- const result = parseFeedUpdateResponse(raw, postUrn, []);
114
- expect(result.authorName).toBe("Bob Johnson");
115
- expect(result.text).toBe("First element");
116
- });
117
- it("resolves actor from URN reference via included", () => {
118
- const actorUrn = "urn:li:member:999";
119
- const raw = {
120
- data: {
121
- actor: actorUrn,
122
- commentary: { text: { text: "Referenced actor" } },
123
- },
124
- };
125
- const included = [
126
- {
127
- entityUrn: actorUrn,
128
- firstName: "Alice",
129
- lastName: "Williams",
130
- publicIdentifier: "alicew",
131
- headline: { text: "Engineer" },
132
- },
133
- ];
134
- const result = parseFeedUpdateResponse(raw, postUrn, included);
135
- expect(result.authorName).toBe("Alice Williams");
136
- expect(result.authorPublicId).toBe("alicew");
137
- expect(result.authorHeadline).toBe("Engineer");
138
- });
139
- it("resolves actor from *actor URN reference", () => {
140
- const actorUrn = "urn:li:member:888";
141
- const raw = {
142
- data: {
143
- "*actor": actorUrn,
144
- commentary: { text: { text: "Star actor ref" } },
145
- },
146
- };
147
- const included = [
148
- {
149
- entityUrn: actorUrn,
150
- name: { text: "Star Actor" },
151
- description: { text: "CTO" },
152
- navigationUrl: "https://www.linkedin.com/in/staractor",
153
- },
154
- ];
155
- const result = parseFeedUpdateResponse(raw, postUrn, included);
156
- expect(result.authorName).toBe("Star Actor");
157
- expect(result.authorPublicId).toBe("staractor");
158
- });
159
- it("handles missing optional fields gracefully", () => {
160
- const raw = {};
161
- const result = parseFeedUpdateResponse(raw, postUrn, []);
162
- expect(result.postUrn).toBe(postUrn);
163
- expect(result.authorName).toBe("");
164
- expect(result.authorHeadline).toBeNull();
165
- expect(result.authorPublicId).toBeNull();
166
- expect(result.text).toBe("");
167
- expect(result.publishedAt).toBeNull();
168
- expect(result.reactionCount).toBe(0);
169
- expect(result.commentCount).toBe(0);
170
- expect(result.shareCount).toBe(0);
171
- });
172
- it("handles string commentary text", () => {
173
- const raw = {
174
- commentary: { text: "Plain string text" },
175
- };
176
- const result = parseFeedUpdateResponse(raw, postUrn, []);
177
- expect(result.text).toBe("Plain string text");
178
- });
179
- it("resolves actor with firstName/lastName pattern", () => {
180
- const raw = {
181
- actor: {
182
- firstName: "First",
183
- lastName: "Last",
184
- headline: { text: "Title" },
185
- publicIdentifier: "firstlast",
186
- },
187
- };
188
- const result = parseFeedUpdateResponse(raw, postUrn, []);
189
- expect(result.authorName).toBe("First Last");
190
- expect(result.authorPublicId).toBe("firstlast");
191
- expect(result.authorHeadline).toBe("Title");
192
- });
193
- });
194
- describe("parseCommentsResponse", () => {
195
- it("parses comments with inline commenter", () => {
196
- const raw = {
197
- elements: [
198
- {
199
- urn: "urn:li:comment:100",
200
- commenter: {
201
- firstName: "Alice",
202
- lastName: "Smith",
203
- publicIdentifier: "alices",
204
- headline: { text: "Engineer" },
205
- },
206
- commentV2: { text: { text: "Nice post!" } },
207
- createdTime: 1700010000000,
208
- socialDetail: {
209
- totalSocialActivityCounts: { numLikes: 3 },
210
- },
211
- },
212
- ],
213
- paging: { start: 0, count: 10, total: 1 },
214
- };
215
- const result = parseCommentsResponse(raw);
216
- expect(result.comments).toHaveLength(1);
217
- expect(result.comments[0]).toEqual({
218
- commentUrn: "urn:li:comment:100",
219
- authorName: "Alice Smith",
220
- authorHeadline: "Engineer",
221
- authorPublicId: "alices",
222
- text: "Nice post!",
223
- createdAt: 1700010000000,
224
- reactionCount: 3,
225
- });
226
- expect(result.paging).toEqual({ start: 0, count: 10, total: 1 });
227
- });
228
- it("parses nested data.elements response", () => {
229
- const raw = {
230
- data: {
231
- elements: [
232
- {
233
- entityUrn: "urn:li:comment:200",
234
- commenter: {
235
- firstName: "Bob",
236
- lastName: "Jones",
237
- },
238
- commentary: { text: { text: "Commentary format" } },
239
- createdTime: 1700020000000,
240
- },
241
- ],
242
- paging: { start: 0, count: 5, total: 1 },
243
- },
244
- };
245
- const result = parseCommentsResponse(raw);
246
- expect(result.comments).toHaveLength(1);
247
- expect(result.comments[0]?.text).toBe("Commentary format");
248
- expect(result.comments[0]?.commentUrn).toBe("urn:li:comment:200");
249
- expect(result.paging).toEqual({ start: 0, count: 5, total: 1 });
250
- });
251
- it("resolves commenter from included via URN reference", () => {
252
- const commenterUrn = "urn:li:member:555";
253
- const raw = {
254
- elements: [
255
- {
256
- urn: "urn:li:comment:300",
257
- commenterUrn,
258
- commentV2: { text: { text: "Looked up commenter" } },
259
- createdTime: 1700030000000,
260
- },
261
- ],
262
- included: [
263
- {
264
- entityUrn: commenterUrn,
265
- firstName: "Charlie",
266
- lastName: "Brown",
267
- publicIdentifier: "charlieb",
268
- occupation: "Writer",
269
- },
270
- ],
271
- };
272
- const result = parseCommentsResponse(raw);
273
- expect(result.comments[0]?.authorName).toBe("Charlie Brown");
274
- expect(result.comments[0]?.authorPublicId).toBe("charlieb");
275
- expect(result.comments[0]?.authorHeadline).toBe("Writer");
276
- });
277
- it("resolves commenter from *commenter URN reference", () => {
278
- const commenterUrn = "urn:li:member:666";
279
- const raw = {
280
- elements: [
281
- {
282
- urn: "urn:li:comment:400",
283
- "*commenter": commenterUrn,
284
- commentV2: { text: { text: "Star commenter ref" } },
285
- },
286
- ],
287
- included: [
288
- {
289
- entityUrn: commenterUrn,
290
- firstName: "Dana",
291
- lastName: "White",
292
- headline: { text: "Manager" },
293
- },
294
- ],
295
- };
296
- const result = parseCommentsResponse(raw);
297
- expect(result.comments[0]?.authorName).toBe("Dana White");
298
- expect(result.comments[0]?.authorHeadline).toBe("Manager");
299
- });
300
- it("handles plain string comment text", () => {
301
- const raw = {
302
- elements: [
303
- {
304
- comment: "Simple string comment",
305
- },
306
- ],
307
- };
308
- const result = parseCommentsResponse(raw);
309
- expect(result.comments[0]?.text).toBe("Simple string comment");
310
- });
311
- it("handles comment with text object", () => {
312
- const raw = {
313
- elements: [
314
- {
315
- comment: { text: "Object text comment" },
316
- },
317
- ],
318
- };
319
- const result = parseCommentsResponse(raw);
320
- expect(result.comments[0]?.text).toBe("Object text comment");
321
- });
322
- it("handles comment with values array", () => {
323
- const raw = {
324
- elements: [
325
- {
326
- comment: { values: [{ value: "Part 1" }, { value: " Part 2" }] },
327
- },
328
- ],
329
- };
330
- const result = parseCommentsResponse(raw);
331
- expect(result.comments[0]?.text).toBe("Part 1 Part 2");
332
- });
333
- it("handles created.time timestamp variant", () => {
334
- const raw = {
335
- elements: [
336
- {
337
- created: { time: 1700040000000 },
338
- commentV2: { text: "Nested time" },
339
- },
340
- ],
341
- };
342
- const result = parseCommentsResponse(raw);
343
- expect(result.comments[0]?.createdAt).toBe(1700040000000);
344
- });
345
- it("handles empty response gracefully", () => {
346
- const result = parseCommentsResponse({});
347
- expect(result.comments).toEqual([]);
348
- expect(result.paging).toEqual({ start: 0, count: 0, total: 0 });
349
- });
350
- it("handles missing optional fields", () => {
351
- const raw = {
352
- elements: [{}],
353
- };
354
- const result = parseCommentsResponse(raw);
355
- expect(result.comments).toHaveLength(1);
356
- expect(result.comments[0]).toEqual({
357
- commentUrn: null,
358
- authorName: "",
359
- authorHeadline: null,
360
- authorPublicId: null,
361
- text: "",
362
- createdAt: null,
363
- reactionCount: 0,
364
- });
365
- });
366
- it("defaults paging from comment count when absent", () => {
367
- const raw = {
368
- elements: [{}, {}, {}],
369
- };
370
- const result = parseCommentsResponse(raw);
371
- expect(result.paging).toEqual({ start: 0, count: 3, total: 3 });
372
- });
373
- });
29
+ import { getPost } from "./get-post.js";
374
30
  describe("getPost", () => {
375
31
  const CDP_PORT = 9222;
376
32
  const POST_URL = "https://www.linkedin.com/feed/update/urn:li:activity:1234567890/";
33
+ const DEFAULT_POST_DETAIL = {
34
+ authorName: "John Doe",
35
+ authorHeadline: "Software Engineer",
36
+ authorProfileUrl: "https://www.linkedin.com/in/johndoe",
37
+ text: "Hello world! This is a long post text.",
38
+ reactionCount: 42,
39
+ commentCount: 5,
40
+ shareCount: 3,
41
+ timestamp: "2024-11-15T10:00:00.000Z",
42
+ };
43
+ const DEFAULT_COMMENTS = [
44
+ {
45
+ authorName: "Alice Smith",
46
+ authorHeadline: "Product Manager",
47
+ authorPublicId: "alices",
48
+ text: "Great post!",
49
+ createdAt: "2024-11-15T11:00:00.000Z",
50
+ reactionCount: 2,
51
+ },
52
+ ];
377
53
  function setupMocks(opts) {
378
- const { postStatus = 200, postBody = {}, commentsStatus = 200, commentsBody = { elements: [] }, } = opts ?? {};
54
+ const { postDetail = DEFAULT_POST_DETAIL, comments = DEFAULT_COMMENTS, readySequence = [true], articleCount = 1, loadMoreClicked = [false], } = opts ?? {};
379
55
  vi.mocked(discoverTargets).mockResolvedValue([
380
56
  {
381
57
  id: "target-1",
@@ -387,24 +63,37 @@ describe("getPost", () => {
387
63
  },
388
64
  ]);
389
65
  const disconnect = vi.fn();
66
+ const navigate = vi.fn().mockResolvedValue(undefined);
67
+ // Build evaluate mock call sequence:
68
+ // 1. readiness checks (boolean)
69
+ // 2. post detail (object)
70
+ // 3. article count for load-more loop (number)
71
+ // 4. load more click result (boolean) — repeats until false
72
+ // 5. final comments scrape (array)
73
+ const evaluateMock = vi.fn();
74
+ for (const ready of readySequence) {
75
+ evaluateMock.mockResolvedValueOnce(ready);
76
+ }
77
+ evaluateMock.mockResolvedValueOnce(postDetail);
78
+ evaluateMock.mockResolvedValueOnce(articleCount);
79
+ for (const clicked of loadMoreClicked) {
80
+ evaluateMock.mockResolvedValueOnce(clicked);
81
+ if (clicked) {
82
+ // After a successful click, the loop checks article count again
83
+ evaluateMock.mockResolvedValueOnce(articleCount);
84
+ }
85
+ }
86
+ evaluateMock.mockResolvedValueOnce(comments);
390
87
  vi.mocked(CDPClient).mockImplementation(function () {
391
88
  return {
392
89
  connect: vi.fn().mockResolvedValue(undefined),
393
90
  disconnect,
91
+ navigate,
92
+ evaluate: evaluateMock,
93
+ send: vi.fn().mockResolvedValue(undefined),
394
94
  };
395
95
  });
396
- const fetchMock = vi
397
- .fn()
398
- .mockResolvedValueOnce({ url: "", status: postStatus, body: postBody })
399
- .mockResolvedValueOnce({
400
- url: "",
401
- status: commentsStatus,
402
- body: commentsBody,
403
- });
404
- vi.mocked(VoyagerInterceptor).mockImplementation(function () {
405
- return { fetch: fetchMock };
406
- });
407
- return { fetchMock, disconnect };
96
+ return { evaluateMock, disconnect, navigate };
408
97
  }
409
98
  beforeEach(() => {
410
99
  vi.clearAllMocks();
@@ -419,21 +108,155 @@ describe("getPost", () => {
419
108
  vi.mocked(discoverTargets).mockResolvedValue([]);
420
109
  await expect(getPost({ postUrl: POST_URL, cdpPort: CDP_PORT })).rejects.toThrow("No LinkedIn page found in LinkedHelper");
421
110
  });
422
- it("throws on non-200 response for post detail", async () => {
423
- setupMocks({ postStatus: 403 });
424
- await expect(getPost({ postUrl: POST_URL, cdpPort: CDP_PORT })).rejects.toThrow("Voyager API returned HTTP 403 for post detail");
111
+ it("navigates to post detail URL and extracts post data from DOM", async () => {
112
+ const { navigate } = setupMocks();
113
+ const result = await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
114
+ expect(navigate).toHaveBeenCalledWith("https://www.linkedin.com/feed/update/urn:li:activity:1234567890/");
115
+ expect(result.post.postUrn).toBe("urn:li:activity:1234567890");
116
+ expect(result.post.authorName).toBe("John Doe");
117
+ expect(result.post.authorHeadline).toBe("Software Engineer");
118
+ expect(result.post.authorPublicId).toBe("johndoe");
119
+ expect(result.post.text).toBe("Hello world! This is a long post text.");
120
+ expect(result.post.reactionCount).toBe(42);
121
+ expect(result.post.commentCount).toBe(5);
122
+ expect(result.post.shareCount).toBe(3);
123
+ });
124
+ it("extracts comments from DOM", async () => {
125
+ setupMocks();
126
+ const result = await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
127
+ expect(result.comments).toHaveLength(1);
128
+ expect(result.comments[0]).toMatchObject({
129
+ commentUrn: null,
130
+ authorName: "Alice Smith",
131
+ authorHeadline: "Product Manager",
132
+ authorPublicId: "alices",
133
+ text: "Great post!",
134
+ reactionCount: 2,
135
+ });
425
136
  });
426
- it("throws on non-object response body for post detail", async () => {
427
- setupMocks({ postBody: null });
428
- await expect(getPost({ postUrl: POST_URL, cdpPort: CDP_PORT })).rejects.toThrow("Voyager API returned an unexpected response format for post detail");
137
+ it("returns paging metadata from visible comments", async () => {
138
+ setupMocks({
139
+ comments: [
140
+ { authorName: "A", text: "c1", authorPublicId: null, authorHeadline: null, createdAt: null, reactionCount: 0 },
141
+ { authorName: "B", text: "c2", authorPublicId: null, authorHeadline: null, createdAt: null, reactionCount: 0 },
142
+ ],
143
+ });
144
+ const result = await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
145
+ expect(result.commentsPaging).toEqual({
146
+ start: 0,
147
+ count: 2,
148
+ total: 2,
149
+ });
429
150
  });
430
- it("throws on non-200 response for post comments", async () => {
431
- setupMocks({ commentsStatus: 500 });
432
- await expect(getPost({ postUrl: POST_URL, cdpPort: CDP_PORT })).rejects.toThrow("Voyager API returned HTTP 500 for post comments");
151
+ it("handles empty comments gracefully", async () => {
152
+ setupMocks({ comments: [] });
153
+ const result = await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
154
+ expect(result.comments).toEqual([]);
155
+ expect(result.commentsPaging).toEqual({ start: 0, count: 0, total: 0 });
433
156
  });
434
- it("throws on non-object response body for post comments", async () => {
435
- setupMocks({ commentsBody: null });
436
- await expect(getPost({ postUrl: POST_URL, cdpPort: CDP_PORT })).rejects.toThrow("Voyager API returned an unexpected response format for post comments");
157
+ it("handles null evaluate result for comments", async () => {
158
+ setupMocks({ comments: null });
159
+ const result = await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
160
+ expect(result.comments).toEqual([]);
161
+ });
162
+ it("throws when post detail extraction fails", async () => {
163
+ setupMocks({ postDetail: null });
164
+ await expect(getPost({ postUrl: POST_URL, cdpPort: CDP_PORT })).rejects.toThrow("Failed to extract post detail from the DOM");
165
+ });
166
+ it("handles missing optional fields in post detail", async () => {
167
+ setupMocks({
168
+ postDetail: {
169
+ authorName: null,
170
+ authorHeadline: null,
171
+ authorProfileUrl: null,
172
+ text: null,
173
+ reactionCount: 0,
174
+ commentCount: 0,
175
+ shareCount: 0,
176
+ timestamp: null,
177
+ },
178
+ comments: [],
179
+ });
180
+ const result = await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
181
+ expect(result.post.postUrn).toBe("urn:li:activity:1234567890");
182
+ expect(result.post.authorName).toBe("");
183
+ expect(result.post.authorHeadline).toBeNull();
184
+ expect(result.post.authorPublicId).toBeNull();
185
+ expect(result.post.text).toBe("");
186
+ expect(result.post.publishedAt).toBeNull();
187
+ expect(result.post.reactionCount).toBe(0);
188
+ expect(result.post.commentCount).toBe(0);
189
+ expect(result.post.shareCount).toBe(0);
190
+ });
191
+ it("waits for post to load with polling", async () => {
192
+ const { evaluateMock } = setupMocks({
193
+ readySequence: [false, false, true],
194
+ });
195
+ await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
196
+ // 3 readiness + 1 post detail + 1 article count + 1 load-more (false) + 1 comments = 7
197
+ expect(evaluateMock).toHaveBeenCalledTimes(7);
198
+ });
199
+ it("extracts authorPublicId from profile URL", async () => {
200
+ setupMocks({
201
+ postDetail: {
202
+ ...DEFAULT_POST_DETAIL,
203
+ authorProfileUrl: "https://www.linkedin.com/in/jane-doe-123",
204
+ },
205
+ comments: [],
206
+ });
207
+ const result = await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
208
+ expect(result.post.authorPublicId).toBe("jane-doe-123");
209
+ });
210
+ it("returns null authorPublicId for company URLs", async () => {
211
+ setupMocks({
212
+ postDetail: {
213
+ ...DEFAULT_POST_DETAIL,
214
+ authorProfileUrl: "https://www.linkedin.com/company/acme-corp",
215
+ },
216
+ comments: [],
217
+ });
218
+ const result = await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
219
+ expect(result.post.authorPublicId).toBeNull();
220
+ });
221
+ it("clicks load-more to expand comments", async () => {
222
+ setupMocks({
223
+ articleCount: 2,
224
+ loadMoreClicked: [true, true, false],
225
+ comments: [
226
+ { authorName: "A", text: "c1", authorPublicId: null, authorHeadline: null, createdAt: null, reactionCount: 0 },
227
+ { authorName: "B", text: "c2", authorPublicId: null, authorHeadline: null, createdAt: null, reactionCount: 0 },
228
+ { authorName: "C", text: "c3", authorPublicId: null, authorHeadline: null, createdAt: null, reactionCount: 0 },
229
+ ],
230
+ });
231
+ const result = await getPost({ postUrl: POST_URL, cdpPort: CDP_PORT });
232
+ expect(result.comments).toHaveLength(3);
233
+ });
234
+ it("skips comment loading when commentCount is 0", async () => {
235
+ const { evaluateMock } = setupMocks({ comments: [] });
236
+ const result = await getPost({
237
+ postUrl: POST_URL,
238
+ cdpPort: CDP_PORT,
239
+ commentCount: 0,
240
+ });
241
+ expect(result.comments).toEqual([]);
242
+ // readiness + post detail + comments scrape (no load-more loop)
243
+ // With commentCount=0: 1 ready + 1 post + 1 comments = 3
244
+ expect(evaluateMock).toHaveBeenCalledTimes(3);
245
+ });
246
+ it("limits comments to commentCount", async () => {
247
+ setupMocks({
248
+ comments: [
249
+ { authorName: "A", text: "c1", authorPublicId: null, authorHeadline: null, createdAt: null, reactionCount: 0 },
250
+ { authorName: "B", text: "c2", authorPublicId: null, authorHeadline: null, createdAt: null, reactionCount: 0 },
251
+ { authorName: "C", text: "c3", authorPublicId: null, authorHeadline: null, createdAt: null, reactionCount: 0 },
252
+ ],
253
+ });
254
+ const result = await getPost({
255
+ postUrl: POST_URL,
256
+ cdpPort: CDP_PORT,
257
+ commentCount: 2,
258
+ });
259
+ expect(result.comments).toHaveLength(2);
437
260
  });
438
261
  it("disconnects CDP client after successful operation", async () => {
439
262
  const { disconnect } = setupMocks();
@@ -441,7 +264,7 @@ describe("getPost", () => {
441
264
  expect(disconnect).toHaveBeenCalled();
442
265
  });
443
266
  it("disconnects CDP client even on error", async () => {
444
- const { disconnect } = setupMocks({ postStatus: 500 });
267
+ const { disconnect } = setupMocks({ postDetail: null });
445
268
  await expect(getPost({ postUrl: POST_URL, cdpPort: CDP_PORT })).rejects.toThrow();
446
269
  expect(disconnect).toHaveBeenCalled();
447
270
  });