codeceptjs 4.0.1-beta.17 → 4.0.1-beta.19

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.
@@ -30,7 +30,7 @@ import ElementNotFound from './errors/ElementNotFound.js'
30
30
  import RemoteBrowserConnectionRefused from './errors/RemoteBrowserConnectionRefused.js'
31
31
  import Popup from './extras/Popup.js'
32
32
  import Console from './extras/Console.js'
33
- import { findReact, findVue, findByPlaywrightLocator } from './extras/PlaywrightReactVueLocator.js'
33
+ import { findReact, findVue } from './extras/PlaywrightLocator.js'
34
34
  import WebElement from '../element/WebElement.js'
35
35
 
36
36
  let playwright
@@ -2489,7 +2489,19 @@ class Playwright extends Helper {
2489
2489
  * {{> selectOption }}
2490
2490
  */
2491
2491
  async selectOption(select, option) {
2492
- const els = await findFields.call(this, select)
2492
+ const selectLocator = Locator.from(select, 'css')
2493
+ let els = null
2494
+
2495
+ if (selectLocator.isFuzzy()) {
2496
+ els = await findByRole(this.page, { role: 'listbox', name: selectLocator.value })
2497
+ if (!els || els.length === 0) {
2498
+ els = await findByRole(this.page, { role: 'combobox', name: selectLocator.value })
2499
+ }
2500
+ }
2501
+
2502
+ if (!els || els.length === 0) {
2503
+ els = await findFields.call(this, select)
2504
+ }
2493
2505
  assertElementExists(els, select, 'Selectable field')
2494
2506
  const el = els[0]
2495
2507
 
@@ -2790,17 +2802,6 @@ class Playwright extends Helper {
2790
2802
  *
2791
2803
  */
2792
2804
  async grabTextFrom(locator) {
2793
- // Handle role locators with text/exact options
2794
- if (isRoleLocatorObject(locator)) {
2795
- const elements = await handleRoleLocator(this.page, locator)
2796
- if (elements && elements.length > 0) {
2797
- const text = await elements[0].textContent()
2798
- assertElementExists(text, JSON.stringify(locator))
2799
- this.debugSection('Text', text)
2800
- return text
2801
- }
2802
- }
2803
-
2804
2805
  const locatorObj = new Locator(locator, 'css')
2805
2806
 
2806
2807
  if (locatorObj.isCustom()) {
@@ -2813,21 +2814,32 @@ class Playwright extends Helper {
2813
2814
  assertElementExists(text, locatorObj.toString())
2814
2815
  this.debugSection('Text', text)
2815
2816
  return text
2816
- } else {
2817
- locator = this._contextLocator(locator)
2818
- try {
2819
- const text = await this.page.textContent(locator)
2820
- assertElementExists(text, locator)
2817
+ }
2818
+
2819
+ if (locatorObj.isRole()) {
2820
+ // Handle role locators with text/exact options
2821
+ const roleElements = await findByRole(this.page, locator)
2822
+ if (roleElements && roleElements.length > 0) {
2823
+ const text = await roleElements[0].textContent()
2824
+ assertElementExists(text, JSON.stringify(locator))
2821
2825
  this.debugSection('Text', text)
2822
2826
  return text
2823
- } catch (error) {
2824
- // Convert Playwright timeout errors to ElementNotFound for consistency
2825
- if (error.message && error.message.includes('Timeout')) {
2826
- throw new ElementNotFound(locator, 'text')
2827
- }
2828
- throw error
2829
2827
  }
2830
2828
  }
2829
+
2830
+ locator = this._contextLocator(locator)
2831
+ try {
2832
+ const text = await this.page.textContent(locator)
2833
+ assertElementExists(text, locator)
2834
+ this.debugSection('Text', text)
2835
+ return text
2836
+ } catch (error) {
2837
+ // Convert Playwright timeout errors to ElementNotFound for consistency
2838
+ if (error.message && error.message.includes('Timeout')) {
2839
+ throw new ElementNotFound(locator, 'text')
2840
+ }
2841
+ throw error
2842
+ }
2831
2843
  }
2832
2844
 
2833
2845
  /**
@@ -4306,50 +4318,26 @@ function buildLocatorString(locator) {
4306
4318
  if (locator.isXPath()) {
4307
4319
  return `xpath=${locator.value}`
4308
4320
  }
4309
- return locator.simplify()
4321
+ return locator.simplify()
4310
4322
  }
4311
4323
 
4312
- /**
4313
- * Checks if a locator is a role locator object (e.g., {role: 'button', text: 'Submit', exact: true})
4314
- */
4315
- function isRoleLocatorObject(locator) {
4316
- return locator && typeof locator === 'object' && locator.role && !locator.type
4317
- }
4318
-
4319
- /**
4320
- * Handles role locator objects by converting them to Playwright's getByRole() API
4321
- * Returns elements array if role locator, null otherwise
4322
- */
4323
- async function handleRoleLocator(context, locator) {
4324
- if (!isRoleLocatorObject(locator)) return null
4325
-
4326
- const options = {}
4327
- if (locator.text) options.name = locator.text
4328
- if (locator.exact !== undefined) options.exact = locator.exact
4329
-
4330
- return context.getByRole(locator.role, Object.keys(options).length > 0 ? options : undefined).all()
4324
+ async function findByRole(context, locator) {
4325
+ const matchedLocator = Locator.from(locator)
4326
+ if (!matchedLocator.isRole()) return null
4327
+ const roleOptions = matchedLocator.getRoleOptions()
4328
+ return context.getByRole(roleOptions.role, roleOptions.options).all()
4331
4329
  }
4332
4330
 
4333
4331
  async function findElements(matcher, locator) {
4334
- // Check if locator is a Locator object with react/vue type, or a raw object with react/vue property
4335
- const isReactLocator = locator.type === 'react' || (locator.locator && locator.locator.react) || locator.react
4336
- const isVueLocator = locator.type === 'vue' || (locator.locator && locator.locator.vue) || locator.vue
4337
- const isPwLocator = locator.type === 'pw' || (locator.locator && locator.locator.pw) || locator.pw
4338
-
4339
- if (isReactLocator) return findReact(matcher, locator)
4340
- if (isVueLocator) return findVue(matcher, locator)
4341
- if (isPwLocator) return findByPlaywrightLocator.call(this, matcher, locator)
4342
-
4343
- // Handle role locators with text/exact options (e.g., {role: 'button', text: 'Submit', exact: true})
4344
- const roleElements = await handleRoleLocator(matcher, locator)
4332
+ const matchedLocator = Locator.from(locator)
4333
+ const roleElements = await findByRole(matcher, matchedLocator)
4345
4334
  if (roleElements) return roleElements
4346
4335
 
4347
- locator = new Locator(locator, 'css')
4336
+ const isReactLocator = matchedLocator.type === 'react'
4337
+ const isVueLocator = matchedLocator.type === 'vue'
4348
4338
 
4349
- // Handle custom locators directly instead of relying on Playwright selector engines
4350
- if (locator.isCustom()) {
4351
- return findCustomElements.call(this, matcher, locator)
4352
- }
4339
+ if (isReactLocator) return findReact(matcher, matchedLocator)
4340
+ if (isVueLocator) return findVue(matcher, matchedLocator)
4353
4341
 
4354
4342
  // Check if we have a custom context locator and need to search within it
4355
4343
  if (this.contextLocator) {
@@ -4362,12 +4350,12 @@ async function findElements(matcher, locator) {
4362
4350
  }
4363
4351
 
4364
4352
  // Search within the first context element
4365
- const locatorString = buildLocatorString(locator)
4353
+ const locatorString = buildLocatorString(matchedLocator)
4366
4354
  return contextElements[0].locator(locatorString).all()
4367
4355
  }
4368
4356
  }
4369
4357
 
4370
- const locatorString = buildLocatorString(locator)
4358
+ const locatorString = buildLocatorString(matchedLocator)
4371
4359
 
4372
4360
  return matcher.locator(locatorString).all()
4373
4361
  }
@@ -4460,13 +4448,17 @@ async function findCustomElements(matcher, locator) {
4460
4448
  }
4461
4449
 
4462
4450
  async function findElement(matcher, locator) {
4463
- if (locator.react) return findReact(matcher, locator)
4464
- if (locator.vue) return findVue(matcher, locator)
4465
- if (locator.pw) return findByPlaywrightLocator.call(this, matcher, locator)
4451
+ const matchedLocator = Locator.from(locator)
4452
+ const roleElements = await findByRole(matcher, matchedLocator)
4453
+ if (roleElements && roleElements.length > 0) return roleElements[0]
4454
+
4455
+ const isReactLocator = matchedLocator.type === 'react'
4456
+ const isVueLocator = matchedLocator.type === 'vue'
4466
4457
 
4467
- locator = new Locator(locator, 'css')
4458
+ if (isReactLocator) return findReact(matcher, matchedLocator)
4459
+ if (isVueLocator) return findVue(matcher, matchedLocator)
4468
4460
 
4469
- return matcher.locator(buildLocatorString(locator)).first()
4461
+ return matcher.locator(buildLocatorString(matchedLocator)).first()
4470
4462
  }
4471
4463
 
4472
4464
  async function getVisibleElements(elements) {
@@ -4518,8 +4510,14 @@ async function proceedClick(locator, context = null, options = {}) {
4518
4510
  }
4519
4511
 
4520
4512
  async function findClickable(matcher, locator) {
4513
+ // Convert to Locator first to handle JSON strings properly
4521
4514
  const matchedLocator = new Locator(locator)
4522
4515
 
4516
+ // Handle role locators from Locator
4517
+ if (matchedLocator.isRole()) {
4518
+ return findByRole(matcher, matchedLocator)
4519
+ }
4520
+
4523
4521
  if (!matchedLocator.isFuzzy()) return findElements.call(this, matcher, matchedLocator)
4524
4522
 
4525
4523
  let els
@@ -4592,14 +4590,17 @@ async function findCheckable(locator, context) {
4592
4590
  }
4593
4591
 
4594
4592
  // Handle role locators with text/exact options
4595
- const roleElements = await handleRoleLocator(contextEl, locator)
4593
+ const roleElements = await findByRole(contextEl, locator)
4596
4594
  if (roleElements) return roleElements
4597
4595
 
4598
- const matchedLocator = new Locator(locator)
4596
+ const matchedLocator = Locator.from(locator)
4599
4597
  if (!matchedLocator.isFuzzy()) {
4600
4598
  return findElements.call(this, contextEl, matchedLocator)
4601
4599
  }
4602
4600
 
4601
+ const checkboxByRole = await findByRole(contextEl, { role: 'checkbox', name: matchedLocator.value })
4602
+ if (checkboxByRole) return checkboxByRole
4603
+
4603
4604
  const literal = xpathLocator.literal(matchedLocator.value)
4604
4605
  let els = await findElements.call(this, contextEl, Locator.checkable.byText(literal))
4605
4606
  if (els.length) {
@@ -4621,17 +4622,15 @@ async function proceedIsChecked(assertType, option) {
4621
4622
  }
4622
4623
 
4623
4624
  async function findFields(locator) {
4624
- // Handle role locators with text/exact options
4625
- if (isRoleLocatorObject(locator)) {
4626
- const page = await this.page
4627
- const roleElements = await handleRoleLocator(page, locator)
4628
- if (roleElements) return roleElements
4629
- }
4625
+ const page = await this.page
4626
+ const roleElements = await findByRole(page, locator)
4627
+ if (roleElements) return roleElements
4630
4628
 
4631
4629
  const matchedLocator = new Locator(locator)
4632
4630
  if (!matchedLocator.isFuzzy()) {
4633
4631
  return this._locate(matchedLocator)
4634
4632
  }
4633
+
4635
4634
  const literal = xpathLocator.literal(locator)
4636
4635
 
4637
4636
  let els = await this._locate({ xpath: Locator.field.labelEquals(literal) })
@@ -11,22 +11,20 @@ function buildLocatorString(locator) {
11
11
  }
12
12
 
13
13
  async function findElements(matcher, locator) {
14
- const matchedLocator = new Locator(locator, 'css')
14
+ const matchedLocator = Locator.from(locator, 'css')
15
15
 
16
16
  if (matchedLocator.type === 'react') return findReact(matcher, matchedLocator)
17
17
  if (matchedLocator.type === 'vue') return findVue(matcher, matchedLocator)
18
- if (matchedLocator.type === 'pw') return findByPlaywrightLocator(matcher, matchedLocator)
19
18
  if (matchedLocator.isRole()) return findByRole(matcher, matchedLocator)
20
19
 
21
20
  return matcher.locator(buildLocatorString(matchedLocator)).all()
22
21
  }
23
22
 
24
23
  async function findElement(matcher, locator) {
25
- const matchedLocator = new Locator(locator, 'css')
24
+ const matchedLocator = Locator.from(locator, 'css')
26
25
 
27
26
  if (matchedLocator.type === 'react') return findReact(matcher, matchedLocator)
28
27
  if (matchedLocator.type === 'vue') return findVue(matcher, matchedLocator)
29
- if (matchedLocator.type === 'pw') return findByPlaywrightLocator(matcher, matchedLocator, { first: true })
30
28
  if (matchedLocator.isRole()) return findByRole(matcher, matchedLocator, { first: true })
31
29
 
32
30
  return matcher.locator(buildLocatorString(matchedLocator)).first()
@@ -46,49 +44,30 @@ async function getVisibleElements(elements) {
46
44
  }
47
45
 
48
46
  async function findReact(matcher, locator) {
49
- const details = locator.locator ?? { react: locator.value }
50
- let locatorString = `_react=${details.react}`
47
+ const props = locator.locator?.props
48
+ let locatorString = `_react=${locator.value}`
51
49
 
52
- if (details.props) {
53
- locatorString += propBuilder(details.props)
50
+ if (props) {
51
+ locatorString += propBuilder(props)
54
52
  }
55
53
 
56
54
  return matcher.locator(locatorString).all()
57
55
  }
58
56
 
59
57
  async function findVue(matcher, locator) {
60
- const details = locator.locator ?? { vue: locator.value }
61
- let locatorString = `_vue=${details.vue}`
58
+ const props = locator.locator?.props
59
+ let locatorString = `_vue=${locator.value}`
62
60
 
63
- if (details.props) {
64
- locatorString += propBuilder(details.props)
61
+ if (props) {
62
+ locatorString += propBuilder(props)
65
63
  }
66
64
 
67
65
  return matcher.locator(locatorString).all()
68
66
  }
69
67
 
70
- async function findByPlaywrightLocator(matcher, locator, { first = false } = {}) {
71
- const details = locator.locator ?? { pw: locator.value }
72
- const locatorValue = details.pw
73
-
74
- const handle = matcher.locator(locatorValue)
75
- return first ? handle.first() : handle.all()
76
- }
77
-
78
68
  async function findByRole(matcher, locator, { first = false } = {}) {
79
- const details = locator.locator ?? { role: locator.value }
80
- const { role, text, name, exact, includeHidden, ...rest } = details
81
- const options = { ...rest }
82
-
83
- if (includeHidden !== undefined) options.includeHidden = includeHidden
84
-
85
- const accessibleName = name ?? text
86
- if (accessibleName !== undefined) {
87
- options.name = accessibleName
88
- if (exact === true) options.exact = true
89
- }
90
-
91
- const roleLocator = matcher.getByRole(role, options)
69
+ const roleOptions = locator.getRoleOptions()
70
+ const roleLocator = matcher.getByRole(roleOptions.role, roleOptions.options)
92
71
  return first ? roleLocator.first() : roleLocator.all()
93
72
  }
94
73
 
@@ -107,4 +86,4 @@ function propBuilder(props) {
107
86
  return _props
108
87
  }
109
88
 
110
- export { buildLocatorString, findElements, findElement, getVisibleElements, findReact, findVue, findByPlaywrightLocator, findByRole }
89
+ export { buildLocatorString, findElements, findElement, getVisibleElements, findReact, findVue, findByRole }
package/lib/locator.js CHANGED
@@ -5,7 +5,7 @@ import { createRequire } from 'module'
5
5
  const require = createRequire(import.meta.url)
6
6
  let cssToXPath
7
7
 
8
- const locatorTypes = ['css', 'by', 'xpath', 'id', 'name', 'fuzzy', 'frame', 'shadow', 'pw', 'role']
8
+ const locatorTypes = ['css', 'by', 'xpath', 'id', 'name', 'fuzzy', 'frame', 'shadow', 'role']
9
9
  /** @class */
10
10
  class Locator {
11
11
  /**
@@ -29,14 +29,12 @@ class Locator {
29
29
  Object.assign(this, locator)
30
30
  return
31
31
  }
32
+ this._applyObjectLocator(locator)
33
+ return
34
+ }
32
35
 
33
- this.locator = locator
34
- this.type = Object.keys(locator)[0]
35
- this.value = locator[this.type]
36
- this.strict = true
37
-
38
- Locator.filters.forEach(f => f(locator, this))
39
-
36
+ // Try to parse JSON strings that look like objects
37
+ if (this.parsedJsonAsString(locator)) {
40
38
  return
41
39
  }
42
40
 
@@ -53,8 +51,9 @@ class Locator {
53
51
  if (isShadow(locator)) {
54
52
  this.type = 'shadow'
55
53
  }
56
- if (isPlaywrightLocator(locator)) {
57
- this.type = 'pw'
54
+ if (isReactVueLocator(locator)) {
55
+ // React/Vue locators - keep as fuzzy type, helpers will handle them specially
56
+ this.type = 'fuzzy'
58
57
  }
59
58
 
60
59
  Locator.filters.forEach(f => f(locator, this))
@@ -76,8 +75,6 @@ class Locator {
76
75
  return this.value
77
76
  case 'shadow':
78
77
  return { shadow: this.value }
79
- case 'pw':
80
- return { pw: this.value }
81
78
  case 'role':
82
79
  return `[role="${this.value}"]`
83
80
  }
@@ -86,9 +83,43 @@ class Locator {
86
83
 
87
84
  toStrict() {
88
85
  if (!this.type) return null
86
+ if (this.type === 'role' && this.locator) {
87
+ return this.locator
88
+ }
89
89
  return { [this.type]: this.value }
90
90
  }
91
91
 
92
+ parsedJsonAsString(locator) {
93
+ if (typeof locator !== 'string') {
94
+ return false
95
+ }
96
+
97
+ const trimmed = locator.trim()
98
+ if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {
99
+ return false
100
+ }
101
+
102
+ try {
103
+ const parsed = JSON.parse(trimmed)
104
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
105
+ this._applyObjectLocator(parsed)
106
+ return true
107
+ }
108
+ } catch (e) {
109
+ }
110
+ return false
111
+ }
112
+
113
+ _applyObjectLocator(locator) {
114
+ this.strict = true
115
+ this.locator = locator
116
+ const keys = Object.keys(locator)
117
+ const [type] = keys
118
+ this.type = type
119
+ this.value = keys.length > 1 ? locator : locator[type]
120
+ Locator.filters.forEach(f => f(locator, this))
121
+ }
122
+
92
123
  /**
93
124
  * @returns {string}
94
125
  */
@@ -127,17 +158,27 @@ class Locator {
127
158
  /**
128
159
  * @returns {boolean}
129
160
  */
130
- isPlaywrightLocator() {
131
- return this.type === 'pw'
161
+ isRole() {
162
+ return this.type === 'role'
132
163
  }
133
164
 
134
165
  /**
135
- * @returns {boolean}
166
+ * @returns {{role: string, options: object}|null}
136
167
  */
137
- isRole() {
138
- return this.type === 'role'
168
+ getRoleOptions() {
169
+ if (!this.isRole()) return null
170
+ const data = this.locator && typeof this.locator === 'object' ? this.locator : { role: this.value }
171
+ const { role, text, name, exact, includeHidden, ...rest } = data
172
+ let options = { ...rest }
173
+ const accessibleName = name ?? text
174
+ if (accessibleName !== undefined) options.name = accessibleName
175
+ if (exact !== undefined) options.exact = exact
176
+ if (includeHidden !== undefined) options.includeHidden = includeHidden
177
+ if (Object.keys(options).length === 0) options = undefined
178
+ return { role, options }
139
179
  }
140
180
 
181
+
141
182
  /**
142
183
  * @returns {boolean}
143
184
  */
@@ -404,6 +445,16 @@ Locator.build = locator => {
404
445
  return new Locator(locator, 'css')
405
446
  }
406
447
 
448
+ /**
449
+ * @param {CodeceptJS.LocatorOrString|Locator} locator
450
+ * @param {string} [defaultType]
451
+ * @returns {Locator}
452
+ */
453
+ Locator.from = (locator, defaultType = '') => {
454
+ if (locator instanceof Locator) return locator
455
+ return new Locator(locator, defaultType)
456
+ }
457
+
407
458
  /**
408
459
  * Filters to modify locators
409
460
  * @type {Array<function(CodeceptJS.LocatorOrString, Locator): void>}
@@ -604,20 +655,12 @@ function removePrefix(xpath) {
604
655
  * @param {string} locator
605
656
  * @returns {boolean}
606
657
  */
607
- function isPlaywrightLocator(locator) {
658
+ function isReactVueLocator(locator) {
608
659
  return locator.includes('_react') || locator.includes('_vue')
609
660
  }
610
661
 
611
662
  /**
612
663
  * @private
613
- * check if the locator is a role locator
614
- * @param {{role: string}} locator
615
- * @returns {boolean}
616
- */
617
- function isRoleLocator(locator) {
618
- return locator.role !== undefined && typeof locator.role === 'string' && Object.keys(locator).length >= 1
619
- }
620
-
621
664
  /**
622
665
  * @private
623
666
  * @param {CodeceptJS.LocatorOrString} locator
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "4.0.1-beta.17",
3
+ "version": "4.0.1-beta.19",
4
4
  "type": "module",
5
5
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
6
6
  "keywords": [
@@ -88,13 +88,13 @@
88
88
  "@codeceptjs/configure": "1.0.6",
89
89
  "@codeceptjs/helper": "2.0.4",
90
90
  "@cucumber/cucumber-expressions": "18",
91
- "@cucumber/gherkin": "35.1.0",
92
- "@cucumber/messages": "29.0.1",
91
+ "@cucumber/gherkin": "37.0.0",
92
+ "@cucumber/messages": "31.0.0",
93
93
  "@xmldom/xmldom": "0.9.8",
94
94
  "acorn": "8.15.0",
95
95
  "ai": "^5.0.60",
96
96
  "arrify": "3.0.0",
97
- "axios": "1.12.2",
97
+ "axios": "1.13.2",
98
98
  "chalk": "4.1.2",
99
99
  "cheerio": "^1.0.0",
100
100
  "chokidar": "^4.0.3",
@@ -108,11 +108,11 @@
108
108
  "fn-args": "4.0.0",
109
109
  "fs-extra": "11.3.2",
110
110
  "fuse.js": "^7.0.0",
111
- "glob": ">=9.0.0 <12",
111
+ "glob": ">=9.0.0 <14",
112
112
  "html-minifier-terser": "7.2.0",
113
113
  "inquirer": "^8.2.7",
114
114
  "invisi-data": "^1.0.0",
115
- "joi": "18.0.1",
115
+ "joi": "18.0.2",
116
116
  "js-beautify": "1.15.4",
117
117
  "lodash.clonedeep": "4.5.0",
118
118
  "lodash.merge": "4.6.2",
@@ -149,7 +149,7 @@
149
149
  "@types/node": "^24.9.2",
150
150
  "@wdio/sauce-service": "9.12.5",
151
151
  "@wdio/selenium-standalone-service": "8.15.0",
152
- "@wdio/utils": "9.20.0",
152
+ "@wdio/utils": "9.21.0",
153
153
  "@xmldom/xmldom": "0.9.8",
154
154
  "bunosh": "latest",
155
155
  "chai": "^6.2.1",
@@ -162,8 +162,8 @@
162
162
  "eslint-plugin-mocha": "11.1.0",
163
163
  "expect": "30.2.0",
164
164
  "express": "^5.1.0",
165
- "globals": "16.4.0",
166
- "graphql": "16.11.0",
165
+ "globals": "16.5.0",
166
+ "graphql": "16.12.0",
167
167
  "graphql-tag": "^2.12.6",
168
168
  "husky": "9.1.7",
169
169
  "jsdoc": "^3.6.11",
@@ -172,7 +172,7 @@
172
172
  "mochawesome": "^7.1.3",
173
173
  "playwright": "1.55.1",
174
174
  "prettier": "^3.3.2",
175
- "puppeteer": "24.15.0",
175
+ "puppeteer": "24.33.0",
176
176
  "qrcode-terminal": "0.12.0",
177
177
  "rosie": "2.1.1",
178
178
  "runok": "^0.9.3",
@@ -184,7 +184,7 @@
184
184
  "tsd": "^0.33.0",
185
185
  "tsd-jsdoc": "2.5.0",
186
186
  "tsx": "^4.19.2",
187
- "typedoc": "0.28.13",
187
+ "typedoc": "0.28.15",
188
188
  "typedoc-plugin-markdown": "4.9.0",
189
189
  "typescript": "5.8.3",
190
190
  "wdio-docker-service": "3.2.1",