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/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
| 🌐 Web | Playwright | [](https://github.com/codeceptjs/CodeceptJS/actions/workflows/playwright.yml) |
|
|
11
11
|
| 🌐 Web | Puppeteer | [](https://github.com/codeceptjs/CodeceptJS/actions/workflows/puppeteer.yml) |
|
|
12
12
|
| 🌐 Web | WebDriver | [](https://github.com/codeceptjs/CodeceptJS/actions/workflows/webdriver.yml) |
|
|
13
|
+
| 🌐 Web | Obscura | [](https://github.com/codeceptjs/CodeceptJS/actions/workflows/obscura.yml) |
|
|
13
14
|
| 📱 Mobile | Appium | [](https://github.com/codeceptjs/CodeceptJS/actions/workflows/appium_Android.yml) |
|
|
14
15
|
|
|
15
16
|
# CodeceptJS [](https://stand-with-ukraine.pp.ua)
|
|
@@ -42,6 +43,7 @@ CodeceptJS uses **Helper** modules to provide actions to `I` object. Currently,
|
|
|
42
43
|
- [**Playwright**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Playwright.md) - is a Node library to automate the Chromium, WebKit and Firefox browsers with a single API.
|
|
43
44
|
- [**Puppeteer**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Puppeteer.md) - uses Google Chrome's Puppeteer for fast headless testing.
|
|
44
45
|
- [**WebDriver**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/WebDriver.md) - uses [webdriverio](http://webdriver.io/) to run tests via WebDriver or Devtools protocol.
|
|
46
|
+
- [**Obscura**](https://codecept.io/helpers/Obscura) - drives the lightweight Obscura browser through Chrome DevTools Protocol. See [Alternative Browser Engines](https://codecept.io/alternative-browsers).
|
|
45
47
|
- [**Appium**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Appium.md) - for **mobile testing** with Appium
|
|
46
48
|
- [**Detox**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Detox.md) - This is a wrapper on top of Detox library, aimed to unify testing experience for CodeceptJS framework. Detox provides a grey box testing for mobile applications, playing especially well for React Native apps.
|
|
47
49
|
|
|
@@ -102,7 +104,7 @@ Later you can even automagically update Type Definitions to include your own cus
|
|
|
102
104
|
|
|
103
105
|
Note:
|
|
104
106
|
|
|
105
|
-
- CodeceptJS requires Node.js
|
|
107
|
+
- CodeceptJS 4.2 requires Node.js `22.12.0` or later.
|
|
106
108
|
|
|
107
109
|
## Usage
|
|
108
110
|
|
|
@@ -5,6 +5,10 @@ title: Alternative Browser Engines
|
|
|
5
5
|
|
|
6
6
|
# Alternative Browser Engines
|
|
7
7
|
|
|
8
|
+
::: warning Experimental
|
|
9
|
+
The `CDPBrowser`, `Obscura`, and `Kitesurf` helpers are experimental in CodeceptJS 4.2. Pin browser versions in CI and retain Playwright or WebDriver coverage for compatibility-critical tests.
|
|
10
|
+
:::
|
|
11
|
+
|
|
8
12
|
Playwright and Puppeteer drive full Chromium — the most accurate way to test what users see.
|
|
9
13
|
But a new class of lightweight, agent-era browsers has appeared, and CodeceptJS can drive them
|
|
10
14
|
through the `CDPBrowser` helper family:
|
|
@@ -12,8 +16,7 @@ through the `CDPBrowser` helper family:
|
|
|
12
16
|
- **[Obscura](https://github.com/h4ckf0r0day/obscura)** — an open-source Rust browser with a real
|
|
13
17
|
V8 engine. From v0.2.0, the default release build also renders — real layout, computed styles,
|
|
14
18
|
and screenshots — with `-no-render` builds still available for pure-speed, nothing-painted
|
|
15
|
-
scraping mode.
|
|
16
|
-
milliseconds.
|
|
19
|
+
scraping mode. Release archives are available for Linux, macOS, and Windows.
|
|
17
20
|
- **[Kitesurf](https://blog.cloudflare.com/kitesurf/)** — Cloudflare's browser that runs in V8
|
|
18
21
|
isolates on Cloudflare Workers, with a real layout and rendering pipeline. Cloud-only,
|
|
19
22
|
free in beta, planned to be open-sourced.
|
|
@@ -24,10 +27,9 @@ on navigation races.
|
|
|
24
27
|
|
|
25
28
|
## When are they better than Playwright?
|
|
26
29
|
|
|
27
|
-
**Smoke suites where
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
minutes into seconds.
|
|
30
|
+
**Smoke suites where startup and execution time matter.** Obscura is distributed as a standalone
|
|
31
|
+
binary and is designed for lightweight browser automation. Benchmark it against your own pages and
|
|
32
|
+
CI environment before choosing it for a PR gate.
|
|
31
33
|
|
|
32
34
|
**Massive parallel scale.** Kitesurf sessions are Cloudflare Workers — they spawn in about a
|
|
33
35
|
second, cost nothing while idle, and there is no practical ceiling on how many you run at once.
|
|
@@ -57,9 +59,8 @@ app's real JavaScript in real V8; it only skips painting. For API-adjacent flows
|
|
|
57
59
|
**Constrained environments.** ARM CI runners, thin containers, air-gapped machines:
|
|
58
60
|
a static binary with no system dependencies goes where Chromium will not.
|
|
59
61
|
|
|
60
|
-
**
|
|
61
|
-
|
|
62
|
-
headless Chromium.
|
|
62
|
+
**Optional stealth builds.** Obscura publishes separate `-stealth` archives. Treat their behaviour
|
|
63
|
+
as an Obscura capability rather than a browser-compatibility guarantee from CodeceptJS.
|
|
63
64
|
|
|
64
65
|
## When to stay with Playwright
|
|
65
66
|
|
|
@@ -77,6 +78,10 @@ headless Chromium.
|
|
|
77
78
|
|
|
78
79
|
## Configuration
|
|
79
80
|
|
|
81
|
+
CodeceptJS 4.2 is tested in CI with Obscura 0.2.2. Obscura 0.2.x is recommended; 0.1.x and
|
|
82
|
+
`-no-render` builds operate without layout, visibility assertions, or screenshots. See
|
|
83
|
+
[Installation](/installation#obscura-experimental) for platform-specific archive names.
|
|
84
|
+
|
|
80
85
|
helpers: {
|
|
81
86
|
Obscura: {
|
|
82
87
|
url: 'http://localhost:3000',
|
|
@@ -144,7 +149,7 @@ process — there is nothing to start by hand in the common case:
|
|
|
144
149
|
| Screenshots | yes | yes (v0.2.0+ default builds); no on `-no-render`/v0.1.x | yes |
|
|
145
150
|
| Visibility assertions | yes | yes (v0.2.0+ default builds); no, DOM-presence only, on `-no-render`/v0.1.x | yes |
|
|
146
151
|
| Screencast / video (`screencast` plugin) | yes — WebM via `page.screencast`, with caption burn-in | yes — APNG via CDP `Page.startScreencast`, assembled in-process (v0.2.0+ default builds; verified PNG frames on the live server); no caption burn-in | untested |
|
|
147
|
-
| Startup
|
|
152
|
+
| Startup model | local browser process | standalone local binary | remote cloud session |
|
|
148
153
|
| Parallel scale | machine-bound | machine-bound (light) | near-unlimited (cloud) |
|
|
149
154
|
| Where it runs | local/grid | local | Cloudflare only |
|
|
150
155
|
| License / cost | open source | Apache-2.0 | proprietary, free beta |
|
|
@@ -9,7 +9,7 @@ CodeceptJS runs in any CI that can install Node.js. This page covers the setup,
|
|
|
9
9
|
|
|
10
10
|
## Setup
|
|
11
11
|
|
|
12
|
-
- **Node.js** — install it on the runner (`actions/setup-node`, the `node:
|
|
12
|
+
- **Node.js 22.12 or newer** — install it on the runner (`actions/setup-node`, the `node:22` image, `NodeTool@0` on Azure). Examples below use Node 22.
|
|
13
13
|
- **Headless** — `codecept.conf.js` must contain `setHeadlessWhen(process.env.HEADLESS || process.env.CI)`. `codeceptjs init` adds it; since CI sets `CI=true`, the suite runs headless automatically.
|
|
14
14
|
|
|
15
15
|
```js
|
|
@@ -61,7 +61,7 @@ Use [`@testomatio/reporter`](https://github.com/testomatio/reporter). It ships p
|
|
|
61
61
|
|
|
62
62
|
## CI examples
|
|
63
63
|
|
|
64
|
-
Each example uses Playwright by default; a WebDriver variant follows where it differs. WebdriverIO 9 downloads its own browser and driver, so the WebDriver variants run on a plain `node:
|
|
64
|
+
Each example uses Playwright by default; a WebDriver variant follows where it differs. WebdriverIO 9 downloads its own browser and driver, so the WebDriver variants run on a plain `node:22` image with no Selenium service and no browser-install step. For Playwright, a `node:22` base image plus `npx playwright install --with-deps` keeps these configs free of version pins.
|
|
65
65
|
|
|
66
66
|
### GitHub Actions — Playwright
|
|
67
67
|
|
|
@@ -85,7 +85,7 @@ jobs:
|
|
|
85
85
|
- uses: actions/checkout@v4
|
|
86
86
|
- uses: actions/setup-node@v4
|
|
87
87
|
with:
|
|
88
|
-
node-version:
|
|
88
|
+
node-version: 22
|
|
89
89
|
cache: npm
|
|
90
90
|
- run: npm ci
|
|
91
91
|
- run: npx playwright install --with-deps chromium
|
|
@@ -115,7 +115,7 @@ jobs:
|
|
|
115
115
|
- uses: actions/checkout@v4
|
|
116
116
|
- uses: actions/setup-node@v4
|
|
117
117
|
with:
|
|
118
|
-
node-version:
|
|
118
|
+
node-version: 22
|
|
119
119
|
- run: npm ci
|
|
120
120
|
- run: npx codeceptjs check
|
|
121
121
|
- run: npx codeceptjs run-workers 2 --by pool
|
|
@@ -142,7 +142,7 @@ jobs:
|
|
|
142
142
|
- uses: actions/checkout@v4
|
|
143
143
|
- uses: actions/setup-node@v4
|
|
144
144
|
with:
|
|
145
|
-
node-version:
|
|
145
|
+
node-version: 22
|
|
146
146
|
- run: npm ci
|
|
147
147
|
- run: npx playwright install --with-deps chromium
|
|
148
148
|
- run: npx codeceptjs check
|
|
@@ -173,7 +173,7 @@ jobs:
|
|
|
173
173
|
- uses: actions/checkout@v4
|
|
174
174
|
- uses: actions/setup-node@v4
|
|
175
175
|
with:
|
|
176
|
-
node-version:
|
|
176
|
+
node-version: 22
|
|
177
177
|
- run: npm ci
|
|
178
178
|
- run: npx playwright install --with-deps
|
|
179
179
|
- run: npx codeceptjs check
|
|
@@ -194,7 +194,7 @@ stages: [test]
|
|
|
194
194
|
|
|
195
195
|
playwright:
|
|
196
196
|
stage: test
|
|
197
|
-
image: node:
|
|
197
|
+
image: node:22
|
|
198
198
|
variables:
|
|
199
199
|
FORCE_COLOR: "1"
|
|
200
200
|
parallel: 4
|
|
@@ -211,7 +211,7 @@ playwright:
|
|
|
211
211
|
|
|
212
212
|
webdriver:
|
|
213
213
|
stage: test
|
|
214
|
-
image: node:
|
|
214
|
+
image: node:22 # WebdriverIO 9 downloads its own browser and driver
|
|
215
215
|
script:
|
|
216
216
|
- npm ci
|
|
217
217
|
- npx codeceptjs check
|
|
@@ -228,7 +228,7 @@ webdriver:
|
|
|
228
228
|
`bitbucket-pipelines.yml`:
|
|
229
229
|
|
|
230
230
|
```yaml
|
|
231
|
-
image: node:
|
|
231
|
+
image: node:22
|
|
232
232
|
|
|
233
233
|
definitions:
|
|
234
234
|
caches:
|
|
@@ -260,7 +260,7 @@ pipelines:
|
|
|
260
260
|
For WebDriver, no Selenium service or browser image is needed — WebdriverIO 9 downloads its own browser and driver:
|
|
261
261
|
|
|
262
262
|
```yaml
|
|
263
|
-
image: node:
|
|
263
|
+
image: node:22
|
|
264
264
|
|
|
265
265
|
pipelines:
|
|
266
266
|
default:
|
|
@@ -280,7 +280,7 @@ pipelines:
|
|
|
280
280
|
pipeline {
|
|
281
281
|
agent {
|
|
282
282
|
docker {
|
|
283
|
-
image 'node:
|
|
283
|
+
image 'node:22'
|
|
284
284
|
args '-u root'
|
|
285
285
|
}
|
|
286
286
|
}
|
|
@@ -311,7 +311,7 @@ pipeline {
|
|
|
311
311
|
}
|
|
312
312
|
```
|
|
313
313
|
|
|
314
|
-
For WebDriver, keep the same `node:
|
|
314
|
+
For WebDriver, keep the same `node:22` agent — WebdriverIO 9 downloads its own browser and driver, so no Selenium container is needed:
|
|
315
315
|
|
|
316
316
|
```groovy
|
|
317
317
|
stage('Test') {
|
|
@@ -332,7 +332,7 @@ version: 2.1
|
|
|
332
332
|
jobs:
|
|
333
333
|
test:
|
|
334
334
|
docker:
|
|
335
|
-
- image: cimg/node:
|
|
335
|
+
- image: cimg/node:22.14-browsers
|
|
336
336
|
parallelism: 4
|
|
337
337
|
steps:
|
|
338
338
|
- checkout
|
|
@@ -350,7 +350,7 @@ jobs:
|
|
|
350
350
|
webdriver:
|
|
351
351
|
docker:
|
|
352
352
|
# WebdriverIO 9 downloads its own browser and driver
|
|
353
|
-
- image: cimg/node:
|
|
353
|
+
- image: cimg/node:22.14
|
|
354
354
|
steps:
|
|
355
355
|
- checkout
|
|
356
356
|
- run: npm ci
|
package/docs/helpers/Obscura.md
CHANGED
|
@@ -22,6 +22,17 @@ This helper is a thin `CDPBrowser` subclass: it changes nothing about how locati
|
|
|
22
22
|
elements works, it only pins the config presets Obscura requires and manages the `obscura serve`
|
|
23
23
|
process lifecycle, the same way Playwright manages its own browser process.
|
|
24
24
|
|
|
25
|
+
> Obscura support is experimental in CodeceptJS 4.2. Pin the browser version in CI and keep a
|
|
26
|
+
> Playwright/WebDriver job for browser-compatibility coverage.
|
|
27
|
+
|
|
28
|
+
## Compatibility
|
|
29
|
+
|
|
30
|
+
| CodeceptJS | Recommended Obscura | Notes |
|
|
31
|
+
| ---------- | -------------------- | --------------------------------------------------------------- |
|
|
32
|
+
| 4.2.x | 0.2.2 | Version used by the CodeceptJS Obscura CI workflow |
|
|
33
|
+
| 4.2.x | 0.2.x | Supported; capabilities are detected at runtime |
|
|
34
|
+
| 4.2.x | 0.1.x / `-no-render` | DOM-only mode; no layout, visibility assertions, or screenshots |
|
|
35
|
+
|
|
25
36
|
## Modes
|
|
26
37
|
|
|
27
38
|
* **ATTACH** — `endpoint` is set explicitly in the config. The helper only connects to it; it
|
|
@@ -39,8 +50,20 @@ process lifecycle, the same way Playwright manages its own browser process.
|
|
|
39
50
|
|
|
40
51
|
## Install
|
|
41
52
|
|
|
42
|
-
Download a release
|
|
43
|
-
|
|
53
|
+
Download a release archive from [Obscura releases][2].
|
|
54
|
+
CodeceptJS 4.2 is tested with Obscura 0.2.2. Rendering archives are available for:
|
|
55
|
+
|
|
56
|
+
| platform | archive |
|
|
57
|
+
| ------------------- | ------------------------------ |
|
|
58
|
+
| Linux x64 | `obscura-x86_64-linux.tar.gz` |
|
|
59
|
+
| Linux ARM64 | `obscura-aarch64-linux.tar.gz` |
|
|
60
|
+
| macOS Intel | `obscura-x86_64-macos.tar.gz` |
|
|
61
|
+
| macOS Apple Silicon | `obscura-aarch64-macos.tar.gz` |
|
|
62
|
+
| Windows x64 | `obscura-x86_64-windows.zip` |
|
|
63
|
+
|
|
64
|
+
Extract the archive and put `obscura` (`obscura.exe` on Windows) on your `PATH`, or point
|
|
65
|
+
`binaryPath`/`OBSCURA_PATH` at it. The helper then launches and tears it down automatically.
|
|
66
|
+
For example, on Linux x64:
|
|
44
67
|
|
|
45
68
|
```sh
|
|
46
69
|
curl -sL https://github.com/h4ckf0r0day/obscura/releases/download/v0.2.2/obscura-x86_64-linux.tar.gz | tar xz
|
|
@@ -84,19 +107,19 @@ Set them explicitly in your own config to skip probing or to force a mode.
|
|
|
84
107
|
This helper should be configured in codecept.conf.js. It accepts everything `CDPBrowser`
|
|
85
108
|
accepts (see its config table), plus:
|
|
86
109
|
|
|
87
|
-
Type: [object][
|
|
110
|
+
Type: [object][7]
|
|
88
111
|
|
|
89
112
|
### Properties
|
|
90
113
|
|
|
91
|
-
* `endpoint` **[string][
|
|
114
|
+
* `endpoint` **[string][5]?** explicit CDP endpoint. Setting this switches the helper to ATTACH
|
|
92
115
|
mode: it only connects, and never spawns or kills a process, no matter what else is configured.
|
|
93
116
|
Leave it unset for SELF-MANAGED mode (see below).
|
|
94
|
-
* `binaryPath` **[string][
|
|
117
|
+
* `binaryPath` **[string][5]?** path to the `obscura` executable, used in SELF-MANAGED mode
|
|
95
118
|
(`endpoint` unset). Checked before `OBSCURA_PATH` and `PATH`.
|
|
96
|
-
* `port` **[number][
|
|
119
|
+
* `port` **[number][4]?** port `obscura serve` listens on, in SELF-MANAGED mode. When unset, a
|
|
97
120
|
free port is picked automatically, which is what makes `run-workers` collision-free — every
|
|
98
121
|
worker gets its own instance on its own port with zero config.
|
|
99
|
-
* `serverStartTimeout` **[number][
|
|
122
|
+
* `serverStartTimeout` **[number][4]?** milliseconds to wait for a spawned `obscura serve`
|
|
100
123
|
to answer `/json/version` before `_connect` gives up.
|
|
101
124
|
|
|
102
125
|
|
|
@@ -150,7 +173,7 @@ Picks a free TCP port on 127.0.0.1 by briefly listening on port 0 and reading ba
|
|
|
150
173
|
port. Used as the SELF-LAUNCH default when `options.port` isn't explicitly set, so multiple
|
|
151
174
|
`run-workers` workers never collide on the same port.
|
|
152
175
|
|
|
153
|
-
Returns **[Promise][
|
|
176
|
+
Returns **[Promise][3]<[number][4]>** a free port.
|
|
154
177
|
|
|
155
178
|
### _finishTest
|
|
156
179
|
|
|
@@ -170,9 +193,9 @@ Probes a `/json/version`-style URL with a short timeout, used for the COURTESY-A
|
|
|
170
193
|
|
|
171
194
|
#### Parameters
|
|
172
195
|
|
|
173
|
-
* `url` **[string][
|
|
196
|
+
* `url` **[string][5]** 
|
|
174
197
|
|
|
175
|
-
Returns **[Promise][
|
|
198
|
+
Returns **[Promise][3]<[boolean][6]>** true if the URL answered.
|
|
176
199
|
|
|
177
200
|
### _resolveBinary
|
|
178
201
|
|
|
@@ -181,7 +204,7 @@ Resolves the `obscura` binary to spawn, in priority order: `options.binaryPath`,
|
|
|
181
204
|
directories itself instead of shelling out to `which`, which does not exist on Windows: on
|
|
182
205
|
Windows every `PATHEXT` suffix is tried, so an `obscura.exe` on `PATH` is found too.
|
|
183
206
|
|
|
184
|
-
Returns **([string][
|
|
207
|
+
Returns **([string][5] | null)** an absolute or relative path to the binary, or null if none resolved.
|
|
185
208
|
|
|
186
209
|
### _resolveSelfManaged
|
|
187
210
|
|
|
@@ -200,12 +223,14 @@ is paid once per run and counts directly toward real-world startup latency.
|
|
|
200
223
|
|
|
201
224
|
[1]: https://github.com/h4ckf0r0day/obscura
|
|
202
225
|
|
|
203
|
-
[2]: https://
|
|
226
|
+
[2]: https://github.com/h4ckf0r0day/obscura/releases
|
|
227
|
+
|
|
228
|
+
[3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
|
204
229
|
|
|
205
|
-
[
|
|
230
|
+
[4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
|
|
206
231
|
|
|
207
|
-
[
|
|
232
|
+
[5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
|
|
208
233
|
|
|
209
|
-
[
|
|
234
|
+
[6]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
|
210
235
|
|
|
211
|
-
[
|
|
236
|
+
[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
|
package/docs/installation.md
CHANGED
|
@@ -7,6 +7,12 @@ title: Installation
|
|
|
7
7
|
|
|
8
8
|
For the quickest start (CodeceptJS + Playwright) follow the [Quickstart](/quickstart). This page covers every browser, mobile, and API helper and what each one needs installed.
|
|
9
9
|
|
|
10
|
+
CodeceptJS 4.2 requires **Node.js 22.12 or newer**. Check your installed version before continuing:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
node --version
|
|
14
|
+
```
|
|
15
|
+
|
|
10
16
|
## Set up a project
|
|
11
17
|
|
|
12
18
|
```sh
|
|
@@ -64,6 +70,35 @@ WebdriverIO 9 downloads and starts the matching driver automatically — no Sele
|
|
|
64
70
|
|
|
65
71
|
To run against a cloud grid (Sauce Labs, BrowserStack, LambdaTest, and so on) instead, set the grid's `host`, `port`, `user`, and `key` (or `protocol` / `path`) in the helper config. For running this on CI, see [Continuous Integration](/continuous-integration).
|
|
66
72
|
|
|
73
|
+
## Obscura (experimental)
|
|
74
|
+
|
|
75
|
+
Obscura is a lightweight browser driven through Chrome DevTools Protocol. CodeceptJS 4.2 is tested with Obscura 0.2.2. Obscura 0.2.x is the recommended version; older 0.1.x and `-no-render` builds have no layout, visibility assertions, or screenshots.
|
|
76
|
+
|
|
77
|
+
Download the archive for your platform from the [Obscura releases](https://github.com/h4ckf0r0day/obscura/releases):
|
|
78
|
+
|
|
79
|
+
| Platform | Rendering archive |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| Linux x64 | `obscura-x86_64-linux.tar.gz` |
|
|
82
|
+
| Linux ARM64 | `obscura-aarch64-linux.tar.gz` |
|
|
83
|
+
| macOS Intel | `obscura-x86_64-macos.tar.gz` |
|
|
84
|
+
| macOS Apple Silicon | `obscura-aarch64-macos.tar.gz` |
|
|
85
|
+
| Windows x64 | `obscura-x86_64-windows.zip` |
|
|
86
|
+
|
|
87
|
+
Extract the archive and either put `obscura` (`obscura.exe` on Windows) on `PATH`, set `OBSCURA_PATH`, or configure `binaryPath`. The helper then starts and stops `obscura serve` automatically:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
export const config = {
|
|
91
|
+
helpers: {
|
|
92
|
+
Obscura: {
|
|
93
|
+
url: 'http://localhost:3000',
|
|
94
|
+
// binaryPath: '/absolute/path/to/obscura', // optional
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
See [Alternative Browser Engines](/alternative-browsers) for connection modes and limitations, and the [Obscura helper reference](/helpers/Obscura) for every option.
|
|
101
|
+
|
|
67
102
|
## Appium (mobile)
|
|
68
103
|
|
|
69
104
|
Native iOS and Android testing. Appium speaks the WebDriver protocol, so CodeceptJS drives it through `webdriverio`:
|
package/docs/mcp.md
CHANGED
|
@@ -441,7 +441,7 @@ Storage capture is **enabled** for `run_code`, `snapshot`, `run_step_by_step` fa
|
|
|
441
441
|
|
|
442
442
|
### Server doesn't start
|
|
443
443
|
|
|
444
|
-
- Node
|
|
444
|
+
- Node 22.12+ is required by CodeceptJS 4.2.
|
|
445
445
|
- Verify the path / `npx` resolution in your client config.
|
|
446
446
|
|
|
447
447
|
### Config not found
|
package/docs/migration-4.md
CHANGED
|
@@ -35,7 +35,7 @@ The rest of this guide documents every change the skill makes — read it if you
|
|
|
35
35
|
|
|
36
36
|
## 1. Update Node and Package
|
|
37
37
|
|
|
38
|
-
CodeceptJS 4.
|
|
38
|
+
CodeceptJS 4.2 requires Node 22.12 or newer. This matches the minimum supported version of its current runtime dependencies. Upgrade Node before installing CodeceptJS 4.2.
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
41
|
npm install codeceptjs@4
|
|
@@ -766,4 +766,4 @@ You don't need these to upgrade, but they unlock new workflows:
|
|
|
766
766
|
4. TypeScript users: run with `tsx` installed and confirm error stack traces point at `.ts` files.
|
|
767
767
|
5. If you removed `autoLogin`: confirm sessions restore under the `auth` plugin.
|
|
768
768
|
6. If you used `tryTo` / `retryTo` / `eachElement` plugins: grep your tests for the old globals and switch to subpath imports.
|
|
769
|
-
7. CI: bump the Node version to
|
|
769
|
+
7. CI: bump the Node version to 22.12+.
|
package/docs/parallel.md
CHANGED
package/lib/helper/Appium.js
CHANGED
|
@@ -1534,6 +1534,29 @@ class Appium extends Webdriver {
|
|
|
1534
1534
|
return this.browser.closeApp()
|
|
1535
1535
|
}
|
|
1536
1536
|
|
|
1537
|
+
/**
|
|
1538
|
+
* {{> clearClipboard }}
|
|
1539
|
+
*
|
|
1540
|
+
* Appium: support both Android and iOS
|
|
1541
|
+
*/
|
|
1542
|
+
async clearClipboard() {
|
|
1543
|
+
if (typeof this.browser.setClipboard !== 'function') return super.clearClipboard()
|
|
1544
|
+
return this.browser.setClipboard('', 'plaintext')
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
/**
|
|
1548
|
+
* {{> grabFromClipboard }}
|
|
1549
|
+
*
|
|
1550
|
+
* Appium: support both Android and iOS
|
|
1551
|
+
*/
|
|
1552
|
+
async grabFromClipboard() {
|
|
1553
|
+
if (typeof this.browser.getClipboard !== 'function') return super.grabFromClipboard()
|
|
1554
|
+
const encoded = await this.browser.getClipboard('plaintext')
|
|
1555
|
+
const clipboard = Buffer.from(encoded || '', 'base64').toString('utf8')
|
|
1556
|
+
this.debugSection('Clipboard', clipboard)
|
|
1557
|
+
return clipboard
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1537
1560
|
/**
|
|
1538
1561
|
* {{> appendField }}
|
|
1539
1562
|
*
|
package/lib/helper/CDPBrowser.js
CHANGED
|
@@ -18,6 +18,7 @@ import { isColorProperty, convertColorToRGBA } from '../colorUtils.js'
|
|
|
18
18
|
import WebElement from '../element/WebElement.js'
|
|
19
19
|
import CDPElementHandle from './extras/CDPElementHandle.js'
|
|
20
20
|
import { checkFocusBeforeType, checkFocusBeforePressKey } from './extras/focusCheck.js'
|
|
21
|
+
import { CLIPBOARD_READ_TIMEOUT_MS, readClipboardScript, writeClipboardScript, clipboardExpression } from './extras/clipboard.js'
|
|
21
22
|
import { dontSeeTraffic, seeTraffic, grabRecordedNetworkTraffics, flushNetworkTraffics } from './network/actions.js'
|
|
22
23
|
import { assembleApng, isPng } from './extras/apngAssembler.js'
|
|
23
24
|
|
|
@@ -1940,6 +1941,89 @@ class CDPBrowser extends Helper {
|
|
|
1940
1941
|
}
|
|
1941
1942
|
}
|
|
1942
1943
|
|
|
1944
|
+
/**
|
|
1945
|
+
* Checks that the system clipboard contains the given text.
|
|
1946
|
+
*
|
|
1947
|
+
* ```js
|
|
1948
|
+
* I.click('Copy to clipboard');
|
|
1949
|
+
* I.seeInClipboard('https://codecept.io');
|
|
1950
|
+
* ```
|
|
1951
|
+
*
|
|
1952
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`).
|
|
1953
|
+
*
|
|
1954
|
+
* @param {string} text value to check.
|
|
1955
|
+
* @returns {Promise<void>}
|
|
1956
|
+
*/
|
|
1957
|
+
async seeInClipboard(text) {
|
|
1958
|
+
const clipboard = await this.grabFromClipboard()
|
|
1959
|
+
return stringIncludes('clipboard').assert(text, clipboard)
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
/**
|
|
1963
|
+
* Checks that the system clipboard is equal to the given text.
|
|
1964
|
+
*
|
|
1965
|
+
* ```js
|
|
1966
|
+
* I.click('Copy to clipboard');
|
|
1967
|
+
* I.seeClipboardEquals('https://codecept.io');
|
|
1968
|
+
* ```
|
|
1969
|
+
*
|
|
1970
|
+
* Reading the clipboard requires a secure context (`https` or `localhost`).
|
|
1971
|
+
*
|
|
1972
|
+
* @param {string} text value to check.
|
|
1973
|
+
* @returns {Promise<void>}
|
|
1974
|
+
*/
|
|
1975
|
+
async seeClipboardEquals(text) {
|
|
1976
|
+
const clipboard = await this.grabFromClipboard()
|
|
1977
|
+
return equals('clipboard').assert(clipboard, text)
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
/**
|
|
1981
|
+
* Clears the system clipboard.
|
|
1982
|
+
*
|
|
1983
|
+
* ```js
|
|
1984
|
+
* I.clearClipboard();
|
|
1985
|
+
* I.seeClipboardEquals('');
|
|
1986
|
+
* ```
|
|
1987
|
+
*
|
|
1988
|
+
* @returns {Promise<void>}
|
|
1989
|
+
*/
|
|
1990
|
+
async clearClipboard() {
|
|
1991
|
+
await this._grantClipboardAccess()
|
|
1992
|
+
await this._evaluate(clipboardExpression(writeClipboardScript, ''))
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
/**
|
|
1996
|
+
* Grabs the text content of the system clipboard.
|
|
1997
|
+
* Resumes test execution, so **should be used inside async function with `await`** operator.
|
|
1998
|
+
*
|
|
1999
|
+
* ```js
|
|
2000
|
+
* I.click('Copy to clipboard');
|
|
2001
|
+
* const url = await I.grabFromClipboard();
|
|
2002
|
+
* ```
|
|
2003
|
+
*
|
|
2004
|
+
* @returns {Promise<string>} the system clipboard contents.
|
|
2005
|
+
*/
|
|
2006
|
+
async grabFromClipboard() {
|
|
2007
|
+
await this._grantClipboardAccess()
|
|
2008
|
+
const clipboard = await this._evaluate(clipboardExpression(readClipboardScript, CLIPBOARD_READ_TIMEOUT_MS))
|
|
2009
|
+
this.debugSection('Clipboard', clipboard)
|
|
2010
|
+
return clipboard
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
/**
|
|
2014
|
+
* Brings the current target to front and grants it clipboard read/write access, so
|
|
2015
|
+
* `navigator.clipboard` does not reject with a permission or focus error. Failures are ignored:
|
|
2016
|
+
* a browser without `Browser.grantPermissions` surfaces its own error from the read instead.
|
|
2017
|
+
*
|
|
2018
|
+
* @protected
|
|
2019
|
+
*/
|
|
2020
|
+
async _grantClipboardAccess() {
|
|
2021
|
+
await this.cdp.send('Page.bringToFront', {}, this.sessionId).catch(() => null)
|
|
2022
|
+
const origin = await this._evaluate('window.location.origin').catch(() => null)
|
|
2023
|
+
if (!origin || !origin.startsWith('http')) return
|
|
2024
|
+
await this.cdp.send('Browser.grantPermissions', { origin, permissions: ['clipboardReadWrite', 'clipboardSanitizedWrite'] }).catch(() => null)
|
|
2025
|
+
}
|
|
2026
|
+
|
|
1943
2027
|
/**
|
|
1944
2028
|
* Saves a screenshot to the output folder (set in codecept.conf.ts or codecept.conf.js).
|
|
1945
2029
|
* Filename is relative to the output folder.
|
package/lib/helper/Obscura.js
CHANGED
|
@@ -39,6 +39,17 @@ const config = {}
|
|
|
39
39
|
* elements works, it only pins the config presets Obscura requires and manages the `obscura serve`
|
|
40
40
|
* process lifecycle, the same way Playwright manages its own browser process.
|
|
41
41
|
*
|
|
42
|
+
* > Obscura support is experimental in CodeceptJS 4.2. Pin the browser version in CI and keep a
|
|
43
|
+
* > Playwright/WebDriver job for browser-compatibility coverage.
|
|
44
|
+
*
|
|
45
|
+
* ## Compatibility
|
|
46
|
+
*
|
|
47
|
+
* | CodeceptJS | Recommended Obscura | Notes |
|
|
48
|
+
* | --- | --- | --- |
|
|
49
|
+
* | 4.2.x | 0.2.2 | Version used by the CodeceptJS Obscura CI workflow |
|
|
50
|
+
* | 4.2.x | 0.2.x | Supported; capabilities are detected at runtime |
|
|
51
|
+
* | 4.2.x | 0.1.x / `-no-render` | DOM-only mode; no layout, visibility assertions, or screenshots |
|
|
52
|
+
*
|
|
42
53
|
* ## Modes
|
|
43
54
|
*
|
|
44
55
|
* - **ATTACH** — `endpoint` is set explicitly in the config. The helper only connects to it; it
|
|
@@ -56,8 +67,20 @@ const config = {}
|
|
|
56
67
|
*
|
|
57
68
|
* ## Install
|
|
58
69
|
*
|
|
59
|
-
* Download a release
|
|
60
|
-
*
|
|
70
|
+
* Download a release archive from [Obscura releases](https://github.com/h4ckf0r0day/obscura/releases).
|
|
71
|
+
* CodeceptJS 4.2 is tested with Obscura 0.2.2. Rendering archives are available for:
|
|
72
|
+
*
|
|
73
|
+
* | platform | archive |
|
|
74
|
+
* | --- | --- |
|
|
75
|
+
* | Linux x64 | `obscura-x86_64-linux.tar.gz` |
|
|
76
|
+
* | Linux ARM64 | `obscura-aarch64-linux.tar.gz` |
|
|
77
|
+
* | macOS Intel | `obscura-x86_64-macos.tar.gz` |
|
|
78
|
+
* | macOS Apple Silicon | `obscura-aarch64-macos.tar.gz` |
|
|
79
|
+
* | Windows x64 | `obscura-x86_64-windows.zip` |
|
|
80
|
+
*
|
|
81
|
+
* Extract the archive and put `obscura` (`obscura.exe` on Windows) on your `PATH`, or point
|
|
82
|
+
* `binaryPath`/`OBSCURA_PATH` at it. The helper then launches and tears it down automatically.
|
|
83
|
+
* For example, on Linux x64:
|
|
61
84
|
*
|
|
62
85
|
* ```sh
|
|
63
86
|
* curl -sL https://github.com/h4ckf0r0day/obscura/releases/download/v0.2.2/obscura-x86_64-linux.tar.gz | tar xz
|