Skip to content

Commit baa888c

Browse files
committed
feat: soft assertion
1 parent ff19db7 commit baa888c

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

lib/plugin/hopeThat.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
const recorder = require('../recorder')
2+
const { debug } = require('../output')
3+
4+
const defaultConfig = {
5+
registerGlobal: true,
6+
}
7+
8+
/**
9+
* Adds a global `hopeThat` function for soft assertions.
10+
*
11+
* Steps executed inside `hopeThat` will not fail the test when they fail;
12+
* instead, they will return `true` or `false`.
13+
*
14+
* Enable this plugin in `codecept.conf.js`:
15+
*
16+
* ```js
17+
* plugins: {
18+
* hopeThat: {
19+
* enabled: true
20+
* }
21+
* }
22+
* ```
23+
*
24+
* ### Usage
25+
*
26+
* Use `hopeThat` in your tests for conditional assertions:
27+
*
28+
* ```js
29+
* const result = await hopeThat(() => I.see('Welcome'));
30+
*
31+
* // If the text "Welcome" is on the page, result => true
32+
* // If the text "Welcome" is not on the page, result => false
33+
* ```
34+
*
35+
* This utility disables the `retryFailedStep` plugin for steps inside its block.
36+
*
37+
* #### Use Cases
38+
*
39+
* - Perform multiple conditional assertions in a test.
40+
* - Handle scenarios with A/B testing on a website.
41+
* - Handle unexpected elements, such as "Accept Cookie" banners.
42+
*
43+
* #### Examples
44+
*
45+
* ##### Multiple Conditional Assertions
46+
*
47+
* Add the assertion library:
48+
* ```js
49+
* const assert = require('assert');
50+
* ```
51+
*
52+
* Use `hopeThat` with assertions:
53+
* ```js
54+
* const result1 = await hopeThat(() => I.see('Hello, user'));
55+
* const result2 = await hopeThat(() => I.seeElement('.welcome'));
56+
* assert.ok(result1 && result2, 'Assertions were not successful');
57+
* ```
58+
*
59+
* ##### Optional Click
60+
*
61+
* ```js
62+
* I.amOnPage('/');
63+
* hopeThat(() => I.click('Agree', '.cookies'));
64+
* ```
65+
*
66+
* ### Configuration
67+
*
68+
* - `registerGlobal` (boolean, default: `true`) — Registers `hopeThat` globally.
69+
*
70+
* If `registerGlobal` is `false`, use `hopeThat` via the plugin:
71+
*
72+
* ```js
73+
* const hopeThat = codeceptjs.container.plugins('hopeThat');
74+
* ```
75+
*
76+
* @param {Object} config - Configuration object.
77+
* @param {boolean} [config.registerGlobal=true] - Whether to register `hopeThat` globally.
78+
* @returns {Function} hopeThat - The soft assertion function.
79+
*/
80+
module.exports = function (config) {
81+
config = Object.assign(defaultConfig, config)
82+
83+
if (config.registerGlobal) {
84+
global.hopeThat = hopeThat
85+
}
86+
return hopeThat
87+
}
88+
89+
function hopeThat(callback) {
90+
let result = false
91+
return recorder.add(
92+
'hopeThat',
93+
() => {
94+
recorder.session.start('hopeThat')
95+
process.env.HOPE_THAT = 'true'
96+
callback()
97+
recorder.add(() => {
98+
result = true
99+
recorder.session.restore('hopeThat')
100+
return result
101+
})
102+
recorder.session.catch(err => {
103+
result = false
104+
const msg = err.inspect ? err.inspect() : err.toString()
105+
debug(`Unsuccessful assertion > ${msg}`)
106+
recorder.session.restore('hopeThat')
107+
return result
108+
})
109+
return recorder.add(
110+
'result',
111+
() => {
112+
process.env.HOPE_THAT = undefined
113+
return result
114+
},
115+
true,
116+
false,
117+
)
118+
},
119+
false,
120+
false,
121+
)
122+
}

test/unit/plugin/hopeThat_test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
let expect
2+
import('chai').then(chai => {
3+
expect = chai.expect
4+
})
5+
const hopeThat = require('../../../lib/plugin/hopeThat')()
6+
const recorder = require('../../../lib/recorder')
7+
8+
describe('hopeThat plugin', () => {
9+
beforeEach(() => {
10+
recorder.start()
11+
})
12+
13+
it('should execute command on success', async () => {
14+
const ok = await hopeThat(() => recorder.add(() => 5))
15+
expect(true).is.equal(ok)
16+
return recorder.promise()
17+
})
18+
19+
it('should execute command on fail', async () => {
20+
const notOk = await hopeThat(() =>
21+
recorder.add(() => {
22+
throw new Error('Ups')
23+
}),
24+
)
25+
expect(false).is.equal(notOk)
26+
return recorder.promise()
27+
})
28+
})

0 commit comments

Comments
 (0)