testplane 9.0.0-rc.4 → 9.0.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 (299) hide show
  1. package/build/package.json +11 -11
  2. package/build/src/base-testplane.d.ts +6 -2
  3. package/build/src/base-testplane.js +18 -5
  4. package/build/src/base-testplane.js.map +1 -1
  5. package/build/src/browser/browser.d.ts +2 -0
  6. package/build/src/browser/browser.js +8 -4
  7. package/build/src/browser/browser.js.map +1 -1
  8. package/build/src/browser/calibrator.js +19 -17
  9. package/build/src/browser/calibrator.js.map +1 -1
  10. package/build/src/browser/camera/index.d.ts +6 -2
  11. package/build/src/browser/camera/index.js +18 -14
  12. package/build/src/browser/camera/index.js.map +1 -1
  13. package/build/src/browser/camera/utils.d.ts +11 -1
  14. package/build/src/browser/camera/utils.js +27 -1
  15. package/build/src/browser/camera/utils.js.map +1 -1
  16. package/build/src/browser/cdp/connection.d.ts +2 -39
  17. package/build/src/browser/cdp/connection.js +73 -353
  18. package/build/src/browser/cdp/connection.js.map +1 -1
  19. package/build/src/browser/cdp/constants.d.ts +0 -10
  20. package/build/src/browser/cdp/constants.js +1 -11
  21. package/build/src/browser/cdp/constants.js.map +1 -1
  22. package/build/src/browser/cdp/domains/css.d.ts +14 -6
  23. package/build/src/browser/cdp/domains/css.js +4 -0
  24. package/build/src/browser/cdp/domains/css.js.map +1 -1
  25. package/build/src/browser/cdp/domains/debugger.d.ts +1 -1
  26. package/build/src/browser/cdp/domains/fetch.d.ts +163 -0
  27. package/build/src/browser/cdp/domains/fetch.js +51 -0
  28. package/build/src/browser/cdp/domains/fetch.js.map +1 -0
  29. package/build/src/browser/cdp/domains/network.d.ts +290 -0
  30. package/build/src/browser/cdp/domains/network.js +75 -0
  31. package/build/src/browser/cdp/domains/network.js.map +1 -0
  32. package/build/src/browser/cdp/domains/page.d.ts +378 -0
  33. package/build/src/browser/cdp/domains/page.js +114 -0
  34. package/build/src/browser/cdp/domains/page.js.map +1 -0
  35. package/build/src/browser/cdp/emitter.d.ts +2 -1
  36. package/build/src/browser/cdp/emitter.js +2 -2
  37. package/build/src/browser/cdp/emitter.js.map +1 -1
  38. package/build/src/browser/cdp/error.d.ts +14 -20
  39. package/build/src/browser/cdp/error.js +29 -32
  40. package/build/src/browser/cdp/error.js.map +1 -1
  41. package/build/src/browser/cdp/index.d.ts +6 -0
  42. package/build/src/browser/cdp/index.js +21 -6
  43. package/build/src/browser/cdp/index.js.map +1 -1
  44. package/build/src/browser/cdp/selectivity/constants.d.ts +2 -0
  45. package/build/src/browser/cdp/selectivity/constants.js +3 -1
  46. package/build/src/browser/cdp/selectivity/constants.js.map +1 -1
  47. package/build/src/browser/cdp/selectivity/css-selectivity.d.ts +13 -3
  48. package/build/src/browser/cdp/selectivity/css-selectivity.js +211 -62
  49. package/build/src/browser/cdp/selectivity/css-selectivity.js.map +1 -1
  50. package/build/src/browser/cdp/selectivity/fs-cache.d.ts +12 -0
  51. package/build/src/browser/cdp/selectivity/fs-cache.js +122 -0
  52. package/build/src/browser/cdp/selectivity/fs-cache.js.map +1 -0
  53. package/build/src/browser/cdp/selectivity/hash-provider.d.ts +1 -0
  54. package/build/src/browser/cdp/selectivity/hash-provider.js +5 -3
  55. package/build/src/browser/cdp/selectivity/hash-provider.js.map +1 -1
  56. package/build/src/browser/cdp/selectivity/hash-reader.d.ts +2 -3
  57. package/build/src/browser/cdp/selectivity/hash-reader.js +39 -26
  58. package/build/src/browser/cdp/selectivity/hash-reader.js.map +1 -1
  59. package/build/src/browser/cdp/selectivity/hash-writer.d.ts +2 -2
  60. package/build/src/browser/cdp/selectivity/hash-writer.js +16 -62
  61. package/build/src/browser/cdp/selectivity/hash-writer.js.map +1 -1
  62. package/build/src/browser/cdp/selectivity/index.d.ts +6 -2
  63. package/build/src/browser/cdp/selectivity/index.js +147 -24
  64. package/build/src/browser/cdp/selectivity/index.js.map +1 -1
  65. package/build/src/browser/cdp/selectivity/js-selectivity.d.ts +11 -4
  66. package/build/src/browser/cdp/selectivity/js-selectivity.js +200 -87
  67. package/build/src/browser/cdp/selectivity/js-selectivity.js.map +1 -1
  68. package/build/src/browser/cdp/selectivity/json-utils.d.ts +5 -0
  69. package/build/src/browser/cdp/selectivity/json-utils.js +19 -9
  70. package/build/src/browser/cdp/selectivity/json-utils.js.map +1 -1
  71. package/build/src/browser/cdp/selectivity/merge-dumps/index.d.ts +2 -0
  72. package/build/src/browser/cdp/selectivity/merge-dumps/index.js +28 -0
  73. package/build/src/browser/cdp/selectivity/merge-dumps/index.js.map +1 -0
  74. package/build/src/browser/cdp/selectivity/merge-dumps/merge-hashes.d.ts +2 -0
  75. package/build/src/browser/cdp/selectivity/merge-dumps/merge-hashes.js +39 -0
  76. package/build/src/browser/cdp/selectivity/merge-dumps/merge-hashes.js.map +1 -0
  77. package/build/src/browser/cdp/selectivity/merge-dumps/merge-tests.d.ts +2 -0
  78. package/build/src/browser/cdp/selectivity/merge-dumps/merge-tests.js +129 -0
  79. package/build/src/browser/cdp/selectivity/merge-dumps/merge-tests.js.map +1 -0
  80. package/build/src/browser/cdp/selectivity/modes.d.ts +4 -0
  81. package/build/src/browser/cdp/selectivity/modes.js +11 -0
  82. package/build/src/browser/cdp/selectivity/modes.js.map +1 -0
  83. package/build/src/browser/cdp/selectivity/runner.d.ts +5 -0
  84. package/build/src/browser/cdp/selectivity/runner.js +114 -22
  85. package/build/src/browser/cdp/selectivity/runner.js.map +1 -1
  86. package/build/src/browser/cdp/selectivity/test-dependencies-reader.js +1 -1
  87. package/build/src/browser/cdp/selectivity/test-dependencies-reader.js.map +1 -1
  88. package/build/src/browser/cdp/selectivity/test-dependencies-writer.js +1 -1
  89. package/build/src/browser/cdp/selectivity/test-dependencies-writer.js.map +1 -1
  90. package/build/src/browser/cdp/selectivity/testplane-selectivity.d.ts +3 -1
  91. package/build/src/browser/cdp/selectivity/testplane-selectivity.js +64 -13
  92. package/build/src/browser/cdp/selectivity/testplane-selectivity.js.map +1 -1
  93. package/build/src/browser/cdp/selectivity/types.d.ts +6 -0
  94. package/build/src/browser/cdp/selectivity/types.js.map +1 -1
  95. package/build/src/browser/cdp/selectivity/used-dumps-tracker.d.ts +7 -0
  96. package/build/src/browser/cdp/selectivity/used-dumps-tracker.js +25 -0
  97. package/build/src/browser/cdp/selectivity/used-dumps-tracker.js.map +1 -0
  98. package/build/src/browser/cdp/selectivity/utils.d.ts +18 -9
  99. package/build/src/browser/cdp/selectivity/utils.js +111 -34
  100. package/build/src/browser/cdp/selectivity/utils.js.map +1 -1
  101. package/build/src/browser/cdp/types.d.ts +214 -0
  102. package/build/src/browser/cdp/utils.d.ts +0 -6
  103. package/build/src/browser/cdp/utils.js +1 -6
  104. package/build/src/browser/cdp/utils.js.map +1 -1
  105. package/build/src/browser/client-scripts/calibrate.js +2 -2
  106. package/build/src/browser/client-scripts/rrweb-record.min.js +2 -2
  107. package/build/src/browser/client-scripts/screen-shooter/build/bundle.compat.js +10 -10
  108. package/build/src/browser/client-scripts/screen-shooter/build/bundle.native.js +10 -10
  109. package/build/src/browser/client-scripts/screen-shooter/tsc-out/client-scripts/screen-shooter/implementation.js +21 -8
  110. package/build/src/browser/client-scripts/screen-shooter/tsc-out/client-scripts/screen-shooter/operations.js +57 -29
  111. package/build/src/browser/commands/assert-view/errors/image-diff-error.d.ts +1 -0
  112. package/build/src/browser/commands/assert-view/index.js +23 -3
  113. package/build/src/browser/commands/assert-view/index.js.map +1 -1
  114. package/build/src/browser/commands/openAndWait.js +23 -26
  115. package/build/src/browser/commands/openAndWait.js.map +1 -1
  116. package/build/src/browser/commands/restoreState/index.js +19 -8
  117. package/build/src/browser/commands/restoreState/index.js.map +1 -1
  118. package/build/src/browser/commands/saveState/index.d.ts +1 -2
  119. package/build/src/browser/commands/saveState/index.js +8 -12
  120. package/build/src/browser/commands/saveState/index.js.map +1 -1
  121. package/build/src/browser/commands/switchToRepl.js +27 -9
  122. package/build/src/browser/commands/switchToRepl.js.map +1 -1
  123. package/build/src/browser/existing-browser.d.ts +2 -0
  124. package/build/src/browser/existing-browser.js +15 -0
  125. package/build/src/browser/existing-browser.js.map +1 -1
  126. package/build/src/browser/history/index.d.ts +8 -1
  127. package/build/src/browser/history/index.js +41 -17
  128. package/build/src/browser/history/index.js.map +1 -1
  129. package/build/src/browser/history/rrweb.d.ts +3 -1
  130. package/build/src/browser/history/rrweb.js +122 -27
  131. package/build/src/browser/history/rrweb.js.map +1 -1
  132. package/build/src/browser/isomorphic/tsconfig.tsbuildinfo +1 -1
  133. package/build/src/browser/new-browser.d.ts +1 -1
  134. package/build/src/browser/new-browser.js +6 -12
  135. package/build/src/browser/new-browser.js.map +1 -1
  136. package/build/src/browser/screen-shooter/composite-image/index.d.ts +23 -0
  137. package/build/src/browser/screen-shooter/composite-image/index.js +161 -14
  138. package/build/src/browser/screen-shooter/composite-image/index.js.map +1 -1
  139. package/build/src/browser/screen-shooter/debug.d.ts +3 -0
  140. package/build/src/browser/screen-shooter/debug.js +25 -0
  141. package/build/src/browser/screen-shooter/debug.js.map +1 -0
  142. package/build/src/browser/screen-shooter/elements-screen-shooter.d.ts +0 -1
  143. package/build/src/browser/screen-shooter/elements-screen-shooter.js +127 -75
  144. package/build/src/browser/screen-shooter/elements-screen-shooter.js.map +1 -1
  145. package/build/src/browser/screen-shooter/full-page-screen-shooter.d.ts +3 -2
  146. package/build/src/browser/screen-shooter/full-page-screen-shooter.js +19 -15
  147. package/build/src/browser/screen-shooter/full-page-screen-shooter.js.map +1 -1
  148. package/build/src/browser/screen-shooter/operations/index.d.ts +1 -0
  149. package/build/src/browser/screen-shooter/operations/index.js +3 -1
  150. package/build/src/browser/screen-shooter/operations/index.js.map +1 -1
  151. package/build/src/browser/screen-shooter/operations/pointer-events.js +7 -0
  152. package/build/src/browser/screen-shooter/operations/pointer-events.js.map +1 -1
  153. package/build/src/browser/screen-shooter/operations/wait-for-selectors-to-settle.d.ts +2 -0
  154. package/build/src/browser/screen-shooter/operations/wait-for-selectors-to-settle.js +133 -0
  155. package/build/src/browser/screen-shooter/operations/wait-for-selectors-to-settle.js.map +1 -0
  156. package/build/src/browser/screen-shooter/viewport-screen-shooter.d.ts +2 -1
  157. package/build/src/browser/screen-shooter/viewport-screen-shooter.js +3 -5
  158. package/build/src/browser/screen-shooter/viewport-screen-shooter.js.map +1 -1
  159. package/build/src/browser/types.d.ts +6 -4
  160. package/build/src/browser/wsdriver/compression.d.ts +5 -0
  161. package/build/src/browser/wsdriver/compression.js +79 -0
  162. package/build/src/browser/wsdriver/compression.js.map +1 -0
  163. package/build/src/browser/wsdriver/constants.d.ts +11 -0
  164. package/build/src/browser/wsdriver/constants.js +15 -0
  165. package/build/src/browser/wsdriver/constants.js.map +1 -0
  166. package/build/src/browser/wsdriver/debug.d.ts +2 -0
  167. package/build/src/browser/wsdriver/debug.js +9 -0
  168. package/build/src/browser/wsdriver/debug.js.map +1 -0
  169. package/build/src/browser/wsdriver/error.d.ts +18 -0
  170. package/build/src/browser/wsdriver/error.js +36 -0
  171. package/build/src/browser/wsdriver/error.js.map +1 -0
  172. package/build/src/browser/wsdriver/index.d.ts +23 -0
  173. package/build/src/browser/wsdriver/index.js +261 -0
  174. package/build/src/browser/wsdriver/index.js.map +1 -0
  175. package/build/src/browser/wsdriver/request.d.ts +10 -0
  176. package/build/src/browser/wsdriver/request.js +58 -0
  177. package/build/src/browser/wsdriver/request.js.map +1 -0
  178. package/build/src/browser/wsdriver/response.d.ts +3 -0
  179. package/build/src/browser/wsdriver/response.js +111 -0
  180. package/build/src/browser/wsdriver/response.js.map +1 -0
  181. package/build/src/browser/wsdriver/types.d.ts +71 -0
  182. package/build/src/browser/wsdriver/types.js +27 -0
  183. package/build/src/browser/wsdriver/types.js.map +1 -0
  184. package/build/src/browser-pool/basic-pool.js +3 -1
  185. package/build/src/browser-pool/basic-pool.js.map +1 -1
  186. package/build/src/cli/commands/selectivity-merge-dumps/index.d.ts +2 -0
  187. package/build/src/cli/commands/selectivity-merge-dumps/index.js +50 -0
  188. package/build/src/cli/commands/selectivity-merge-dumps/index.js.map +1 -0
  189. package/build/src/cli/constants.d.ts +1 -0
  190. package/build/src/cli/constants.js +1 -0
  191. package/build/src/cli/constants.js.map +1 -1
  192. package/build/src/cli/index.js +3 -5
  193. package/build/src/cli/index.js.map +1 -1
  194. package/build/src/config/browser-options.js +11 -3
  195. package/build/src/config/browser-options.js.map +1 -1
  196. package/build/src/config/defaults.d.ts +7 -2
  197. package/build/src/config/defaults.js +10 -5
  198. package/build/src/config/defaults.js.map +1 -1
  199. package/build/src/config/index.d.ts +10 -6
  200. package/build/src/config/index.js +67 -42
  201. package/build/src/config/index.js.map +1 -1
  202. package/build/src/config/types.d.ts +59 -14
  203. package/build/src/config/types.js +15 -5
  204. package/build/src/config/types.js.map +1 -1
  205. package/build/src/config/utils.d.ts +2 -2
  206. package/build/src/config/utils.js +11 -6
  207. package/build/src/config/utils.js.map +1 -1
  208. package/build/src/constants/config.d.ts +0 -1
  209. package/build/src/constants/config.js +1 -2
  210. package/build/src/constants/config.js.map +1 -1
  211. package/build/src/constants/png.d.ts +1 -0
  212. package/build/src/constants/repl.d.ts +2 -0
  213. package/build/src/constants/repl.js +6 -0
  214. package/build/src/constants/repl.js.map +1 -0
  215. package/build/src/dev-server/index.d.ts +1 -1
  216. package/build/src/dev-server/index.js +1 -1
  217. package/build/src/dev-server/index.js.map +1 -1
  218. package/build/src/globals.d.ts +7 -0
  219. package/build/src/globals.js +10 -0
  220. package/build/src/globals.js.map +1 -0
  221. package/build/src/image.d.ts +6 -1
  222. package/build/src/image.js +56 -2
  223. package/build/src/image.js.map +1 -1
  224. package/build/src/index.d.ts +3 -13
  225. package/build/src/index.js +5 -1
  226. package/build/src/index.js.map +1 -1
  227. package/build/src/runner/browser-env/vite/browser-modules/driver.js +6 -8
  228. package/build/src/runner/browser-env/vite/browser-modules/driver.js.map +1 -1
  229. package/build/src/runner/browser-env/vite/browser-modules/tsconfig.tsbuildinfo +1 -1
  230. package/build/src/runner/browser-env/vite/browser-modules/types.d.ts +1 -1
  231. package/build/src/runner/index.js +1 -0
  232. package/build/src/runner/index.js.map +1 -1
  233. package/build/src/runner/suite-monitor.d.ts +1 -1
  234. package/build/src/runner/test-runner/regular-test-runner.js +2 -2
  235. package/build/src/runner/test-runner/regular-test-runner.js.map +1 -1
  236. package/build/src/signal-handler.d.ts +2 -2
  237. package/build/src/signal-handler.js +24 -11
  238. package/build/src/signal-handler.js.map +1 -1
  239. package/build/src/test-reader/mocha-reader/mocha-event-bus.d.ts +1 -1
  240. package/build/src/test-reader/test-parser.js +3 -3
  241. package/build/src/test-reader/test-parser.js.map +1 -1
  242. package/build/src/testplane.d.ts +4 -5
  243. package/build/src/testplane.js +20 -10
  244. package/build/src/testplane.js.map +1 -1
  245. package/build/src/types/globals.d.ts +16 -0
  246. package/build/src/types/globals.js +3 -0
  247. package/build/src/types/globals.js.map +1 -0
  248. package/build/src/types/index.d.ts +2 -3
  249. package/build/src/utils/crypto.d.ts +1 -0
  250. package/build/src/utils/crypto.js +2 -1
  251. package/build/src/utils/crypto.js.map +1 -1
  252. package/build/src/utils/eight-bit-rgba-to-png.d.ts +1 -0
  253. package/build/src/utils/repl-instrumentation/index.d.ts +1 -0
  254. package/build/src/utils/repl-instrumentation/index.js +46 -0
  255. package/build/src/utils/repl-instrumentation/index.js.map +1 -0
  256. package/build/src/utils/repl-instrumentation/typescript.d.ts +7 -0
  257. package/build/src/utils/repl-instrumentation/typescript.js +307 -0
  258. package/build/src/utils/repl-instrumentation/typescript.js.map +1 -0
  259. package/build/src/utils/repl-module-hooks.d.ts +1 -0
  260. package/build/src/utils/repl-module-hooks.js +111 -0
  261. package/build/src/utils/repl-module-hooks.js.map +1 -0
  262. package/build/src/utils/workers-registry.d.ts +2 -2
  263. package/build/src/utils/workers-registry.js +1 -0
  264. package/build/src/utils/workers-registry.js.map +1 -1
  265. package/build/src/vendors/expect-webdriverio/matchers-overrides.d.ts +49 -0
  266. package/build/src/vendors/expect-webdriverio/matchers-overrides.js +3 -0
  267. package/build/src/vendors/expect-webdriverio/matchers-overrides.js.map +1 -0
  268. package/build/src/worker/runner/browser-pool.js +4 -1
  269. package/build/src/worker/runner/browser-pool.js.map +1 -1
  270. package/build/src/worker/runner/index.js +6 -3
  271. package/build/src/worker/runner/index.js.map +1 -1
  272. package/build/src/worker/runner/sequence-test-parser.js +5 -7
  273. package/build/src/worker/runner/sequence-test-parser.js.map +1 -1
  274. package/build/src/worker/runner/test-runner/capture-fail-screenshot.js +2 -3
  275. package/build/src/worker/runner/test-runner/capture-fail-screenshot.js.map +1 -1
  276. package/build/src/worker/runner/test-runner/execution-thread.d.ts +0 -1
  277. package/build/src/worker/runner/test-runner/execution-thread.js +0 -5
  278. package/build/src/worker/runner/test-runner/execution-thread.js.map +1 -1
  279. package/build/src/worker/runner/test-runner/index.d.ts +1 -0
  280. package/build/src/worker/runner/test-runner/index.js +47 -2
  281. package/build/src/worker/runner/test-runner/index.js.map +1 -1
  282. package/build/src/worker/testplane-facade.js +5 -3
  283. package/build/src/worker/testplane-facade.js.map +1 -1
  284. package/build/src/worker/testplane.d.ts +1 -0
  285. package/build/src/worker/testplane.js +4 -1
  286. package/build/src/worker/testplane.js.map +1 -1
  287. package/build/src/ws-connection/constants.d.ts +13 -0
  288. package/build/src/ws-connection/constants.js +17 -0
  289. package/build/src/ws-connection/constants.js.map +1 -0
  290. package/build/src/ws-connection/error.d.ts +52 -0
  291. package/build/src/ws-connection/error.js +84 -0
  292. package/build/src/ws-connection/error.js.map +1 -0
  293. package/build/src/ws-connection/index.d.ts +83 -0
  294. package/build/src/ws-connection/index.js +397 -0
  295. package/build/src/ws-connection/index.js.map +1 -0
  296. package/build/src/ws-connection/utils.d.ts +6 -0
  297. package/build/src/ws-connection/utils.js +9 -0
  298. package/build/src/ws-connection/utils.js.map +1 -0
  299. package/package.json +11 -11
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.startSelectivity = exports.updateSelectivityHashes = void 0;
6
+ exports.startSelectivity = exports.clearUnusedSelectivityDumps = exports.updateSelectivityHashes = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
4
9
  const css_selectivity_1 = require("./css-selectivity");
5
10
  const js_selectivity_1 = require("./js-selectivity");
6
11
  const test_dependencies_writer_1 = require("./test-dependencies-writer");
@@ -10,16 +15,24 @@ const types_1 = require("./types");
10
15
  const testplane_selectivity_1 = require("./testplane-selectivity");
11
16
  const hash_reader_1 = require("./hash-reader");
12
17
  const events_1 = require("../../../events");
18
+ const modes_1 = require("./modes");
19
+ const debug_1 = require("./debug");
20
+ const used_dumps_tracker_1 = require("./used-dumps-tracker");
13
21
  /**
14
- * Called at the end of successfull testplane run
22
+ * Called at the end of testplane run
15
23
  * Not using "Promise.all" here because all hashes are already calculated and cached at the start
16
24
  */
17
- const updateSelectivityHashes = async (config) => {
25
+ const updateSelectivityHashes = async (config, isRunFailed) => {
18
26
  const browserIds = config.getBrowserIds();
27
+ const processedRoots = new Set();
19
28
  for (const browserId of browserIds) {
20
29
  const browserConfig = config.forBrowser(browserId);
21
- const { enabled, testDependenciesPath, compression, disableSelectivityPatterns } = browserConfig.selectivity;
22
- if (!enabled) {
30
+ const { enabled, testDependenciesPath, compression, disableSelectivityPatterns, saveIncompleteDumpOnFail } = browserConfig.selectivity;
31
+ const rootKey = `${testDependenciesPath}#${compression}`;
32
+ if ((isRunFailed || browserConfig.lastFailed.only) && !saveIncompleteDumpOnFail) {
33
+ continue;
34
+ }
35
+ if (!(0, modes_1.selectivityShouldWrite)(enabled) || processedRoots.has(rootKey)) {
23
36
  continue;
24
37
  }
25
38
  const hashReader = (0, hash_reader_1.getHashReader)(testDependenciesPath, compression);
@@ -30,13 +43,84 @@ const updateSelectivityHashes = async (config) => {
30
43
  hashWriter.addPatternDependencyHash(pattern);
31
44
  }
32
45
  }
33
- await hashWriter.commit();
46
+ try {
47
+ await hashWriter.save();
48
+ }
49
+ catch (cause) {
50
+ throw new Error(["Selectivity: couldn't save test dependencies hash", String(cause)].join("\n"));
51
+ }
52
+ processedRoots.add(rootKey);
34
53
  }
35
54
  };
36
55
  exports.updateSelectivityHashes = updateSelectivityHashes;
56
+ /**
57
+ * Called at the end of testplane run
58
+ */
59
+ const clearUnusedSelectivityDumps = async (config, isRunFailed) => {
60
+ if (process.env.TESTPLANE_SELECTIVITY_CLEAR_UNUSED_DUMPS === "false") {
61
+ return;
62
+ }
63
+ const usedDumpsTracker = (0, used_dumps_tracker_1.getUsedDumpsTracker)();
64
+ const browserIds = config.getBrowserIds();
65
+ const selectivityRoots = [];
66
+ for (const browserId of browserIds) {
67
+ const browserConfig = config.forBrowser(browserId);
68
+ const { enabled, testDependenciesPath, saveIncompleteDumpOnFail } = browserConfig.selectivity;
69
+ if ((isRunFailed && !saveIncompleteDumpOnFail) || browserConfig.lastFailed.only) {
70
+ continue;
71
+ }
72
+ else if ((0, modes_1.selectivityShouldWrite)(enabled) && !selectivityRoots.includes(testDependenciesPath)) {
73
+ selectivityRoots.push(testDependenciesPath);
74
+ }
75
+ }
76
+ let filesTotal = 0;
77
+ let filesDeleted = 0;
78
+ // eslint-disable-next-line no-bitwise
79
+ const rwMode = fs_extra_1.default.constants.R_OK | fs_extra_1.default.constants.W_OK;
80
+ await Promise.all(selectivityRoots.map(async (selectivityRoot) => {
81
+ if (!usedDumpsTracker.usedDumpsFor(selectivityRoot)) {
82
+ return;
83
+ }
84
+ const testsPath = (0, utils_1.getSelectivityTestsPath)(selectivityRoot);
85
+ const accessError = await fs_extra_1.default.access(testsPath, rwMode).catch((err) => err);
86
+ if (accessError) {
87
+ if (!("code" in accessError && accessError.code === "ENOENT")) {
88
+ (0, debug_1.debugSelectivity)(`Couldn't access "${testsPath}" to clear stale files: %O`, accessError);
89
+ }
90
+ return;
91
+ }
92
+ const testsFileNames = await fs_extra_1.default.readdir(testsPath);
93
+ filesTotal += testsFileNames.length;
94
+ for (const testFileName of testsFileNames) {
95
+ const extensionPosition = testFileName.indexOf(".json");
96
+ // If the file does not look like selectivity test dependencies, skip it
97
+ if (extensionPosition === -1) {
98
+ continue;
99
+ }
100
+ const dumpId = testFileName.slice(0, extensionPosition);
101
+ if (!usedDumpsTracker.wasUsed(dumpId, selectivityRoot)) {
102
+ const filePath = node_path_1.default.join(testsPath, testFileName);
103
+ await fs_extra_1.default
104
+ .unlink(filePath)
105
+ .then(() => {
106
+ filesDeleted++;
107
+ })
108
+ .catch(err => {
109
+ (0, debug_1.debugSelectivity)(`Couldn't remove stale file "${filePath}": %O`, err);
110
+ });
111
+ }
112
+ }
113
+ }));
114
+ if (filesDeleted) {
115
+ (0, debug_1.debugSelectivity)(`Out of ${filesTotal} dump files, ${filesDeleted} were considered as outdated and deleted`);
116
+ }
117
+ };
118
+ exports.clearUnusedSelectivityDumps = clearUnusedSelectivityDumps;
119
+ const testplaneCoverageBreakScriptName = "__testplane_cdp_coverage_snapshot_pause";
120
+ const scriptToEvaluateOnNewDocument = `window.addEventListener("beforeunload", function ${testplaneCoverageBreakScriptName}() {debugger;});`;
37
121
  const startSelectivity = async (browser) => {
38
- const { enabled, compression, sourceRoot, testDependenciesPath, mapDependencyRelativePath } = browser.config.selectivity;
39
- if (!enabled || !browser.publicAPI.isChromium) {
122
+ const { enabled, compression, sourceRoot, testDependenciesPath, mapDependencyRelativePath, mapSourceMapUrl } = browser.config.selectivity;
123
+ if (!(0, modes_1.selectivityShouldWrite)(enabled) || !browser.publicAPI.isChromium) {
40
124
  return () => Promise.resolve();
41
125
  }
42
126
  if (compression === types_1.Compression.ZSTD && !process.versions.zstd) {
@@ -45,9 +129,9 @@ const startSelectivity = async (browser) => {
45
129
  if (!browser.cdp) {
46
130
  throw new Error("Selectivity: Devtools connection is not established, couldn't record selectivity without it");
47
131
  }
48
- const cdpTaget = browser.cdp.target;
132
+ const cdp = browser.cdp;
49
133
  const handle = await browser.publicAPI.getWindowHandle();
50
- const { targetInfos } = await cdpTaget.getTargets();
134
+ const { targetInfos } = await cdp.target.getTargets();
51
135
  const cdpTargetId = targetInfos.find(t => handle.includes(t.targetId))?.targetId;
52
136
  if (!cdpTargetId) {
53
137
  throw new Error([
@@ -56,29 +140,68 @@ const startSelectivity = async (browser) => {
56
140
  `\n\t- cdp targets: ${targetInfos.map(t => `"${t.targetId}"`).join(", ")}`,
57
141
  ].join(""));
58
142
  }
59
- const sessionId = await cdpTaget.attachToTarget(cdpTargetId).then(r => r.sessionId);
60
- const cssSelectivity = new css_selectivity_1.CSSSelectivity(browser.cdp, sessionId, sourceRoot);
61
- const jsSelectivity = new js_selectivity_1.JSSelectivity(browser.cdp, sessionId, sourceRoot);
62
- await Promise.all([cssSelectivity.start(), jsSelectivity.start()]);
143
+ const wdSessionId = browser.sessionId;
144
+ const cdpSessionId = await cdp.target.attachToTarget(cdpTargetId).then(r => r.sessionId);
145
+ const cssSelectivity = new css_selectivity_1.CSSSelectivity(cdp, cdpSessionId, wdSessionId, sourceRoot, mapSourceMapUrl);
146
+ const jsSelectivity = new js_selectivity_1.JSSelectivity(cdp, cdpSessionId, sourceRoot, mapSourceMapUrl);
147
+ await Promise.all([
148
+ cdp.dom.enable(cdpSessionId).then(() => cdp.css.enable(cdpSessionId)),
149
+ cdp.target.setAutoAttach(cdpSessionId, { autoAttach: true, waitForDebuggerOnStart: false }),
150
+ cdp.debugger.enable(cdpSessionId),
151
+ cdp.page.enable(cdpSessionId),
152
+ cdp.profiler.enable(cdpSessionId),
153
+ ]);
154
+ await Promise.allSettled([cssSelectivity.start(), jsSelectivity.start()]).then(async ([css, js]) => {
155
+ if (css.status === "rejected" || js.status === "rejected") {
156
+ await Promise.all([cssSelectivity.stop(true), jsSelectivity.stop(true)]);
157
+ const originalError = css.status === "rejected" ? css.reason : js.status === "rejected" ? js.reason : "unknown reason";
158
+ throw new Error(["Selectivity: Couldn't start selectivity:", String(originalError)].join("\n"));
159
+ }
160
+ });
161
+ let pageSwitchPromise = Promise.resolve();
162
+ let isSelectivityStopped = false;
163
+ const debuggerPausedFn = ({ callFrames }, eventCdpSessionId) => {
164
+ if (eventCdpSessionId !== cdpSessionId) {
165
+ return;
166
+ }
167
+ if (callFrames[0]?.functionName !== testplaneCoverageBreakScriptName || isSelectivityStopped) {
168
+ cdp.debugger.resume(cdpSessionId).catch(() => { });
169
+ return;
170
+ }
171
+ pageSwitchPromise = pageSwitchPromise.finally(() => Promise.all([cssSelectivity.takeCoverageSnapshot(), jsSelectivity.takeCoverageSnapshot()])
172
+ .catch(err => {
173
+ console.error("Selectivity: couldn't take snapshot while navigating:", err);
174
+ })
175
+ .then(() => {
176
+ cdp.debugger.resume(cdpSessionId).catch(() => { });
177
+ }));
178
+ };
179
+ cdp.debugger.on("paused", debuggerPausedFn);
180
+ await cdp.page.addScriptToEvaluateOnNewDocument(cdpSessionId, { source: scriptToEvaluateOnNewDocument });
63
181
  /** @param drop only performs cleanup without writing anything. Should be "true" if test is failed */
64
182
  return async function stopSelectivity(test, drop) {
65
- const [cssDependencies, jsDependencies] = await Promise.all([
183
+ isSelectivityStopped = true;
184
+ await pageSwitchPromise;
185
+ const [cssDependenciesPromise, jsDependenciesPromise] = await Promise.allSettled([
66
186
  cssSelectivity.stop(drop),
67
187
  jsSelectivity.stop(drop),
68
188
  ]);
69
- cdpTaget.detachFromTarget(sessionId).catch(() => { });
189
+ cdp.debugger.off("paused", debuggerPausedFn);
190
+ cdp.target.detachFromTarget(cdpSessionId).catch(() => { });
191
+ if (jsDependenciesPromise.status === "rejected") {
192
+ throw jsDependenciesPromise.reason;
193
+ }
194
+ if (cssDependenciesPromise.status === "rejected") {
195
+ throw cssDependenciesPromise.reason;
196
+ }
197
+ const cssDependencies = cssDependenciesPromise.value;
198
+ const jsDependencies = jsDependenciesPromise.value;
70
199
  if (drop || (!cssDependencies?.size && !jsDependencies?.size)) {
71
200
  return;
72
201
  }
73
- const mapBrowserDepsRelativePath = mapDependencyRelativePath
74
- ? (relativePath) => mapDependencyRelativePath({ scope: "browser", relativePath })
75
- : null;
76
- const mapTestplaneDepsRelativePath = mapDependencyRelativePath
77
- ? (relativePath) => mapDependencyRelativePath({ scope: "testplane", relativePath })
78
- : null;
79
202
  const testDependencyWriter = (0, test_dependencies_writer_1.getTestDependenciesWriter)(testDependenciesPath, compression);
80
- const browserDeps = (0, utils_1.transformSourceDependencies)(cssDependencies, jsDependencies, mapBrowserDepsRelativePath);
81
- const testplaneDeps = (0, utils_1.transformSourceDependencies)(null, (0, testplane_selectivity_1.getCollectedTestplaneDependencies)(), mapTestplaneDepsRelativePath);
203
+ const browserDeps = (0, utils_1.transformSourceDependencies)({ css: cssDependencies, js: jsDependencies, png: null }, mapDependencyRelativePath, "browser");
204
+ const testplaneDeps = (0, utils_1.transformSourceDependencies)({ css: null, js: (0, testplane_selectivity_1.getCollectedTestplaneJsDependencies)(), png: (0, testplane_selectivity_1.getCollectedTestplanePngDependencies)() }, mapDependencyRelativePath, "testplane");
82
205
  process.send?.({
83
206
  event: events_1.MasterEvents.TEST_DEPENDENCIES,
84
207
  context: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/browser/cdp/selectivity/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/browser/cdp/selectivity/index.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,23 @@
1
1
  import type { CDP } from "..";
2
2
  import type { CDPSessionId } from "../types";
3
+ import type { SelectivityMapSourceMapUrlFn } from "../../../config/types";
3
4
  export declare class JSSelectivity {
4
5
  private readonly _cdp;
5
6
  private readonly _sessionId;
6
7
  private readonly _sourceRoot;
7
- private _debuggerOnPausedFn;
8
+ private readonly _mapSourceMapUrl;
8
9
  private _debuggerOnScriptParsedFn;
9
- private _scriptsSource;
10
- private _scriptsSourceMap;
11
- constructor(cdp: CDP, sessionId: CDPSessionId, sourceRoot?: string);
10
+ private readonly _scriptsSource;
11
+ private readonly _scriptsSourceMap;
12
+ private readonly _scriptIdToSourceUrl;
13
+ private readonly _scriptIdToSourceMapUrl;
14
+ private readonly _coverageResult;
15
+ constructor(cdp: CDP, sessionId: CDPSessionId, sourceRoot: string, mapSourceMapUrl: SelectivityMapSourceMapUrlFn | null);
12
16
  private _processScript;
17
+ private _ensureScriptsAreLoading;
18
+ private _waitForLoadingScripts;
13
19
  start(): Promise<void>;
20
+ takeCoverageSnapshot(): Promise<void>;
14
21
  /** @param drop only performs cleanup without providing actual deps. Should be "true" if test is failed */
15
22
  stop(drop?: boolean): Promise<Set<string> | null>;
16
23
  }
@@ -5,124 +5,237 @@ const lodash_1 = require("lodash");
5
5
  const node_url_1 = require("node:url");
6
6
  const constants_1 = require("../../../error-snippets/constants");
7
7
  const utils_1 = require("./utils");
8
+ const fs_cache_1 = require("./fs-cache");
9
+ const debug_1 = require("./debug");
8
10
  const SOURCE_CODE_EXTENSIONS = [".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs", ".mts", ".cts"];
9
11
  const isSourceCodeFile = (sourceFileName) => {
10
12
  return SOURCE_CODE_EXTENSIONS.some(ext => sourceFileName.endsWith(ext));
11
13
  };
12
14
  class JSSelectivity {
13
- constructor(cdp, sessionId, sourceRoot = "") {
14
- this._debuggerOnPausedFn = null;
15
+ constructor(cdp, sessionId, sourceRoot, mapSourceMapUrl) {
15
16
  this._debuggerOnScriptParsedFn = null;
16
17
  this._scriptsSource = {};
17
18
  this._scriptsSourceMap = {};
19
+ this._scriptIdToSourceUrl = {};
20
+ this._scriptIdToSourceMapUrl = {};
21
+ this._coverageResult = [];
18
22
  this._cdp = cdp;
19
23
  this._sessionId = sessionId;
20
24
  this._sourceRoot = sourceRoot;
25
+ this._mapSourceMapUrl = mapSourceMapUrl;
21
26
  }
22
- _processScript({ scriptId, url, sourceMapURL }) {
23
- if (!this._sessionId) {
27
+ _processScript({ scriptId, url, sourceMapURL }, cdpSessionId) {
28
+ if (!this._sessionId || cdpSessionId !== this._sessionId) {
24
29
  return;
25
30
  }
26
- if (!url || !sourceMapURL) {
31
+ this._scriptIdToSourceUrl[scriptId] ||= url;
32
+ if (!url || !sourceMapURL || url.startsWith("chrome-error://")) {
27
33
  this._scriptsSource[scriptId] ||= null;
28
34
  this._scriptsSourceMap[scriptId] ||= null;
29
35
  return;
30
36
  }
31
- this._scriptsSource[scriptId] ||= this._cdp.debugger
32
- .getScriptSource(this._sessionId, scriptId)
33
- .then(res => res.scriptSource)
34
- .catch((err) => err);
35
- this._scriptsSourceMap[scriptId] ||= (0, utils_1.fetchTextWithBrowserFallback)((0, node_url_1.resolve)(url, sourceMapURL), this._cdp.runtime, this._sessionId);
37
+ if (this._scriptsSource[scriptId] && this._scriptsSourceMap[scriptId]) {
38
+ return;
39
+ }
40
+ let sourceMapResolvedUrl = (0, node_url_1.resolve)(url, sourceMapURL);
41
+ const mapResult = this._mapSourceMapUrl
42
+ ? this._mapSourceMapUrl({ type: "js", sourceUrl: url, sourceMapUrl: sourceMapResolvedUrl })
43
+ : true;
44
+ if (!mapResult) {
45
+ this._scriptsSource[scriptId] ||= null;
46
+ this._scriptsSourceMap[scriptId] ||= null;
47
+ return;
48
+ }
49
+ if (mapResult !== true) {
50
+ this._scriptIdToSourceMapUrl[scriptId] = sourceMapResolvedUrl = mapResult;
51
+ }
52
+ this._scriptsSource[scriptId] ||= (0, fs_cache_1.hasCachedSelectivityFile)(fs_cache_1.CacheType.Asset, url).then(isCached => {
53
+ return isCached
54
+ ? true
55
+ : this._cdp.debugger
56
+ .getScriptSource(this._sessionId, scriptId)
57
+ .then(res => res.scriptSource)
58
+ .then(data => (0, fs_cache_1.setCachedSelectivityFile)(fs_cache_1.CacheType.Asset, url, data)
59
+ .then(() => true)
60
+ .catch(err => {
61
+ (0, debug_1.debugSelectivity)(`Couldn't offload asset from "${url}" to fs-cache: %O`, err);
62
+ return data;
63
+ }))
64
+ .catch((err) => err);
65
+ });
66
+ // Embedded source maps are not cached on file system because of their large cache key
67
+ if ((0, utils_1.isDataProtocol)(sourceMapResolvedUrl)) {
68
+ this._scriptIdToSourceMapUrl[scriptId] = null;
69
+ this._scriptsSourceMap[scriptId] ||= (0, utils_1.fetchTextWithBrowserFallback)(sourceMapResolvedUrl, this._cdp.runtime, this._sessionId).catch((err) => err);
70
+ }
71
+ else {
72
+ this._scriptIdToSourceMapUrl[scriptId] = sourceMapResolvedUrl;
73
+ this._scriptsSourceMap[scriptId] ||= (0, fs_cache_1.hasCachedSelectivityFile)(fs_cache_1.CacheType.Asset, sourceMapResolvedUrl).then(isCached => {
74
+ return isCached
75
+ ? true
76
+ : (0, utils_1.fetchTextWithBrowserFallback)(sourceMapResolvedUrl, this._cdp.runtime, this._sessionId)
77
+ .then(data => (0, fs_cache_1.setCachedSelectivityFile)(fs_cache_1.CacheType.Asset, sourceMapResolvedUrl, data)
78
+ .then(() => true)
79
+ .catch(err => {
80
+ (0, debug_1.debugSelectivity)(`Couldn't offload asset from "${sourceMapResolvedUrl}" to fs-cache: %O`, err);
81
+ return data;
82
+ }))
83
+ .catch((err) => err);
84
+ });
85
+ }
36
86
  }
37
- async start() {
38
- const debuggerOnPaused = (this._debuggerOnPausedFn = async () => {
39
- return this._cdp.debugger.resume(this._sessionId).catch(() => { });
87
+ // If we haven't got "scriptParsed" event for the script, pull up source code + source map manually
88
+ _ensureScriptsAreLoading(coverage) {
89
+ coverage.forEach(({ scriptId, url }) => {
90
+ const fixedUrl = url || this._scriptIdToSourceUrl[scriptId];
91
+ const wasProcessed = Object.hasOwn(this._scriptsSource, scriptId) && Object.hasOwn(this._scriptsSourceMap, scriptId);
92
+ const isAnonymous = !fixedUrl;
93
+ const urlWasCorrected = url && url !== this._scriptIdToSourceUrl[scriptId];
94
+ const shouldRecalculateSource = Boolean(urlWasCorrected && this._mapSourceMapUrl);
95
+ if ((wasProcessed && !shouldRecalculateSource) || isAnonymous) {
96
+ return;
97
+ }
98
+ // Not dropping sources to fs the end of test (when "stop" is called) because we use it immediately
99
+ const scriptSourcePromise = (async () => {
100
+ const currentValue = await this._scriptsSource[scriptId];
101
+ const cacheResolvedValue = (0, utils_1.isCachedOnFs)(currentValue)
102
+ ? await (0, fs_cache_1.getCachedSelectivityFile)(fs_cache_1.CacheType.Asset, fixedUrl)
103
+ : currentValue;
104
+ if (cacheResolvedValue && typeof cacheResolvedValue === "string") {
105
+ return cacheResolvedValue;
106
+ }
107
+ return this._cdp.debugger
108
+ .getScriptSource(this._sessionId, scriptId)
109
+ .then(({ scriptSource }) => {
110
+ (0, fs_cache_1.setCachedSelectivityFile)(fs_cache_1.CacheType.Asset, fixedUrl, scriptSource).catch(() => { });
111
+ return scriptSource;
112
+ })
113
+ .catch((err) => err);
114
+ })();
115
+ this._scriptIdToSourceUrl[scriptId] ||= url;
116
+ this._scriptsSource[scriptId] ||= scriptSourcePromise;
117
+ if (!this._scriptsSourceMap[scriptId] || shouldRecalculateSource) {
118
+ this._scriptsSourceMap[scriptId] = scriptSourcePromise.then(async (sourceCode) => {
119
+ if (sourceCode instanceof Error) {
120
+ return sourceCode;
121
+ }
122
+ const sourceMapsStartIndex = sourceCode.lastIndexOf(constants_1.JS_SOURCE_MAP_URL_COMMENT);
123
+ const sourceMapsEndIndex = sourceCode.indexOf("\n", sourceMapsStartIndex);
124
+ // Source maps are not generated for this source file
125
+ if (sourceMapsStartIndex === -1) {
126
+ return null;
127
+ }
128
+ const sourceMapURL = sourceMapsEndIndex === -1
129
+ ? sourceCode.slice(sourceMapsStartIndex + constants_1.JS_SOURCE_MAP_URL_COMMENT.length)
130
+ : sourceCode.slice(sourceMapsStartIndex + constants_1.JS_SOURCE_MAP_URL_COMMENT.length, sourceMapsEndIndex);
131
+ let resolvedSourceMapUrl = (0, node_url_1.resolve)(fixedUrl, sourceMapURL);
132
+ const mappedResult = this._mapSourceMapUrl
133
+ ? this._mapSourceMapUrl({ type: "js", sourceUrl: fixedUrl, sourceMapUrl: resolvedSourceMapUrl })
134
+ : true;
135
+ if (!mappedResult) {
136
+ this._scriptsSource[scriptId] = null;
137
+ return null;
138
+ }
139
+ if (mappedResult !== true) {
140
+ this._scriptIdToSourceMapUrl[scriptId] = resolvedSourceMapUrl = mappedResult;
141
+ }
142
+ else {
143
+ this._scriptIdToSourceMapUrl[scriptId] ||= resolvedSourceMapUrl;
144
+ }
145
+ if ((0, utils_1.isDataProtocol)(resolvedSourceMapUrl)) {
146
+ return (0, utils_1.fetchTextWithBrowserFallback)(resolvedSourceMapUrl, this._cdp.runtime, this._sessionId).catch((err) => err);
147
+ }
148
+ try {
149
+ const cachedSourceMaps = await (0, fs_cache_1.getCachedSelectivityFile)(fs_cache_1.CacheType.Asset, resolvedSourceMapUrl);
150
+ if (cachedSourceMaps) {
151
+ return cachedSourceMaps;
152
+ }
153
+ const sourceMap = await (0, utils_1.fetchTextWithBrowserFallback)(resolvedSourceMapUrl, this._cdp.runtime, this._sessionId);
154
+ (0, fs_cache_1.setCachedSelectivityFile)(fs_cache_1.CacheType.Asset, resolvedSourceMapUrl, sourceMap).catch(() => { });
155
+ return sourceMap;
156
+ }
157
+ catch (err) {
158
+ return err;
159
+ }
160
+ });
161
+ }
40
162
  });
163
+ }
164
+ async _waitForLoadingScripts() {
165
+ await Promise.all([
166
+ Promise.allSettled(Object.values(this._scriptsSource)),
167
+ Promise.allSettled(Object.values(this._scriptsSourceMap)),
168
+ ]);
169
+ }
170
+ async start() {
41
171
  const debuggerOnScriptParsedFn = (this._debuggerOnScriptParsedFn = this._processScript.bind(this));
42
172
  const sessionId = this._sessionId;
43
- this._cdp.debugger.on("paused", debuggerOnPaused);
44
173
  this._cdp.debugger.on("scriptParsed", debuggerOnScriptParsedFn);
45
- await Promise.all([
46
- this._cdp.target.setAutoAttach(sessionId, { autoAttach: true, waitForDebuggerOnStart: false }),
47
- this._cdp.debugger.enable(sessionId),
48
- this._cdp.profiler.enable(sessionId).then(() => this._cdp.profiler.startPreciseCoverage(sessionId, {
49
- callCount: false,
50
- detailed: false,
51
- allowTriggeredUpdates: false,
52
- })),
53
- ]);
174
+ await this._cdp.profiler.startPreciseCoverage(sessionId, {
175
+ callCount: false,
176
+ detailed: false,
177
+ allowTriggeredUpdates: false,
178
+ });
179
+ }
180
+ async takeCoverageSnapshot() {
181
+ const coveragePart = await this._cdp.profiler.takePreciseCoverage(this._sessionId);
182
+ this._ensureScriptsAreLoading(coveragePart.result);
183
+ await this._waitForLoadingScripts();
184
+ this._coverageResult.push(...coveragePart.result);
54
185
  }
55
186
  /** @param drop only performs cleanup without providing actual deps. Should be "true" if test is failed */
56
187
  async stop(drop) {
57
- if (drop) {
58
- this._debuggerOnPausedFn && this._cdp.debugger.off("paused", this._debuggerOnPausedFn);
59
- this._debuggerOnScriptParsedFn && this._cdp.debugger.off("scriptParsed", this._debuggerOnScriptParsedFn);
60
- return null;
61
- }
62
- const coverage = await this._cdp.profiler.takePreciseCoverage(this._sessionId);
63
- const scriptsWithUrl = coverage.result.filter(script => script.url);
64
- // If we haven't got "scriptParsed" event for the script, pull up source code + source map manually
65
- scriptsWithUrl.forEach(({ scriptId, url }) => {
66
- if (Object.hasOwn(this._scriptsSource, scriptId) && Object.hasOwn(this._scriptsSourceMap, scriptId)) {
67
- return;
188
+ try {
189
+ if (drop) {
190
+ return null;
68
191
  }
69
- const scriptSourcePromise = this._cdp.debugger
70
- .getScriptSource(this._sessionId, scriptId)
71
- .then(res => res.scriptSource)
72
- .catch((err) => err);
73
- this._scriptsSource[scriptId] ||= scriptSourcePromise;
74
- this._scriptsSourceMap[scriptId] ||= scriptSourcePromise.then(sourceCode => {
75
- if (sourceCode instanceof Error) {
76
- return sourceCode;
192
+ const coverageLastPart = await this._cdp.profiler.takePreciseCoverage(this._sessionId);
193
+ const coverageScripts = [...this._coverageResult, ...coverageLastPart.result];
194
+ this._ensureScriptsAreLoading(coverageLastPart.result);
195
+ const totalDependingSourceFiles = new Set();
196
+ const grouppedByScriptCoverage = (0, lodash_1.groupBy)(coverageScripts, "scriptId");
197
+ const scriptIds = Object.keys(grouppedByScriptCoverage);
198
+ await Promise.all(scriptIds.map(async (scriptId) => {
199
+ const [source, sourceMaps] = await Promise.all([
200
+ this._scriptsSource[scriptId],
201
+ this._scriptsSourceMap[scriptId],
202
+ ]);
203
+ const sourceMapUrl = this._scriptIdToSourceMapUrl[scriptId];
204
+ // Every "scriptId" has only one uniq "url"
205
+ const sourceUrl = this._scriptIdToSourceUrl[scriptId] || grouppedByScriptCoverage[scriptId][0].url;
206
+ // Function was called, but source maps were not generated for the file
207
+ // Or its anonymous script, without source url
208
+ if (!source || !sourceMaps || !sourceUrl) {
209
+ return;
77
210
  }
78
- const sourceMapsStartIndex = sourceCode.lastIndexOf(constants_1.JS_SOURCE_MAP_URL_COMMENT);
79
- const sourceMapsEndIndex = sourceCode.indexOf("\n", sourceMapsStartIndex);
80
- if (sourceMapsStartIndex === -1) {
81
- return new Error("Source maping url comment is missing");
211
+ if (source instanceof Error) {
212
+ throw new Error([`JS Selectivity: Couldn't load source code from ${sourceUrl}:`, String(source)].join("\n"));
82
213
  }
83
- const sourceMapURL = sourceMapsEndIndex === -1
84
- ? sourceCode.slice(sourceMapsStartIndex + constants_1.JS_SOURCE_MAP_URL_COMMENT.length)
85
- : sourceCode.slice(sourceMapsStartIndex + constants_1.JS_SOURCE_MAP_URL_COMMENT.length, sourceMapsEndIndex);
86
- return (0, utils_1.fetchTextWithBrowserFallback)((0, node_url_1.resolve)(url, sourceMapURL), this._cdp.runtime, this._sessionId);
87
- });
88
- });
89
- const totalDependingSourceFiles = new Set();
90
- const grouppedByScriptCoverage = (0, lodash_1.groupBy)(coverage.result, "scriptId");
91
- const scriptIds = Object.keys(grouppedByScriptCoverage);
92
- await Promise.all(scriptIds.map(async (scriptId) => {
93
- // Every "scriptId" has only one uniq "url"
94
- const url = grouppedByScriptCoverage[scriptId][0].url;
95
- const [source, sourceMaps] = await Promise.all([
96
- this._scriptsSource[scriptId],
97
- this._scriptsSourceMap[scriptId],
98
- ]);
99
- if (!source || !sourceMaps) {
100
- return;
101
- }
102
- if (source instanceof Error) {
103
- throw new Error(`JS Selectivity: Couldn't load source code at ${url}: ${source}`);
104
- }
105
- if (sourceMaps instanceof Error) {
106
- throw new Error(`JS Selectivity: Couldn't load source maps of ${url}: ${sourceMaps}`);
107
- }
108
- const startOffsetsSet = new Set();
109
- grouppedByScriptCoverage[scriptId].forEach(entry => {
110
- entry.functions.forEach(fn => {
111
- fn.ranges.forEach(range => {
112
- startOffsetsSet.add(range.startOffset);
113
- });
114
- });
115
- });
116
- const dependingSourceFiles = await (0, utils_1.extractSourceFilesDeps)(source, sourceMaps, Array.from(startOffsetsSet), this._sourceRoot);
117
- for (const sourceFile of dependingSourceFiles.values()) {
118
- if (isSourceCodeFile(sourceFile)) {
214
+ if (sourceMaps instanceof Error) {
215
+ throw new Error([`JS Selectivity: Couldn't load source maps from ${sourceMapUrl}`, String(sourceMaps)].join("\n"));
216
+ }
217
+ if ((0, utils_1.isCachedOnFs)(sourceMaps) && !sourceMapUrl) {
218
+ throw new Error("Assertation failed: souce map url has to present if source maps are fs-cached");
219
+ }
220
+ const [sourceString, sourceMapsString] = await Promise.all([
221
+ (0, utils_1.isCachedOnFs)(source) ? (0, fs_cache_1.getCachedSelectivityFile)(fs_cache_1.CacheType.Asset, sourceUrl) : source,
222
+ (0, utils_1.isCachedOnFs)(sourceMaps)
223
+ ? (0, fs_cache_1.getCachedSelectivityFile)(fs_cache_1.CacheType.Asset, sourceMapUrl)
224
+ : sourceMaps,
225
+ ]);
226
+ if (!sourceString || !sourceMapsString) {
227
+ throw new Error(`JS Selectivity: fs-cache is broken for ${sourceUrl}`);
228
+ }
229
+ const dependingSourceFiles = (0, utils_1.extractSourceFilesDeps)(sourceString, sourceMapsString, grouppedByScriptCoverage[scriptId], this._sourceRoot, isSourceCodeFile);
230
+ for (const sourceFile of dependingSourceFiles.values()) {
119
231
  totalDependingSourceFiles.add(sourceFile);
120
232
  }
121
- }
122
- }));
123
- this._debuggerOnPausedFn && this._cdp.debugger.off("paused", this._debuggerOnPausedFn);
124
- this._debuggerOnScriptParsedFn && this._cdp.debugger.off("scriptParsed", this._debuggerOnScriptParsedFn);
125
- return totalDependingSourceFiles;
233
+ }));
234
+ return totalDependingSourceFiles;
235
+ }
236
+ finally {
237
+ this._debuggerOnScriptParsedFn && this._cdp.debugger.off("scriptParsed", this._debuggerOnScriptParsedFn);
238
+ }
126
239
  }
127
240
  }
128
241
  exports.JSSelectivity = JSSelectivity;