codeceptjs 4.2.1-beta.1 → 4.2.1-beta.2
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.
- package/docs/helpers/Lightpanda.md +1 -1
- package/lib/helper/CDPBrowser.js +30 -6
- package/lib/helper/Lightpanda.js +1 -1
- package/lib/helper/clientscripts/cdpBrowserClient.js +1 -1
- package/lib/helper/clientscripts/layoutProbe.js +12 -0
- package/lib/helper/extras/CDPConnection.js +10 -2
- package/package.json +1 -1
- package/typings/promiseBasedTypes.d.ts +1 -1
- package/typings/types.d.ts +1 -1
|
@@ -62,7 +62,7 @@ These are set automatically and only need overriding for unusual setups:
|
|
|
62
62
|
|
|
63
63
|
## Limitations
|
|
64
64
|
|
|
65
|
-
* No screenshots and no screencast: `saveScreenshot`
|
|
65
|
+
* No screenshots and no screencast: `saveScreenshot` and `saveElementScreenshot` do nothing (a debug message is printed).
|
|
66
66
|
* No frames or popups.
|
|
67
67
|
* No scrolling: scroll positions always stay at 0.
|
|
68
68
|
* Computed styles cover what visibility checks need (`display`, `visibility`, `opacity`,
|
package/lib/helper/CDPBrowser.js
CHANGED
|
@@ -7,7 +7,9 @@ import Helper from '@codeceptjs/helper'
|
|
|
7
7
|
import CDPConnection from './extras/CDPConnection.js'
|
|
8
8
|
import installCodeceptClient from './clientscripts/cdpBrowserClient.js'
|
|
9
9
|
import xpathPolyfillSource from './clientscripts/xpathPolyfill.js'
|
|
10
|
+
import layoutProbe from './clientscripts/layoutProbe.js'
|
|
10
11
|
import Locator from '../locator.js'
|
|
12
|
+
import output from '../output.js'
|
|
11
13
|
import store from '../store.js'
|
|
12
14
|
import { xpathLocator, normalizePath, resolveUrl, toCamelCase, convertCssPropertiesToCamelCase, normalizeSpacesInString, fileExists, base64EncodeFile, getMimeType, isFile, isWindows } from '../utils.js'
|
|
13
15
|
import ElementNotFound from './errors/ElementNotFound.js'
|
|
@@ -357,8 +359,20 @@ class CDPBrowser extends Helper {
|
|
|
357
359
|
await this.cdp.connect()
|
|
358
360
|
}
|
|
359
361
|
|
|
362
|
+
_beforeStep() {
|
|
363
|
+
if (this._connectError) throw new Error(this._connectError.message)
|
|
364
|
+
}
|
|
365
|
+
|
|
360
366
|
async _before() {
|
|
361
|
-
|
|
367
|
+
this._connectError = null
|
|
368
|
+
if (!this.cdp || !this.cdp.isConnected) {
|
|
369
|
+
try {
|
|
370
|
+
await this._connect()
|
|
371
|
+
} catch (err) {
|
|
372
|
+
this._connectError = err
|
|
373
|
+
throw err
|
|
374
|
+
}
|
|
375
|
+
}
|
|
362
376
|
this._navStartWaiters = []
|
|
363
377
|
this._lastMainFrameNav = { loaderId: null, events: {} }
|
|
364
378
|
const { targetId } = await this.cdp.send('Target.createTarget', { url: 'about:blank' })
|
|
@@ -595,8 +609,8 @@ class CDPBrowser extends Helper {
|
|
|
595
609
|
|
|
596
610
|
async _probeCapabilities() {
|
|
597
611
|
if (this.capabilities.layout === null) {
|
|
598
|
-
const display = await this._evaluate(`
|
|
599
|
-
this.capabilities.layout = display === '' ? '
|
|
612
|
+
const display = await this._evaluate(`(${layoutProbe.toString()})()`)
|
|
613
|
+
this.capabilities.layout = display === 'none' ? 'real' : 'none'
|
|
600
614
|
}
|
|
601
615
|
if (this.capabilities.screenshot === null) {
|
|
602
616
|
this.capabilities.screenshot = this.capabilities.layout === 'real'
|
|
@@ -610,6 +624,13 @@ class CDPBrowser extends Helper {
|
|
|
610
624
|
if (this.capabilities.innerText === null) {
|
|
611
625
|
await this._needsVisibleTextFallback()
|
|
612
626
|
}
|
|
627
|
+
if (!this._engineReported) {
|
|
628
|
+
this._engineReported = true
|
|
629
|
+
let engine = 'render (layout and screenshots)'
|
|
630
|
+
if (this.capabilities.layout === 'none') engine = 'no-render (DOM only: no layout, visibility checks or screenshots)'
|
|
631
|
+
else if (!this.capabilities.screenshot) engine = 'layout without screenshots'
|
|
632
|
+
output.print(`${this.constructor.name} engine: ${engine}`)
|
|
633
|
+
}
|
|
613
634
|
}
|
|
614
635
|
|
|
615
636
|
async _run(candidates, action, payload, context = null) {
|
|
@@ -807,7 +828,8 @@ class CDPBrowser extends Helper {
|
|
|
807
828
|
const useWalker = await this._needsVisibleTextFallback()
|
|
808
829
|
const res = await this._runTextCheck(text, { ignoreCase, useWalker })
|
|
809
830
|
if (negate ? !res.found : res.found) return
|
|
810
|
-
let source =
|
|
831
|
+
let source = res.text
|
|
832
|
+
if (source === undefined) source = await this._textSource(null)
|
|
811
833
|
let needle = text
|
|
812
834
|
if (ignoreCase) {
|
|
813
835
|
needle = needle.toLowerCase()
|
|
@@ -1343,7 +1365,8 @@ class CDPBrowser extends Helper {
|
|
|
1343
1365
|
*/
|
|
1344
1366
|
async saveScreenshot(fileName) {
|
|
1345
1367
|
if (this.capabilities.screenshot === false) {
|
|
1346
|
-
|
|
1368
|
+
this.debug('saveScreenshot skipped: this browser has no rendering engine')
|
|
1369
|
+
return
|
|
1347
1370
|
}
|
|
1348
1371
|
const outputDir = global.output_dir || '.'
|
|
1349
1372
|
const res = await this.cdp.send('Page.captureScreenshot', { format: 'png' }, this.sessionId)
|
|
@@ -1355,7 +1378,8 @@ class CDPBrowser extends Helper {
|
|
|
1355
1378
|
*/
|
|
1356
1379
|
async saveElementScreenshot(locator, fileName) {
|
|
1357
1380
|
if (this.capabilities.screenshot === false) {
|
|
1358
|
-
|
|
1381
|
+
this.debug('saveElementScreenshot skipped: this browser has no rendering engine')
|
|
1382
|
+
return
|
|
1359
1383
|
}
|
|
1360
1384
|
const res = await this._run(this._candidates(locator), 'rect')
|
|
1361
1385
|
if (!res.found) throw new ElementNotFound(locator)
|
package/lib/helper/Lightpanda.js
CHANGED
|
@@ -72,7 +72,7 @@ const config = {}
|
|
|
72
72
|
*
|
|
73
73
|
* ## Limitations
|
|
74
74
|
*
|
|
75
|
-
* - No screenshots and no screencast: `saveScreenshot`
|
|
75
|
+
* - No screenshots and no screencast: `saveScreenshot` and `saveElementScreenshot` do nothing (a debug message is printed).
|
|
76
76
|
* - No frames or popups.
|
|
77
77
|
* - No scrolling: scroll positions always stay at 0.
|
|
78
78
|
* - Computed styles cover what visibility checks need (`display`, `visibility`, `opacity`,
|
|
@@ -76,7 +76,7 @@ export default function installCodeceptClient(xpathNeedsPolyfill) {
|
|
|
76
76
|
const hayCmp = opts.ignoreCase ? hay.toLowerCase() : hay
|
|
77
77
|
const needleCmp = opts.ignoreCase ? needleNorm.toLowerCase() : needleNorm
|
|
78
78
|
const idx = hayCmp.indexOf(needleCmp)
|
|
79
|
-
if (idx === -1) return { found: false, snippet: null }
|
|
79
|
+
if (idx === -1) return { found: false, snippet: null, text: hay }
|
|
80
80
|
const from = Math.max(0, idx - 60)
|
|
81
81
|
return { found: true, snippet: hay.slice(from, idx + needleNorm.length + 60) }
|
|
82
82
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default function layoutProbe() {
|
|
2
|
+
const style = document.createElement('style')
|
|
3
|
+
style.textContent = '.__codecept-layout-probe{display:none}'
|
|
4
|
+
document.documentElement.appendChild(style)
|
|
5
|
+
const probe = document.createElement('div')
|
|
6
|
+
probe.className = '__codecept-layout-probe'
|
|
7
|
+
;(document.body || document.documentElement).appendChild(probe)
|
|
8
|
+
const display = getComputedStyle(probe).display
|
|
9
|
+
style.remove()
|
|
10
|
+
probe.remove()
|
|
11
|
+
return display
|
|
12
|
+
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { WebSocket } from 'ws'
|
|
2
|
+
import debugModule from 'debug'
|
|
3
|
+
|
|
4
|
+
const debug = debugModule('codeceptjs:cdp')
|
|
2
5
|
|
|
3
6
|
class CDPConnection {
|
|
4
7
|
constructor(endpoint, options = {}) {
|
|
@@ -9,6 +12,7 @@ class CDPConnection {
|
|
|
9
12
|
this.lastId = 0
|
|
10
13
|
this.pending = new Map()
|
|
11
14
|
this.listeners = new Map()
|
|
15
|
+
this.totals = {}
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
async connect() {
|
|
@@ -49,7 +53,7 @@ class CDPConnection {
|
|
|
49
53
|
this.pending.delete(id)
|
|
50
54
|
reject(new Error(`CDP command ${method} timed out after ${this.timeout}ms`))
|
|
51
55
|
}, this.timeout)
|
|
52
|
-
this.pending.set(id, { resolve, reject, timer })
|
|
56
|
+
this.pending.set(id, { resolve, reject, timer, method, started: Date.now() })
|
|
53
57
|
this.ws.send(JSON.stringify(message))
|
|
54
58
|
})
|
|
55
59
|
}
|
|
@@ -61,9 +65,12 @@ class CDPConnection {
|
|
|
61
65
|
|
|
62
66
|
_onMessage(msg) {
|
|
63
67
|
if (msg.id && this.pending.has(msg.id)) {
|
|
64
|
-
const { resolve, reject, timer } = this.pending.get(msg.id)
|
|
68
|
+
const { resolve, reject, timer, method, started } = this.pending.get(msg.id)
|
|
65
69
|
clearTimeout(timer)
|
|
66
70
|
this.pending.delete(msg.id)
|
|
71
|
+
const ms = Date.now() - started
|
|
72
|
+
this.totals[method] = (this.totals[method] || 0) + ms
|
|
73
|
+
debug(`${method} ${ms}ms`)
|
|
67
74
|
if (msg.error) reject(new Error(msg.error.message))
|
|
68
75
|
else resolve(msg.result)
|
|
69
76
|
return
|
|
@@ -80,6 +87,7 @@ class CDPConnection {
|
|
|
80
87
|
|
|
81
88
|
async close() {
|
|
82
89
|
if (!this.ws) return
|
|
90
|
+
debug('total time per method', this.totals)
|
|
83
91
|
await new Promise(resolve => {
|
|
84
92
|
if (this.ws.readyState === WebSocket.CLOSED) return resolve()
|
|
85
93
|
this.ws.once('close', resolve)
|
package/package.json
CHANGED
|
@@ -3438,7 +3438,7 @@ declare namespace CodeceptJS {
|
|
|
3438
3438
|
*
|
|
3439
3439
|
* ## Limitations
|
|
3440
3440
|
*
|
|
3441
|
-
* - No screenshots and no screencast: `saveScreenshot`
|
|
3441
|
+
* - No screenshots and no screencast: `saveScreenshot` and `saveElementScreenshot` do nothing (a debug message is printed).
|
|
3442
3442
|
* - No frames or popups.
|
|
3443
3443
|
* - No scrolling: scroll positions always stay at 0.
|
|
3444
3444
|
* - Computed styles cover what visibility checks need (`display`, `visibility`, `opacity`,
|
package/typings/types.d.ts
CHANGED
|
@@ -3541,7 +3541,7 @@ declare namespace CodeceptJS {
|
|
|
3541
3541
|
*
|
|
3542
3542
|
* ## Limitations
|
|
3543
3543
|
*
|
|
3544
|
-
* - No screenshots and no screencast: `saveScreenshot`
|
|
3544
|
+
* - No screenshots and no screencast: `saveScreenshot` and `saveElementScreenshot` do nothing (a debug message is printed).
|
|
3545
3545
|
* - No frames or popups.
|
|
3546
3546
|
* - No scrolling: scroll positions always stay at 0.
|
|
3547
3547
|
* - Computed styles cover what visibility checks need (`display`, `visibility`, `opacity`,
|