codeceptjs 4.2.0-beta.3 → 4.2.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.
- package/README.md +3 -1
- package/docs/alternative-browsers.md +15 -10
- package/docs/continuous-integration.md +14 -14
- package/docs/helpers/Obscura.md +41 -16
- package/docs/installation.md +35 -0
- package/docs/mcp.md +1 -1
- package/docs/migration-4.md +2 -2
- package/docs/parallel.md +1 -1
- package/lib/helper/Appium.js +23 -0
- package/lib/helper/CDPBrowser.js +84 -0
- package/lib/helper/Obscura.js +25 -2
- package/lib/helper/Playwright.js +55 -4
- package/lib/helper/Puppeteer.js +60 -3
- package/lib/helper/WebDriver.js +43 -0
- package/lib/helper/extras/clipboard.js +31 -0
- package/lib/plugin/retryFailedStep.js +7 -2
- package/package.json +2 -2
- package/typings/promiseBasedTypes.d.ts +248 -2
- package/typings/types.d.ts +261 -2
package/lib/helper/Playwright.js
CHANGED
|
@@ -8,6 +8,7 @@ import Locator from '../locator.js'
|
|
|
8
8
|
import recorder from '../recorder.js'
|
|
9
9
|
import store from '../store.js'
|
|
10
10
|
import { checkFocusBeforeType, checkFocusBeforePressKey } from './extras/focusCheck.js'
|
|
11
|
+
import { CLIPBOARD_READ_TIMEOUT_MS, readClipboardScript, writeClipboardScript } from './extras/clipboard.js'
|
|
11
12
|
import { includes as stringIncludes } from '../assert/include.js'
|
|
12
13
|
import { urlEquals, equals } from '../assert/equal.js'
|
|
13
14
|
import { empty } from '../assert/empty.js'
|
|
@@ -584,7 +585,8 @@ class Playwright extends Helper {
|
|
|
584
585
|
// Clear popup state to ensure clean state for each test
|
|
585
586
|
popupStore.clear()
|
|
586
587
|
|
|
587
|
-
|
|
588
|
+
// Configure retry for this test; will clean up after test completes
|
|
589
|
+
this._retryConfig = {
|
|
588
590
|
retries: test?.opts?.conditionalRetries || 3,
|
|
589
591
|
when: err => {
|
|
590
592
|
if (!err || typeof err.message !== 'string') {
|
|
@@ -593,7 +595,8 @@ class Playwright extends Helper {
|
|
|
593
595
|
// ignore context errors
|
|
594
596
|
return err.message.includes('context')
|
|
595
597
|
},
|
|
596
|
-
}
|
|
598
|
+
}
|
|
599
|
+
recorder.retry(this._retryConfig)
|
|
597
600
|
|
|
598
601
|
// Start browser if needed (initial start or browser restart strategy)
|
|
599
602
|
if (!this.isRunning && !this.options.manualStart) await this._startBrowser()
|
|
@@ -698,6 +701,12 @@ class Playwright extends Helper {
|
|
|
698
701
|
}
|
|
699
702
|
|
|
700
703
|
async _after() {
|
|
704
|
+
// Clean up our retry config to prevent accumulation
|
|
705
|
+
if (this._retryConfig) {
|
|
706
|
+
recorder.retries = recorder.retries.filter(r => r !== this._retryConfig)
|
|
707
|
+
this._retryConfig = null
|
|
708
|
+
}
|
|
709
|
+
|
|
701
710
|
if (!this.isRunning) return
|
|
702
711
|
|
|
703
712
|
// Clear popup state to prevent leakage between tests
|
|
@@ -2659,6 +2668,49 @@ class Playwright extends Helper {
|
|
|
2659
2668
|
return this.browserContext.clearCookies()
|
|
2660
2669
|
}
|
|
2661
2670
|
|
|
2671
|
+
/**
|
|
2672
|
+
* {{> seeInClipboard }}
|
|
2673
|
+
*/
|
|
2674
|
+
async seeInClipboard(text) {
|
|
2675
|
+
const clipboard = await this.grabFromClipboard()
|
|
2676
|
+
stringIncludes('clipboard').assert(text, clipboard)
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
/**
|
|
2680
|
+
* {{> seeClipboardEquals }}
|
|
2681
|
+
*/
|
|
2682
|
+
async seeClipboardEquals(text) {
|
|
2683
|
+
const clipboard = await this.grabFromClipboard()
|
|
2684
|
+
return equals('clipboard').assert(clipboard, text)
|
|
2685
|
+
}
|
|
2686
|
+
|
|
2687
|
+
/**
|
|
2688
|
+
* {{> grabFromClipboard }}
|
|
2689
|
+
*/
|
|
2690
|
+
async grabFromClipboard() {
|
|
2691
|
+
await this._grantClipboardAccess()
|
|
2692
|
+
const clipboard = await this.page.evaluate(readClipboardScript, CLIPBOARD_READ_TIMEOUT_MS)
|
|
2693
|
+
this.debugSection('Clipboard', clipboard)
|
|
2694
|
+
return clipboard
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2697
|
+
/**
|
|
2698
|
+
* {{> clearClipboard }}
|
|
2699
|
+
*/
|
|
2700
|
+
async clearClipboard() {
|
|
2701
|
+
await this._grantClipboardAccess()
|
|
2702
|
+
return this.page.evaluate(writeClipboardScript, '')
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
async _grantClipboardAccess() {
|
|
2706
|
+
await this.page.bringToFront().catch(() => {})
|
|
2707
|
+
if (this.options.browser !== 'chromium') return
|
|
2708
|
+
await this.page
|
|
2709
|
+
.context()
|
|
2710
|
+
.grantPermissions(['clipboard-read', 'clipboard-write'])
|
|
2711
|
+
.catch(() => {})
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2662
2714
|
/**
|
|
2663
2715
|
* Executes a script on the page:
|
|
2664
2716
|
*
|
|
@@ -3667,8 +3719,7 @@ class Playwright extends Helper {
|
|
|
3667
3719
|
}
|
|
3668
3720
|
|
|
3669
3721
|
try {
|
|
3670
|
-
|
|
3671
|
-
this.frame = await Promise.race([this.page.frameLocator(locator), new Promise((_, reject) => setTimeout(() => reject(new Error('Frame locator timeout')), 5000))])
|
|
3722
|
+
this.frame = this.frame ? this.frame.frameLocator(locator) : this.page.frameLocator(locator)
|
|
3672
3723
|
} catch (e) {
|
|
3673
3724
|
console.warn('Warning during frame locator creation:', e.message)
|
|
3674
3725
|
throw new Error(`Frame ${JSON.stringify(locator)} could not be accessed`)
|
package/lib/helper/Puppeteer.js
CHANGED
|
@@ -9,6 +9,7 @@ import Locator from '../locator.js'
|
|
|
9
9
|
import recorder from '../recorder.js'
|
|
10
10
|
import store from '../store.js'
|
|
11
11
|
import { checkFocusBeforeType, checkFocusBeforePressKey } from './extras/focusCheck.js'
|
|
12
|
+
import { CLIPBOARD_READ_TIMEOUT_MS, readClipboardScript, writeClipboardScript } from './extras/clipboard.js'
|
|
12
13
|
import { includes as stringIncludes } from '../assert/include.js'
|
|
13
14
|
import { urlEquals, equals } from '../assert/equal.js'
|
|
14
15
|
import { empty } from '../assert/empty.js'
|
|
@@ -354,7 +355,8 @@ class Puppeteer extends Helper {
|
|
|
354
355
|
async _before(test) {
|
|
355
356
|
this.sessionPages = {}
|
|
356
357
|
this.currentRunningTest = test
|
|
357
|
-
|
|
358
|
+
// Configure retry for this test; will clean up after test completes
|
|
359
|
+
this._retryConfig = {
|
|
358
360
|
retries: test?.opts?.conditionalRetries || 3,
|
|
359
361
|
when: err => {
|
|
360
362
|
if (!err || typeof err.message !== 'string') {
|
|
@@ -363,13 +365,20 @@ class Puppeteer extends Helper {
|
|
|
363
365
|
// ignore context errors
|
|
364
366
|
return err.message.includes('context')
|
|
365
367
|
},
|
|
366
|
-
}
|
|
368
|
+
}
|
|
369
|
+
recorder.retry(this._retryConfig)
|
|
367
370
|
if (this.options.restart && !this.options.manualStart) return this._startBrowser()
|
|
368
371
|
if (!this.isRunning && !this.options.manualStart) return this._startBrowser()
|
|
369
372
|
return this.browser
|
|
370
373
|
}
|
|
371
374
|
|
|
372
375
|
async _after() {
|
|
376
|
+
// Clean up our retry config to prevent accumulation
|
|
377
|
+
if (this._retryConfig) {
|
|
378
|
+
recorder.retries = recorder.retries.filter(r => r !== this._retryConfig)
|
|
379
|
+
this._retryConfig = null
|
|
380
|
+
}
|
|
381
|
+
|
|
373
382
|
if (!this.isRunning) return
|
|
374
383
|
|
|
375
384
|
// Clear popup state to prevent leakage between tests
|
|
@@ -1960,6 +1969,55 @@ class Puppeteer extends Helper {
|
|
|
1960
1969
|
return this.page.deleteCookie(cookie[0])
|
|
1961
1970
|
}
|
|
1962
1971
|
|
|
1972
|
+
/**
|
|
1973
|
+
* {{> seeInClipboard }}
|
|
1974
|
+
*/
|
|
1975
|
+
async seeInClipboard(text) {
|
|
1976
|
+
const clipboard = await this.grabFromClipboard()
|
|
1977
|
+
stringIncludes('clipboard').assert(text, clipboard)
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
/**
|
|
1981
|
+
* {{> seeClipboardEquals }}
|
|
1982
|
+
*/
|
|
1983
|
+
async seeClipboardEquals(text) {
|
|
1984
|
+
const clipboard = await this.grabFromClipboard()
|
|
1985
|
+
return equals('clipboard').assert(clipboard, text)
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
/**
|
|
1989
|
+
* {{> grabFromClipboard }}
|
|
1990
|
+
*/
|
|
1991
|
+
async grabFromClipboard() {
|
|
1992
|
+
await this._grantClipboardAccess()
|
|
1993
|
+
const clipboard = await this.page.evaluate(readClipboardScript, CLIPBOARD_READ_TIMEOUT_MS)
|
|
1994
|
+
this.debugSection('Clipboard', clipboard)
|
|
1995
|
+
return clipboard
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
/**
|
|
1999
|
+
* {{> clearClipboard }}
|
|
2000
|
+
*/
|
|
2001
|
+
async clearClipboard() {
|
|
2002
|
+
await this._grantClipboardAccess()
|
|
2003
|
+
return this.page.evaluate(writeClipboardScript, '')
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
async _grantClipboardAccess() {
|
|
2007
|
+
await this.page.bringToFront().catch(() => {})
|
|
2008
|
+
let origin
|
|
2009
|
+
try {
|
|
2010
|
+
origin = new URL(this.page.url()).origin
|
|
2011
|
+
} catch (err) {
|
|
2012
|
+
return
|
|
2013
|
+
}
|
|
2014
|
+
if (!origin.startsWith('http')) return
|
|
2015
|
+
await this.page
|
|
2016
|
+
.browserContext()
|
|
2017
|
+
.overridePermissions(origin, ['clipboard-read', 'clipboard-write', 'clipboard-sanitized-write'])
|
|
2018
|
+
.catch(() => {})
|
|
2019
|
+
}
|
|
2020
|
+
|
|
1963
2021
|
/**
|
|
1964
2022
|
* If a function returns a Promise, tt will wait for its resolution.
|
|
1965
2023
|
*
|
|
@@ -3709,4 +3767,3 @@ async function proceedSelect(context, el, option) {
|
|
|
3709
3767
|
|
|
3710
3768
|
return this._waitForAction()
|
|
3711
3769
|
}
|
|
3712
|
-
|
package/lib/helper/WebDriver.js
CHANGED
|
@@ -11,6 +11,7 @@ import { includes as stringIncludes } from '../assert/include.js'
|
|
|
11
11
|
import { urlEquals, equals } from '../assert/equal.js'
|
|
12
12
|
import store from '../store.js'
|
|
13
13
|
import { checkFocusBeforeType, checkFocusBeforePressKey } from './extras/focusCheck.js'
|
|
14
|
+
import { CLIPBOARD_READ_TIMEOUT_MS, readClipboardScript, writeClipboardScript, clipboardAsyncScript } from './extras/clipboard.js'
|
|
14
15
|
import output from '../output.js'
|
|
15
16
|
const { debug } = output
|
|
16
17
|
import { empty } from '../assert/empty.js'
|
|
@@ -2091,6 +2092,48 @@ class WebDriver extends Helper {
|
|
|
2091
2092
|
return cookie[0]
|
|
2092
2093
|
}
|
|
2093
2094
|
|
|
2095
|
+
/**
|
|
2096
|
+
* {{> seeInClipboard }}
|
|
2097
|
+
*/
|
|
2098
|
+
async seeInClipboard(text) {
|
|
2099
|
+
const clipboard = await this.grabFromClipboard()
|
|
2100
|
+
return stringIncludes('clipboard').assert(text, clipboard)
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
/**
|
|
2104
|
+
* {{> seeClipboardEquals }}
|
|
2105
|
+
*/
|
|
2106
|
+
async seeClipboardEquals(text) {
|
|
2107
|
+
const clipboard = await this.grabFromClipboard()
|
|
2108
|
+
return equals('clipboard').assert(clipboard, text)
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
/**
|
|
2112
|
+
* {{> grabFromClipboard }}
|
|
2113
|
+
*/
|
|
2114
|
+
async grabFromClipboard() {
|
|
2115
|
+
await this._grantClipboardAccess()
|
|
2116
|
+
const result = (await this.browser.executeAsync(clipboardAsyncScript(readClipboardScript), CLIPBOARD_READ_TIMEOUT_MS)) || {}
|
|
2117
|
+
if (result.error) throw new Error(`Could not read the clipboard: ${result.error}`)
|
|
2118
|
+
this.debugSection('Clipboard', result.value)
|
|
2119
|
+
return result.value
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
/**
|
|
2123
|
+
* {{> clearClipboard }}
|
|
2124
|
+
*/
|
|
2125
|
+
async clearClipboard() {
|
|
2126
|
+
await this._grantClipboardAccess()
|
|
2127
|
+
const result = (await this.browser.executeAsync(clipboardAsyncScript(writeClipboardScript), '')) || {}
|
|
2128
|
+
if (result.error) throw new Error(`Could not write to the clipboard: ${result.error}`)
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
async _grantClipboardAccess() {
|
|
2132
|
+
if (typeof this.browser.setPermissions !== 'function') return
|
|
2133
|
+
await this.browser.setPermissions({ name: 'clipboard-read' }, 'granted').catch(() => {})
|
|
2134
|
+
await this.browser.setPermissions({ name: 'clipboard-write' }, 'granted').catch(() => {})
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2094
2137
|
/**
|
|
2095
2138
|
* {{> waitForCookie }}
|
|
2096
2139
|
*/
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const CLIPBOARD_READ_TIMEOUT_MS = 5000
|
|
2
|
+
|
|
3
|
+
export function readClipboardScript(timeout) {
|
|
4
|
+
if (!navigator.clipboard || !navigator.clipboard.readText) {
|
|
5
|
+
throw new Error('Clipboard API is not available on this page, it requires a secure context (https or localhost)')
|
|
6
|
+
}
|
|
7
|
+
return Promise.race([navigator.clipboard.readText(), new Promise((resolve, reject) => setTimeout(() => reject(new Error('timed out while reading the clipboard')), timeout))])
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function writeClipboardScript(text) {
|
|
11
|
+
if (!navigator.clipboard || !navigator.clipboard.writeText) {
|
|
12
|
+
throw new Error('Clipboard API is not available on this page, it requires a secure context (https or localhost)')
|
|
13
|
+
}
|
|
14
|
+
return navigator.clipboard.writeText(text)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function clipboardExpression(script, arg) {
|
|
18
|
+
return `(${script.toString()})(${JSON.stringify(arg)})`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function clipboardAsyncScript(script) {
|
|
22
|
+
return `
|
|
23
|
+
var done = arguments[arguments.length - 1]
|
|
24
|
+
var fail = function (err) { done({ error: (err && err.message) || String(err) }) }
|
|
25
|
+
try {
|
|
26
|
+
(${script.toString()})(arguments[0]).then(function (value) { done({ value: value }) }, fail)
|
|
27
|
+
} catch (err) {
|
|
28
|
+
fail(err)
|
|
29
|
+
}
|
|
30
|
+
`
|
|
31
|
+
}
|
|
@@ -98,7 +98,6 @@ export default function (config) {
|
|
|
98
98
|
|
|
99
99
|
const when = err => {
|
|
100
100
|
if (!enableRetry) return
|
|
101
|
-
if (store.debugMode) return false
|
|
102
101
|
if (!store.autoRetries) return false
|
|
103
102
|
if (err && err.isTerminal) return false
|
|
104
103
|
if (err && err.message && (err.message.includes('ERR_ABORTED') || err.message.includes('frame was detached') || err.message.includes('Target page, context or browser has been closed'))) return false
|
|
@@ -152,7 +151,9 @@ export default function (config) {
|
|
|
152
151
|
test.opts.stepRetryPriority = stepRetryPriority
|
|
153
152
|
|
|
154
153
|
debug('applying retries = %d for test %s', config.retries, test.title)
|
|
155
|
-
recorder.
|
|
154
|
+
if (!recorder.retries.find(r => r === config)) {
|
|
155
|
+
recorder.retry(config)
|
|
156
|
+
}
|
|
156
157
|
})
|
|
157
158
|
|
|
158
159
|
event.dispatcher.on(event.test.started, test => {
|
|
@@ -171,4 +172,8 @@ export default function (config) {
|
|
|
171
172
|
test.opts.conditionalRetries = test.opts.conditionalRetries || config.retries
|
|
172
173
|
}
|
|
173
174
|
})
|
|
175
|
+
|
|
176
|
+
event.dispatcher.on(event.test.after, () => {
|
|
177
|
+
recorder.retries = recorder.retries.filter(r => r !== config)
|
|
178
|
+
})
|
|
174
179
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeceptjs",
|
|
3
|
-
"version": "4.2.0
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Supercharged End 2 End Testing Framework for NodeJS",
|
|
6
6
|
"keywords": [
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
}
|
|
208
208
|
},
|
|
209
209
|
"engines": {
|
|
210
|
-
"node": ">=
|
|
210
|
+
"node": ">=22.12.0",
|
|
211
211
|
"npm": ">=5.6.0"
|
|
212
212
|
},
|
|
213
213
|
"es6": true,
|
|
@@ -770,6 +770,32 @@ declare namespace CodeceptJS {
|
|
|
770
770
|
* @returns Appium: support both Android and iOS
|
|
771
771
|
*/
|
|
772
772
|
closeApp(): Promise<void>;
|
|
773
|
+
/**
|
|
774
|
+
* Clears the system clipboard.
|
|
775
|
+
*
|
|
776
|
+
* ```js
|
|
777
|
+
* I.clearClipboard();
|
|
778
|
+
* I.seeClipboardEquals('');
|
|
779
|
+
* ```
|
|
780
|
+
*/
|
|
781
|
+
clearClipboard(): Promise<any>;
|
|
782
|
+
/**
|
|
783
|
+
* Grabs the text content of the system clipboard and returns it to test.
|
|
784
|
+
* Resumes test execution, so **should be used inside async function with `await`** operator.
|
|
785
|
+
*
|
|
786
|
+
* ```js
|
|
787
|
+
* I.click('Copy to clipboard');
|
|
788
|
+
* let url = await I.grabFromClipboard();
|
|
789
|
+
* ```
|
|
790
|
+
*
|
|
791
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
792
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
793
|
+
* @returns the system clipboard contents.
|
|
794
|
+
*
|
|
795
|
+
*
|
|
796
|
+
* Appium: support both Android and iOS
|
|
797
|
+
*/
|
|
798
|
+
grabFromClipboard(): Promise<string>;
|
|
773
799
|
/**
|
|
774
800
|
* Appends text to a input field or textarea.
|
|
775
801
|
* Field is located by name, label, CSS or XPath
|
|
@@ -2166,6 +2192,56 @@ declare namespace CodeceptJS {
|
|
|
2166
2192
|
* @param [name = null] - (optional, `null` by default) cookie name
|
|
2167
2193
|
*/
|
|
2168
2194
|
clearCookie(name?: string | null): Promise<void>;
|
|
2195
|
+
/**
|
|
2196
|
+
* Checks that the system clipboard contains the given text.
|
|
2197
|
+
*
|
|
2198
|
+
* ```js
|
|
2199
|
+
* I.click('Copy to clipboard');
|
|
2200
|
+
* I.seeInClipboard('https://codecept.io');
|
|
2201
|
+
* ```
|
|
2202
|
+
*
|
|
2203
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`).
|
|
2204
|
+
* @param text - value to check.
|
|
2205
|
+
*/
|
|
2206
|
+
seeInClipboard(text: string): Promise<void>;
|
|
2207
|
+
/**
|
|
2208
|
+
* Checks that the system clipboard is equal to the given text.
|
|
2209
|
+
*
|
|
2210
|
+
* ```js
|
|
2211
|
+
* I.click('Copy to clipboard');
|
|
2212
|
+
* I.seeClipboardEquals('https://codecept.io');
|
|
2213
|
+
* ```
|
|
2214
|
+
*
|
|
2215
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`).
|
|
2216
|
+
* @param text - value to check.
|
|
2217
|
+
*/
|
|
2218
|
+
seeClipboardEquals(text: string): Promise<void>;
|
|
2219
|
+
/**
|
|
2220
|
+
* Clears the system clipboard.
|
|
2221
|
+
*
|
|
2222
|
+
* ```js
|
|
2223
|
+
* I.clearClipboard();
|
|
2224
|
+
* I.seeClipboardEquals('');
|
|
2225
|
+
* ```
|
|
2226
|
+
*/
|
|
2227
|
+
clearClipboard(): Promise<void>;
|
|
2228
|
+
/**
|
|
2229
|
+
* Grabs the text content of the system clipboard.
|
|
2230
|
+
* Resumes test execution, so **should be used inside async function with `await`** operator.
|
|
2231
|
+
*
|
|
2232
|
+
* ```js
|
|
2233
|
+
* I.click('Copy to clipboard');
|
|
2234
|
+
* const url = await I.grabFromClipboard();
|
|
2235
|
+
* ```
|
|
2236
|
+
* @returns the system clipboard contents.
|
|
2237
|
+
*/
|
|
2238
|
+
grabFromClipboard(): Promise<string>;
|
|
2239
|
+
/**
|
|
2240
|
+
* Brings the current target to front and grants it clipboard read/write access, so
|
|
2241
|
+
* `navigator.clipboard` does not reject with a permission or focus error. Failures are ignored:
|
|
2242
|
+
* a browser without `Browser.grantPermissions` surfaces its own error from the read instead.
|
|
2243
|
+
*/
|
|
2244
|
+
protected _grantClipboardAccess(): Promise<any>;
|
|
2169
2245
|
/**
|
|
2170
2246
|
* Saves a screenshot to the output folder (set in codecept.conf.ts or codecept.conf.js).
|
|
2171
2247
|
* Filename is relative to the output folder.
|
|
@@ -3423,6 +3499,17 @@ declare namespace CodeceptJS {
|
|
|
3423
3499
|
* elements works, it only pins the config presets Obscura requires and manages the `obscura serve`
|
|
3424
3500
|
* process lifecycle, the same way Playwright manages its own browser process.
|
|
3425
3501
|
*
|
|
3502
|
+
* > Obscura support is experimental in CodeceptJS 4.2. Pin the browser version in CI and keep a
|
|
3503
|
+
* > Playwright/WebDriver job for browser-compatibility coverage.
|
|
3504
|
+
*
|
|
3505
|
+
* ## Compatibility
|
|
3506
|
+
*
|
|
3507
|
+
* | CodeceptJS | Recommended Obscura | Notes |
|
|
3508
|
+
* | --- | --- | --- |
|
|
3509
|
+
* | 4.2.x | 0.2.2 | Version used by the CodeceptJS Obscura CI workflow |
|
|
3510
|
+
* | 4.2.x | 0.2.x | Supported; capabilities are detected at runtime |
|
|
3511
|
+
* | 4.2.x | 0.1.x / `-no-render` | DOM-only mode; no layout, visibility assertions, or screenshots |
|
|
3512
|
+
*
|
|
3426
3513
|
* ## Modes
|
|
3427
3514
|
*
|
|
3428
3515
|
* - **ATTACH** — `endpoint` is set explicitly in the config. The helper only connects to it; it
|
|
@@ -3440,8 +3527,20 @@ declare namespace CodeceptJS {
|
|
|
3440
3527
|
*
|
|
3441
3528
|
* ## Install
|
|
3442
3529
|
*
|
|
3443
|
-
* Download a release
|
|
3444
|
-
*
|
|
3530
|
+
* Download a release archive from [Obscura releases](https://github.com/h4ckf0r0day/obscura/releases).
|
|
3531
|
+
* CodeceptJS 4.2 is tested with Obscura 0.2.2. Rendering archives are available for:
|
|
3532
|
+
*
|
|
3533
|
+
* | platform | archive |
|
|
3534
|
+
* | --- | --- |
|
|
3535
|
+
* | Linux x64 | `obscura-x86_64-linux.tar.gz` |
|
|
3536
|
+
* | Linux ARM64 | `obscura-aarch64-linux.tar.gz` |
|
|
3537
|
+
* | macOS Intel | `obscura-x86_64-macos.tar.gz` |
|
|
3538
|
+
* | macOS Apple Silicon | `obscura-aarch64-macos.tar.gz` |
|
|
3539
|
+
* | Windows x64 | `obscura-x86_64-windows.zip` |
|
|
3540
|
+
*
|
|
3541
|
+
* Extract the archive and put `obscura` (`obscura.exe` on Windows) on your `PATH`, or point
|
|
3542
|
+
* `binaryPath`/`OBSCURA_PATH` at it. The helper then launches and tears it down automatically.
|
|
3543
|
+
* For example, on Linux x64:
|
|
3445
3544
|
*
|
|
3446
3545
|
* ```sh
|
|
3447
3546
|
* curl -sL https://github.com/h4ckf0r0day/obscura/releases/download/v0.2.2/obscura-x86_64-linux.tar.gz | tar xz
|
|
@@ -5084,6 +5183,55 @@ declare namespace CodeceptJS {
|
|
|
5084
5183
|
* @param [cookie = null] - (optional, `null` by default) cookie name
|
|
5085
5184
|
*/
|
|
5086
5185
|
clearCookie(cookie?: string): Promise<any>;
|
|
5186
|
+
/**
|
|
5187
|
+
* Checks that the system clipboard contains the given text.
|
|
5188
|
+
*
|
|
5189
|
+
* ```js
|
|
5190
|
+
* I.click('Copy to clipboard');
|
|
5191
|
+
* I.seeInClipboard('https://codecept.io');
|
|
5192
|
+
* ```
|
|
5193
|
+
*
|
|
5194
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
5195
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
5196
|
+
* @param text - value to check.
|
|
5197
|
+
*/
|
|
5198
|
+
seeInClipboard(text: string): Promise<any>;
|
|
5199
|
+
/**
|
|
5200
|
+
* Checks that the system clipboard is equal to the given text.
|
|
5201
|
+
*
|
|
5202
|
+
* ```js
|
|
5203
|
+
* I.click('Copy to clipboard');
|
|
5204
|
+
* I.seeClipboardEquals('https://codecept.io');
|
|
5205
|
+
* ```
|
|
5206
|
+
*
|
|
5207
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
5208
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
5209
|
+
* @param text - value to check.
|
|
5210
|
+
*/
|
|
5211
|
+
seeClipboardEquals(text: string): Promise<any>;
|
|
5212
|
+
/**
|
|
5213
|
+
* Grabs the text content of the system clipboard and returns it to test.
|
|
5214
|
+
* Resumes test execution, so **should be used inside async function with `await`** operator.
|
|
5215
|
+
*
|
|
5216
|
+
* ```js
|
|
5217
|
+
* I.click('Copy to clipboard');
|
|
5218
|
+
* let url = await I.grabFromClipboard();
|
|
5219
|
+
* ```
|
|
5220
|
+
*
|
|
5221
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
5222
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
5223
|
+
* @returns the system clipboard contents.
|
|
5224
|
+
*/
|
|
5225
|
+
grabFromClipboard(): Promise<string>;
|
|
5226
|
+
/**
|
|
5227
|
+
* Clears the system clipboard.
|
|
5228
|
+
*
|
|
5229
|
+
* ```js
|
|
5230
|
+
* I.clearClipboard();
|
|
5231
|
+
* I.seeClipboardEquals('');
|
|
5232
|
+
* ```
|
|
5233
|
+
*/
|
|
5234
|
+
clearClipboard(): Promise<any>;
|
|
5087
5235
|
/**
|
|
5088
5236
|
* Executes a script on the page:
|
|
5089
5237
|
*
|
|
@@ -7165,6 +7313,55 @@ declare namespace CodeceptJS {
|
|
|
7165
7313
|
* @param [cookie = null] - (optional, `null` by default) cookie name
|
|
7166
7314
|
*/
|
|
7167
7315
|
clearCookie(cookie?: string): Promise<any>;
|
|
7316
|
+
/**
|
|
7317
|
+
* Checks that the system clipboard contains the given text.
|
|
7318
|
+
*
|
|
7319
|
+
* ```js
|
|
7320
|
+
* I.click('Copy to clipboard');
|
|
7321
|
+
* I.seeInClipboard('https://codecept.io');
|
|
7322
|
+
* ```
|
|
7323
|
+
*
|
|
7324
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
7325
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
7326
|
+
* @param text - value to check.
|
|
7327
|
+
*/
|
|
7328
|
+
seeInClipboard(text: string): Promise<any>;
|
|
7329
|
+
/**
|
|
7330
|
+
* Checks that the system clipboard is equal to the given text.
|
|
7331
|
+
*
|
|
7332
|
+
* ```js
|
|
7333
|
+
* I.click('Copy to clipboard');
|
|
7334
|
+
* I.seeClipboardEquals('https://codecept.io');
|
|
7335
|
+
* ```
|
|
7336
|
+
*
|
|
7337
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
7338
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
7339
|
+
* @param text - value to check.
|
|
7340
|
+
*/
|
|
7341
|
+
seeClipboardEquals(text: string): Promise<any>;
|
|
7342
|
+
/**
|
|
7343
|
+
* Grabs the text content of the system clipboard and returns it to test.
|
|
7344
|
+
* Resumes test execution, so **should be used inside async function with `await`** operator.
|
|
7345
|
+
*
|
|
7346
|
+
* ```js
|
|
7347
|
+
* I.click('Copy to clipboard');
|
|
7348
|
+
* let url = await I.grabFromClipboard();
|
|
7349
|
+
* ```
|
|
7350
|
+
*
|
|
7351
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
7352
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
7353
|
+
* @returns the system clipboard contents.
|
|
7354
|
+
*/
|
|
7355
|
+
grabFromClipboard(): Promise<string>;
|
|
7356
|
+
/**
|
|
7357
|
+
* Clears the system clipboard.
|
|
7358
|
+
*
|
|
7359
|
+
* ```js
|
|
7360
|
+
* I.clearClipboard();
|
|
7361
|
+
* I.seeClipboardEquals('');
|
|
7362
|
+
* ```
|
|
7363
|
+
*/
|
|
7364
|
+
clearClipboard(): Promise<any>;
|
|
7168
7365
|
/**
|
|
7169
7366
|
* If a function returns a Promise, tt will wait for its resolution.
|
|
7170
7367
|
*
|
|
@@ -9482,6 +9679,55 @@ declare namespace CodeceptJS {
|
|
|
9482
9679
|
* @param [name = null] - cookie name.
|
|
9483
9680
|
*/
|
|
9484
9681
|
grabCookie(name?: string): Promise<any>;
|
|
9682
|
+
/**
|
|
9683
|
+
* Checks that the system clipboard contains the given text.
|
|
9684
|
+
*
|
|
9685
|
+
* ```js
|
|
9686
|
+
* I.click('Copy to clipboard');
|
|
9687
|
+
* I.seeInClipboard('https://codecept.io');
|
|
9688
|
+
* ```
|
|
9689
|
+
*
|
|
9690
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
9691
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
9692
|
+
* @param text - value to check.
|
|
9693
|
+
*/
|
|
9694
|
+
seeInClipboard(text: string): Promise<any>;
|
|
9695
|
+
/**
|
|
9696
|
+
* Checks that the system clipboard is equal to the given text.
|
|
9697
|
+
*
|
|
9698
|
+
* ```js
|
|
9699
|
+
* I.click('Copy to clipboard');
|
|
9700
|
+
* I.seeClipboardEquals('https://codecept.io');
|
|
9701
|
+
* ```
|
|
9702
|
+
*
|
|
9703
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
9704
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
9705
|
+
* @param text - value to check.
|
|
9706
|
+
*/
|
|
9707
|
+
seeClipboardEquals(text: string): Promise<any>;
|
|
9708
|
+
/**
|
|
9709
|
+
* Grabs the text content of the system clipboard and returns it to test.
|
|
9710
|
+
* Resumes test execution, so **should be used inside async function with `await`** operator.
|
|
9711
|
+
*
|
|
9712
|
+
* ```js
|
|
9713
|
+
* I.click('Copy to clipboard');
|
|
9714
|
+
* let url = await I.grabFromClipboard();
|
|
9715
|
+
* ```
|
|
9716
|
+
*
|
|
9717
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`) and is supported
|
|
9718
|
+
* in Chromium-based browsers, where read access is granted automatically.
|
|
9719
|
+
* @returns the system clipboard contents.
|
|
9720
|
+
*/
|
|
9721
|
+
grabFromClipboard(): Promise<string>;
|
|
9722
|
+
/**
|
|
9723
|
+
* Clears the system clipboard.
|
|
9724
|
+
*
|
|
9725
|
+
* ```js
|
|
9726
|
+
* I.clearClipboard();
|
|
9727
|
+
* I.seeClipboardEquals('');
|
|
9728
|
+
* ```
|
|
9729
|
+
*/
|
|
9730
|
+
clearClipboard(): Promise<any>;
|
|
9485
9731
|
/**
|
|
9486
9732
|
* Waits for the specified cookie in the cookies.
|
|
9487
9733
|
*
|