browser-commander 0.16.0 → 0.17.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 (62) hide show
  1. package/.changeset/config.json +1 -1
  2. package/.changeset/merged-loud-river.md +7 -0
  3. package/.jscpd-baseline.json +257 -0
  4. package/.jscpd.json +1 -3
  5. package/.prettierignore +1 -0
  6. package/CHANGELOG.md +22 -0
  7. package/eslint.config.js +23 -1
  8. package/package.json +13 -24
  9. package/scripts/changeset-version.mjs +2 -6
  10. package/scripts/create-github-release.mjs +7 -8
  11. package/scripts/create-manual-changeset.mjs +7 -8
  12. package/scripts/format-github-release.mjs +6 -7
  13. package/scripts/format-release-notes.mjs +7 -8
  14. package/scripts/instant-version-bump.mjs +7 -8
  15. package/scripts/publish-to-npm.mjs +7 -8
  16. package/scripts/setup-npm.mjs +2 -6
  17. package/scripts/version-and-commit.mjs +7 -8
  18. package/src/browser/browser-cookie-credentials.js +3 -1
  19. package/src/browser/browser-cookies.js +6 -2
  20. package/src/browser/browser-profiles.js +1 -1
  21. package/src/browser/launch-options.js +31 -8
  22. package/src/browser/launcher.js +16 -0
  23. package/src/exports.js +34 -0
  24. package/src/fingerprint/apply.js +116 -0
  25. package/src/fingerprint/automation-parity.js +224 -0
  26. package/src/fingerprint/cdp-overrides.js +176 -0
  27. package/src/fingerprint/derive.js +104 -0
  28. package/src/fingerprint/init-payload.js +181 -0
  29. package/src/fingerprint/init-script.js +104 -0
  30. package/src/fingerprint/limitations.js +107 -0
  31. package/src/fingerprint/limitations.json +96 -0
  32. package/src/fingerprint/presets.js +244 -0
  33. package/src/fingerprint/profile.js +428 -0
  34. package/src/tests/index.js +2 -1
  35. package/tests/e2e/fingerprint-parity.e2e.test.js +212 -0
  36. package/tests/helpers/mocks.js +4 -2
  37. package/tests/helpers/repo.js +74 -0
  38. package/tests/unit/browser/launch-options.test.js +9 -1
  39. package/tests/unit/experiments/fingerprint-parity-harness.test.js +97 -0
  40. package/tests/unit/fingerprint/apply.test.js +271 -0
  41. package/tests/unit/fingerprint/automation-parity.test.js +212 -0
  42. package/tests/unit/fingerprint/cdp-overrides.test.js +227 -0
  43. package/tests/unit/fingerprint/derive.test.js +105 -0
  44. package/tests/unit/fingerprint/init-script.test.js +357 -0
  45. package/tests/unit/fingerprint/limitations.test.js +184 -0
  46. package/tests/unit/fingerprint/presets.test.js +135 -0
  47. package/tests/unit/fingerprint/profile.test.js +282 -0
  48. package/tests/unit/scripts/check-pipeline-status.test.js +133 -0
  49. package/tests/unit/scripts/check-version-modification.test.js +70 -0
  50. package/tests/unit/scripts/check-web-archive.test.js +191 -0
  51. package/tests/unit/scripts/ci-timeout-budgets.test.js +311 -0
  52. package/tests/unit/scripts/ci-workflow-policy.test.js +217 -28
  53. package/tests/unit/scripts/debug-print.test.js +67 -0
  54. package/tests/unit/scripts/jscpd-config.test.js +141 -0
  55. package/tests/unit/scripts/pre-commit-config.test.js +209 -0
  56. package/tests/unit/scripts/read-manifest.test.js +194 -0
  57. package/tests/unit/scripts/run-with-budget-warning.test.js +115 -0
  58. package/tests/unit/scripts/use-module-adoption.test.js +74 -0
  59. package/tests/unit/scripts/use-module-integration.test.js +64 -0
  60. package/tests/unit/scripts/use-module.test.js +182 -0
  61. package/.husky/pre-commit +0 -1
  62. package/.prettierrc +0 -10
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
2
+ "$schema": "https://unpkg.com/@changesets/config@4.0.0/schema.json",
3
3
  "changelog": "@changesets/cli/changelog",
4
4
  "commit": false,
5
5
  "fixed": [],
@@ -0,0 +1,7 @@
1
+ ---
2
+ 'browser-commander': minor
3
+ ---
4
+
5
+ Restore the release pipeline. `const { $ } = await use('command-stream')` returned `undefined` on the Node 24 the release jobs pin, because Node 23 added a synthetic `'module.exports'` named export for CommonJS namespaces that use-m's unwrapping does not recognise, so every JS and Rust release died on its first shell call with `TypeError: $ is not a function`. Dependencies now load through `scripts/use-module.mjs`, which detects that namespace shape and unwraps it. Manifest fields are read by TOML table through `scripts/read-manifest.mjs` instead of a line-anchored `grep`, which matched duplicate keys in other tables and wrote two lines into `$GITHUB_OUTPUT`. The duplication gate had `format` set to a reporter name, so jscpd scanned zero files and passed unconditionally; it now scans the tree against a recorded baseline.
6
+
7
+ Add the `fingerprint` subsystem, which removes the differences between a browser this library controls and one started by hand. `navigator.webdriver` stays false because the `AutomationControlled` Blink feature is disabled at launch, and `launchBrowser()` no longer passes the engine defaults a real Chrome does not carry. `resolveFingerprintProfile()` validates the 19 environment fields a page can read -- user agent and client hints, languages and locale, time zone, platform, cores, memory, screen, viewport, touch, WebGL strings, geolocation and the media preferences -- `createFingerprintPreset()` builds internally consistent Windows, macOS, Linux and Android machines, and `applyFingerprint()` installs a profile over CDP for both Playwright and Puppeteer. `FINGERPRINT_LIMITATIONS` documents what still cannot be made identical, and `relevantFingerprintLimitations()` narrows it to the entries a given profile and browser actually hit. The excluded defaults include Playwright's unconditional `--enable-unsafe-swiftshader`, which would otherwise give an automated browser a SwiftShader WebGL context on a machine where a hand-started Chrome has none.
@@ -0,0 +1,257 @@
1
+ {
2
+ "version": 1,
3
+ "fingerprints": {
4
+ "00d381dd611ae8ac": 1,
5
+ "029a62ef1f48e856": 1,
6
+ "038170e72e0af1f5": 1,
7
+ "04b28d01d0bb47dc": 1,
8
+ "04f605be138bc350": 1,
9
+ "0796d358ad2562c3": 1,
10
+ "090a69d9528e4cdb": 1,
11
+ "09694dc8fb9d683c": 1,
12
+ "0a3459aad03492bb": 1,
13
+ "0b48b63049c42591": 1,
14
+ "0b8c71391c107a5e": 1,
15
+ "0ba2d165b56db0b3": 1,
16
+ "0c8a29320e45bdfa": 1,
17
+ "0ca2d9c2f2b44d6c": 1,
18
+ "0caa402c4eae32d8": 1,
19
+ "0fd23be8410c2c95": 1,
20
+ "0fe4f3b5e5e939b3": 1,
21
+ "10b6201c3ca1fbe0": 1,
22
+ "1273365073edd790": 1,
23
+ "1296adc3c3128048": 1,
24
+ "13c4b58d3ea0719b": 1,
25
+ "14beedf656e57fba": 1,
26
+ "150c8efe188ac225": 1,
27
+ "16340a16ed52849e": 1,
28
+ "17c26c0db2d35ad1": 1,
29
+ "193b46c0e7f72053": 1,
30
+ "1ac9fbd87efdb313": 1,
31
+ "1ad4dc7e19a77f68": 1,
32
+ "1c1baf1bc8ea0eae": 1,
33
+ "1d61f5c49f12d2dc": 1,
34
+ "1ef570563d4e5a08": 1,
35
+ "1f2104c950b12a30": 1,
36
+ "20bb8deee1481129": 1,
37
+ "21f9aab35441e4ff": 1,
38
+ "22755b35701c5bb6": 1,
39
+ "2296c06fa00da254": 1,
40
+ "229b903386b17538": 1,
41
+ "2357ae472525f6bf": 1,
42
+ "2394170c8a2a0e9a": 1,
43
+ "23d2486c0e269b77": 1,
44
+ "24b29d9d78441dbd": 1,
45
+ "266893ea7a511fe4": 1,
46
+ "266b9cb95f783cdf": 1,
47
+ "26bb09996580437c": 1,
48
+ "26ebb2e251c9a39e": 1,
49
+ "2a78ee4b05679c8d": 1,
50
+ "2b1a759e2cfd21a2": 1,
51
+ "2c0f8b5c6f28420b": 1,
52
+ "2d2d6fd6c7c0f30d": 1,
53
+ "2e70be24d2268673": 1,
54
+ "2f9e15467cc2f12a": 1,
55
+ "3101802d3ea65339": 1,
56
+ "33357ce94e07cc4b": 1,
57
+ "37bd4114d0089f49": 1,
58
+ "389df6fb4b8315a1": 1,
59
+ "39eaada6d1879f4a": 1,
60
+ "3a9f1672ecc1d55b": 1,
61
+ "3adca52a3f04837c": 1,
62
+ "3c1017def7b3216c": 1,
63
+ "3d7e17ad32108a7f": 1,
64
+ "3da23cbee214a1a5": 1,
65
+ "3dced48baf70eb36": 1,
66
+ "3fa2ebbb416120f0": 1,
67
+ "3fe61c0a7772f18b": 1,
68
+ "406fed8e5b39aafd": 1,
69
+ "40aa2953f783819c": 1,
70
+ "418db56376cc23bd": 1,
71
+ "441570d51d6f70a4": 1,
72
+ "457c71f32f53833d": 1,
73
+ "46e3f58cfb14a43a": 1,
74
+ "4b0d3cc5c27227e7": 1,
75
+ "4c3b94caa28045d0": 1,
76
+ "4f3c541b3f3e3f23": 1,
77
+ "4fe5663c69a426cb": 1,
78
+ "505d98bd14b63a6c": 1,
79
+ "5085765e1f103f3e": 1,
80
+ "5184c90c9f8406c3": 1,
81
+ "520a28ee2ced56c2": 1,
82
+ "53519ec61a6ba319": 1,
83
+ "53f7e3f3e444a37d": 1,
84
+ "5587ec0cdb7b96e6": 1,
85
+ "559b5241047cd753": 1,
86
+ "562ebfb882d4aa8f": 1,
87
+ "56b5df15ee61887d": 1,
88
+ "56b7675e4ce57335": 1,
89
+ "56d45d447baad2fd": 1,
90
+ "56deee57166c4369": 1,
91
+ "578ab1469dc998ec": 1,
92
+ "57c410b183671eec": 1,
93
+ "57e313e36a5ce81d": 1,
94
+ "58c08b8242c875ec": 1,
95
+ "58c1ca12d4d2b50f": 1,
96
+ "5a09e2677334ba05": 1,
97
+ "5ae9b1430fc38daf": 1,
98
+ "602bfd129bba900e": 1,
99
+ "608e1dd27138ec6f": 1,
100
+ "60d0c58a01fc8746": 1,
101
+ "61bcadcd8dc9f63e": 1,
102
+ "63a3b672c8d8b50b": 1,
103
+ "63ff613b1780c67a": 1,
104
+ "642cc89ed49f8a21": 1,
105
+ "6479c3604c153ec4": 1,
106
+ "66fb97eebd7ff0dc": 1,
107
+ "67a95e428b8fa31c": 1,
108
+ "6880d620e0e67229": 1,
109
+ "69d50e6f6a5f2ee9": 1,
110
+ "6a7ed9ad3fc00a39": 1,
111
+ "6af3c307939ef75e": 1,
112
+ "6cd00d6b6a039022": 1,
113
+ "6e2457cd3e1f69e7": 1,
114
+ "6fa62e2642cc73c3": 1,
115
+ "7009c5e9bd61dbe8": 1,
116
+ "709348ea44394b52": 1,
117
+ "731fbc5d4188839a": 1,
118
+ "73dbf56d17ab79ed": 1,
119
+ "760d9925f6e3ca85": 1,
120
+ "7623a3eea4680be4": 1,
121
+ "771db68809cce310": 1,
122
+ "771ddbb36a118cbb": 1,
123
+ "779517ed59b39aa6": 1,
124
+ "7850ccac58d09216": 1,
125
+ "785d557d0683185b": 1,
126
+ "785e57db939e1887": 1,
127
+ "786d7040e54017c7": 1,
128
+ "78c84b601cbc4ffe": 1,
129
+ "799dc9940577a15e": 1,
130
+ "79e705499ddaf44b": 1,
131
+ "7e6bad380644f9b0": 1,
132
+ "81a56c10bfd42e39": 1,
133
+ "837ba752ecdaf052": 1,
134
+ "8549c997a472cb6c": 1,
135
+ "86646647aab19e39": 1,
136
+ "8678919f1350f154": 1,
137
+ "86aae81b1aa0d21b": 1,
138
+ "87484a2744e09748": 1,
139
+ "87514cf1299c9c0e": 1,
140
+ "876d2c8edfc8c40a": 1,
141
+ "8b013ac20e436d76": 1,
142
+ "8c2b1408886c1db1": 1,
143
+ "8cb9a984bf19a062": 1,
144
+ "8ec18cdbd4a96518": 1,
145
+ "8ecf2e554a04d2ef": 1,
146
+ "91049efadc65169b": 1,
147
+ "9134185980de8a17": 1,
148
+ "916833bafca4fa63": 1,
149
+ "91a538e4a0c28f25": 1,
150
+ "929fba5228e9fdac": 1,
151
+ "92ddafa7e65be7eb": 1,
152
+ "94821a4d1b745dfd": 1,
153
+ "94d89888ac9da9a9": 1,
154
+ "97c5a112fdde7be8": 1,
155
+ "98cc22079feaa004": 1,
156
+ "990d87f21678fa96": 1,
157
+ "9b6ef4df04562546": 1,
158
+ "9c055dfd90c369bf": 1,
159
+ "9cb19f1b972e811e": 1,
160
+ "9ee57dcd5e7a6691": 1,
161
+ "9fbb8296259dedbe": 1,
162
+ "a0183465782b0b15": 1,
163
+ "a1e3a3a13b27dba4": 1,
164
+ "a1ef39a15701c2b5": 1,
165
+ "a2a00d268fb2cee4": 1,
166
+ "a305c6cac16f3af5": 1,
167
+ "a4c8498d4f2d2191": 1,
168
+ "a6ad7ab6c05656dc": 1,
169
+ "a78d76908162699e": 1,
170
+ "a9bd4ffef6da5faf": 1,
171
+ "a9d71c2e50f1b832": 1,
172
+ "abe5a58f2b2cc593": 1,
173
+ "acc95d694eb2f581": 1,
174
+ "ad4469f2e8131535": 1,
175
+ "ad4cfa76daa1b6fc": 1,
176
+ "adae1329361a81a1": 1,
177
+ "ae477ba64bafba3f": 1,
178
+ "aee1e5c65f783848": 1,
179
+ "aee45e8b58c2d87f": 1,
180
+ "af9d6a2f4eba146e": 1,
181
+ "b010686af23efa90": 1,
182
+ "b2a0686231220c8a": 1,
183
+ "b35ff46c365dcd18": 1,
184
+ "b41581af204af40e": 1,
185
+ "b62f3449cde7991d": 1,
186
+ "b71fa5250da28739": 1,
187
+ "b740ecac685a15fe": 1,
188
+ "b8c2d21f2a26f77d": 1,
189
+ "bb269582b94ed42d": 1,
190
+ "bb3e6d0f7e7edccd": 1,
191
+ "bccf0d5cc57c08df": 1,
192
+ "bd0ae42c13d5b4f9": 1,
193
+ "bd6c62a6e1c6a071": 1,
194
+ "bdb8ca169be36b80": 1,
195
+ "bdcd11c2bfb5fde0": 1,
196
+ "be0900fb3e87164e": 1,
197
+ "bf452b9431c092ad": 1,
198
+ "c0b027bebd7bd737": 1,
199
+ "c2c155adbcb46f3c": 1,
200
+ "c30737d62069fc02": 1,
201
+ "c3c3569357673af8": 1,
202
+ "c415ffcd004d6518": 1,
203
+ "c461a83b51eb7740": 1,
204
+ "c9cf3c28bed33a5b": 1,
205
+ "cbd444e9a6a9072e": 1,
206
+ "cc60029bf62920a3": 1,
207
+ "cd49f39b43d14635": 1,
208
+ "cebff7d1cc87f646": 1,
209
+ "cf6116d195199f8a": 1,
210
+ "cfd68135b744c27b": 1,
211
+ "d097f41a6f43e634": 1,
212
+ "d17201496391f6cc": 1,
213
+ "d17e8db5a2bab966": 1,
214
+ "d1a4a8e6a523b752": 1,
215
+ "d2ed3d02dd6a2d8c": 1,
216
+ "d4eec99f58906a63": 1,
217
+ "d6157a86fea41907": 1,
218
+ "d6fa9884eee815f0": 1,
219
+ "d86bafb915488255": 1,
220
+ "de0bf2317c53d427": 1,
221
+ "de1b481bfe8c3e58": 1,
222
+ "df2dc922f40485e7": 1,
223
+ "df3b85f6947db144": 1,
224
+ "e0b90bce5112bb9c": 1,
225
+ "e2ef7800deb0f464": 1,
226
+ "e3111b845acb7a0e": 1,
227
+ "e4b10b56d7e1edac": 1,
228
+ "e59733bafda785e9": 1,
229
+ "e5feedc0c24e103e": 1,
230
+ "e67726a913675120": 1,
231
+ "ea1195048ded896c": 1,
232
+ "ea88711c5deb1fe5": 1,
233
+ "eb9a70c2a21094ff": 1,
234
+ "ebd08637a2d7bcf3": 1,
235
+ "ebe03c5f8c2f5147": 1,
236
+ "edccf5a595ab439f": 1,
237
+ "ee19c8b9b332ee98": 1,
238
+ "eeca0ccf8d821f21": 1,
239
+ "ef2fc2e92ac07c6e": 1,
240
+ "f022b763ff342b2d": 1,
241
+ "f07f979f8c2706e8": 1,
242
+ "f38f72095a67c95e": 1,
243
+ "f40ba84763547f41": 1,
244
+ "f46509ed693574df": 1,
245
+ "f4bb6f4c83950fcd": 1,
246
+ "f4bfa7e503443cd1": 1,
247
+ "f67a07a611f39cb2": 1,
248
+ "f911821aa7dda47f": 1,
249
+ "f97bf515bfd95829": 1,
250
+ "fae844842fba705b": 1,
251
+ "faf76ec43b2dbbaa": 1,
252
+ "fb3a2e9ace145907": 1,
253
+ "fc6ed7d760c98f51": 1,
254
+ "fccfd8b004c12dd4": 1,
255
+ "fe859df9f97c75d4": 1
256
+ }
257
+ }
package/.jscpd.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
- "threshold": 0,
3
2
  "minTokens": 30,
4
3
  "minLines": 5,
5
- "skipComments": true,
4
+ "mode": "weak",
6
5
  "ignore": [
7
6
  "**/node_modules/**",
8
7
  "**/build/**",
@@ -14,7 +13,6 @@
14
13
  "**/pnpm-lock.yaml",
15
14
  "**/yarn.lock"
16
15
  ],
17
- "format": "console",
18
16
  "reporters": ["console", "html"],
19
17
  "output": "./reports/jscpd"
20
18
  }
package/.prettierignore CHANGED
@@ -6,3 +6,4 @@ docs-api
6
6
  package-lock.json
7
7
  .eslintcache
8
8
  CLAUDE.md
9
+ reports
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Restore the release pipeline. `const { $ } = await use('command-stream')` returned `undefined` on the Node 24 the release jobs pin, because Node 23 added a synthetic `'module.exports'` named export for CommonJS namespaces that use-m's unwrapping does not recognise, so every JS and Rust release died on its first shell call with `TypeError: $ is not a function`. Dependencies now load through `scripts/use-module.mjs`, which detects that namespace shape and unwraps it. Manifest fields are read by TOML table through `scripts/read-manifest.mjs` instead of a line-anchored `grep`, which matched duplicate keys in other tables and wrote two lines into `$GITHUB_OUTPUT`. The duplication gate had `format` set to a reporter name, so jscpd scanned zero files and passed unconditionally; it now scans the tree against a recorded baseline.
8
+
9
+ Add the `fingerprint` subsystem, which removes the differences between a browser this library controls and one started by hand. `navigator.webdriver` stays false because the `AutomationControlled` Blink feature is disabled at launch, and `launchBrowser()` no longer passes the engine defaults a real Chrome does not carry. `resolveFingerprintProfile()` validates the 19 environment fields a page can read -- user agent and client hints, languages and locale, time zone, platform, cores, memory, screen, viewport, touch, WebGL strings, geolocation and the media preferences -- `createFingerprintPreset()` builds internally consistent Windows, macOS, Linux and Android machines, and `applyFingerprint()` installs a profile over CDP for both Playwright and Puppeteer. `FINGERPRINT_LIMITATIONS` documents what still cannot be made identical, and `relevantFingerprintLimitations()` narrows it to the entries a given profile and browser actually hit. The excluded defaults include Playwright's unconditional `--enable-unsafe-swiftshader`, which would otherwise give an automated browser a SwiftShader WebGL context on a machine where a hand-started Chrome has none.
10
+
11
+ ## 0.16.1
12
+
13
+ ### Patch Changes
14
+
15
+ - 542bf75: Fix CI/CD false positives, false negatives and warnings across all workflows
16
+ - Repair `if:` conditions that started with `!`, which a YAML plain scalar cannot do
17
+ - Replace `always()` with `!cancelled()` so cancelled runs stop propagating
18
+ - Gate `instant-release` and `changeset-pr` on lint and test, so a manual release can no longer publish unvalidated code
19
+ - Make the changelog fragment checks fail instead of only warning
20
+ - Pass `github.base_ref` and free-form `workflow_dispatch` inputs through environment variables instead of interpolating them into shell bodies
21
+ - Update `actions/setup-python` to v6, `codecov/codecov-action` to v7 and `peter-evans/create-pull-request` to v8
22
+ - Extend `scripts/check-ci-workflows.mjs` so each of the above becomes a permanent policy check
23
+ - Add repository-wide secrets scanning and a 1500-line file limit gate
24
+
3
25
  ## 0.16.0
4
26
 
5
27
  ### Minor Changes
package/eslint.config.js CHANGED
@@ -45,9 +45,22 @@ export default [
45
45
  Bun: 'readonly',
46
46
  Deno: 'readonly',
47
47
  globalThis: 'readonly',
48
- // Browser globals (used in evaluate functions)
48
+ // Browser globals (used in evaluate functions and in the page
49
+ // scripts under experiments/fingerprint-parity/, which are shipped to
50
+ // Chrome verbatim rather than executed by Node).
49
51
  document: 'readonly',
50
52
  window: 'readonly',
53
+ navigator: 'readonly',
54
+ Navigator: 'readonly',
55
+ screen: 'readonly',
56
+ Screen: 'readonly',
57
+ Notification: 'readonly',
58
+ speechSynthesis: 'readonly',
59
+ HTMLCanvasElement: 'readonly',
60
+ CanvasRenderingContext2D: 'readonly',
61
+ WebGLRenderingContext: 'readonly',
62
+ Blob: 'readonly',
63
+ Worker: 'readonly',
51
64
  },
52
65
  },
53
66
  rules: {
@@ -104,6 +117,15 @@ export default [
104
117
  'max-lines': ['error', 1500], // Maximum lines per file - counts all lines including blank lines and comments
105
118
  },
106
119
  },
120
+ {
121
+ // The shared init payload is source text, not a module: it is read verbatim
122
+ // and sent to the page, so the declaration it exports to the page has no
123
+ // caller inside this package. See scripts/check-shared-fingerprint-assets.sh.
124
+ files: ['src/fingerprint/init-payload.js'],
125
+ rules: {
126
+ 'no-unused-vars': 'off',
127
+ },
128
+ },
107
129
  {
108
130
  // Test files have different requirements
109
131
  files: ['tests/**/*.js', '**/*.test.js'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-commander",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Universal browser automation library that supports both Playwright and Puppeteer with a unified API",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -15,19 +15,20 @@
15
15
  "test:e2e": "node scripts/run-tests.mjs --env RUN_E2E=true tests/e2e",
16
16
  "test:e2e:playwright": "node scripts/run-tests.mjs --env RUN_E2E=true tests/e2e/playwright.e2e.test.js",
17
17
  "test:e2e:puppeteer": "node scripts/run-tests.mjs --env RUN_E2E=true tests/e2e/puppeteer.e2e.test.js",
18
+ "test:e2e:parity": "node scripts/run-tests.mjs --env RUN_E2E=true tests/e2e/fingerprint-parity.e2e.test.js",
18
19
  "test:all": "npm run test:unit && npm run test:e2e",
19
20
  "lint": "eslint .",
20
21
  "lint:fix": "eslint . --fix",
21
22
  "format": "prettier --write .",
22
23
  "format:check": "prettier --check .",
23
24
  "docs:api": "jsdoc -c jsdoc.json",
24
- "check:duplication": "jscpd .",
25
+ "check:duplication": "jscpd . --baseline .jscpd-baseline.json --fail-on-new-clones",
25
26
  "check": "npm run lint && npm run format:check && npm run check:duplication",
26
- "prepare": "husky || true",
27
27
  "changeset": "changeset",
28
28
  "changeset:version": "node scripts/changeset-version.mjs",
29
29
  "changeset:publish": "changeset publish",
30
- "changeset:status": "changeset status --since=origin/main"
30
+ "changeset:status": "changeset status --since=origin/main",
31
+ "check:duplication:update": "jscpd . --baseline .jscpd-baseline.json --update-baseline"
31
32
  },
32
33
  "repository": {
33
34
  "type": "git",
@@ -68,27 +69,15 @@
68
69
  "test-anywhere": "^0.9.1"
69
70
  },
70
71
  "devDependencies": {
71
- "@changesets/cli": "^2.29.7",
72
- "eslint": "^9.39.0",
72
+ "@changesets/cli": "^3.0.2",
73
+ "@eslint/js": "^10.0.1",
74
+ "eslint": "^10.10.0",
73
75
  "eslint-config-prettier": "^10.1.8",
74
- "eslint-plugin-prettier": "^5.5.4",
75
- "husky": "^9.1.7",
76
- "jscpd": "^4.0.5",
76
+ "eslint-plugin-prettier": "^5.5.6",
77
+ "jscpd": "^5.1.2",
77
78
  "jsdoc": "^4.0.4",
78
- "lint-staged": "^16.2.6",
79
- "playwright": "^1.56.1",
80
- "prettier": "^3.6.2",
81
- "puppeteer": "^24.27.0"
82
- },
83
- "lint-staged": {
84
- "*.{js,mjs,cjs}": [
85
- "eslint --fix",
86
- "prettier --write",
87
- "prettier --check"
88
- ],
89
- "*.md": [
90
- "prettier --write",
91
- "prettier --check"
92
- ]
79
+ "playwright": "^1.62.1",
80
+ "prettier": "^3.9.6",
81
+ "puppeteer": "^25.10.0"
93
82
  }
94
83
  }
@@ -13,13 +13,9 @@
13
13
  * - command-stream: Modern shell command execution with streaming support
14
14
  */
15
15
 
16
- // Load use-m dynamically
17
- const { use } = eval(
18
- await (await fetch('https://unpkg.com/use-m/use.js')).text()
19
- );
16
+ import { loadCommandStream } from '../../scripts/use-module.mjs';
20
17
 
21
- // Import command-stream for shell command execution
22
- const { $ } = await use('command-stream');
18
+ const { $ } = await loadCommandStream();
23
19
 
24
20
  try {
25
21
  console.log('Running changeset version...');
@@ -14,14 +14,13 @@
14
14
 
15
15
  import { readFileSync } from 'fs';
16
16
 
17
- // Load use-m dynamically
18
- const { use } = eval(
19
- await (await fetch('https://unpkg.com/use-m/use.js')).text()
20
- );
21
-
22
- // Import link-foundation libraries
23
- const { $ } = await use('command-stream');
24
- const { makeConfig } = await use('lino-arguments');
17
+ import {
18
+ loadCommandStream,
19
+ loadLinoArguments,
20
+ } from '../../scripts/use-module.mjs';
21
+
22
+ const { $ } = await loadCommandStream();
23
+ const { makeConfig } = await loadLinoArguments();
25
24
 
26
25
  // Parse CLI arguments using lino-arguments
27
26
  // Note: Using --release-version instead of --version to avoid conflict with yargs' built-in --version flag
@@ -15,14 +15,13 @@ import { randomBytes } from 'crypto';
15
15
 
16
16
  const PACKAGE_NAME = 'browser-commander';
17
17
 
18
- // Load use-m dynamically
19
- const { use } = eval(
20
- await (await fetch('https://unpkg.com/use-m/use.js')).text()
21
- );
22
-
23
- // Import link-foundation libraries
24
- const { $ } = await use('command-stream');
25
- const { makeConfig } = await use('lino-arguments');
18
+ import {
19
+ loadCommandStream,
20
+ loadLinoArguments,
21
+ } from '../../scripts/use-module.mjs';
22
+
23
+ const { $ } = await loadCommandStream();
24
+ const { makeConfig } = await loadLinoArguments();
26
25
 
27
26
  // Parse CLI arguments using lino-arguments
28
27
  const config = makeConfig({
@@ -13,14 +13,13 @@
13
13
  * - lino-arguments: Unified configuration from CLI args, env vars, and .lenv files
14
14
  */
15
15
 
16
- // Load use-m dynamically
17
- const { use } = eval(
18
- await (await fetch('https://unpkg.com/use-m/use.js')).text()
19
- );
16
+ import {
17
+ loadCommandStream,
18
+ loadLinoArguments,
19
+ } from '../../scripts/use-module.mjs';
20
20
 
21
- // Import link-foundation libraries
22
- const { $ } = await use('command-stream');
23
- const { makeConfig } = await use('lino-arguments');
21
+ const { $ } = await loadCommandStream();
22
+ const { makeConfig } = await loadLinoArguments();
24
23
 
25
24
  // Parse CLI arguments using lino-arguments
26
25
  // Note: Using --release-version instead of --version to avoid conflict with yargs' built-in --version flag
@@ -23,14 +23,13 @@
23
23
 
24
24
  const PACKAGE_NAME = 'browser-commander';
25
25
 
26
- // Load use-m dynamically
27
- const { use } = eval(
28
- await (await fetch('https://unpkg.com/use-m/use.js')).text()
29
- );
30
-
31
- // Import link-foundation libraries
32
- const { $ } = await use('command-stream');
33
- const { makeConfig } = await use('lino-arguments');
26
+ import {
27
+ loadCommandStream,
28
+ loadLinoArguments,
29
+ } from '../../scripts/use-module.mjs';
30
+
31
+ const { $ } = await loadCommandStream();
32
+ const { makeConfig } = await loadLinoArguments();
34
33
 
35
34
  // Parse CLI arguments using lino-arguments
36
35
  // Note: Using --release-version instead of --version to avoid conflict with yargs' built-in --version flag
@@ -14,14 +14,13 @@
14
14
 
15
15
  import { readFileSync, writeFileSync } from 'fs';
16
16
 
17
- // Load use-m dynamically
18
- const { use } = eval(
19
- await (await fetch('https://unpkg.com/use-m/use.js')).text()
20
- );
21
-
22
- // Import link-foundation libraries
23
- const { $ } = await use('command-stream');
24
- const { makeConfig } = await use('lino-arguments');
17
+ import {
18
+ loadCommandStream,
19
+ loadLinoArguments,
20
+ } from '../../scripts/use-module.mjs';
21
+
22
+ const { $ } = await loadCommandStream();
23
+ const { makeConfig } = await loadLinoArguments();
25
24
 
26
25
  // Parse CLI arguments using lino-arguments
27
26
  const config = makeConfig({
@@ -17,14 +17,13 @@ import { isVersionPublished } from './npm-registry.mjs';
17
17
 
18
18
  const PACKAGE_NAME = 'browser-commander';
19
19
 
20
- // Load use-m dynamically
21
- const { use } = eval(
22
- await (await fetch('https://unpkg.com/use-m/use.js')).text()
23
- );
24
-
25
- // Import link-foundation libraries
26
- const { $ } = await use('command-stream');
27
- const { makeConfig } = await use('lino-arguments');
20
+ import {
21
+ loadCommandStream,
22
+ loadLinoArguments,
23
+ } from '../../scripts/use-module.mjs';
24
+
25
+ const { $ } = await loadCommandStream();
26
+ const { makeConfig } = await loadLinoArguments();
28
27
 
29
28
  // Parse CLI arguments using lino-arguments
30
29
  const config = makeConfig({
@@ -10,13 +10,9 @@
10
10
  * - command-stream: Modern shell command execution with streaming support
11
11
  */
12
12
 
13
- // Load use-m dynamically
14
- const { use } = eval(
15
- await (await fetch('https://unpkg.com/use-m/use.js')).text()
16
- );
13
+ import { loadCommandStream } from '../../scripts/use-module.mjs';
17
14
 
18
- // Import command-stream for shell command execution
19
- const { $ } = await use('command-stream');
15
+ const { $ } = await loadCommandStream();
20
16
 
21
17
  try {
22
18
  // Get current npm version
@@ -14,14 +14,13 @@
14
14
 
15
15
  import { readFileSync, appendFileSync, readdirSync } from 'fs';
16
16
 
17
- // Load use-m dynamically
18
- const { use } = eval(
19
- await (await fetch('https://unpkg.com/use-m/use.js')).text()
20
- );
21
-
22
- // Import link-foundation libraries
23
- const { $ } = await use('command-stream');
24
- const { makeConfig } = await use('lino-arguments');
17
+ import {
18
+ loadCommandStream,
19
+ loadLinoArguments,
20
+ } from '../../scripts/use-module.mjs';
21
+
22
+ const { $ } = await loadCommandStream();
23
+ const { makeConfig } = await loadLinoArguments();
25
24
 
26
25
  // Parse CLI arguments using lino-arguments
27
26
  const config = makeConfig({
@@ -134,7 +134,9 @@ export async function readWindowsEncryptionKey({
134
134
  try {
135
135
  state = JSON.parse(await readFile(localStatePath, 'utf8'));
136
136
  } catch (error) {
137
- throw new Error(`Could not read Chromium Local State: ${error.message}`);
137
+ throw new Error(`Could not read Chromium Local State: ${error.message}`, {
138
+ cause: error,
139
+ });
138
140
  }
139
141
  const encoded = state.os_crypt?.encrypted_key;
140
142
  if (!encoded) {