Releases: codeceptjs/CodeceptJS
3.6.4
What's Changed
❤️ Thanks all to those who contributed to make this release! ❤️
🛩️ Features
- feat(rest): print curl (#4396) - by @kobenguyent
Config:
...
REST: {
...
printCurl: true,
...
}
...
› [CURL Request] curl --location --request POST https://httpbin.org/post -H ...
- feat(AI): Generate PageObject, added types, shell improvement (#4319) - by @DavertMik
- added
askForPageObject
method to generate PageObjects on the fly - improved AI types
- interactive shell improved to restore history
- added
🐛 Bug Fixes
- fix(heal): wrong priority (#4394) - by @kobenguyent
📖 Documentation
- AI docs improvements
Full Changelog: 3.6.3...3.6.4
3.6.3
What's Changed
❤️ Thanks all to those who contributed to make this release! ❤️
🛩️ Features
- feat(plugin): coverage with WebDriver - devtools (#4349) - by @kobenguyent
🐛 Bug Fixes
- fix(cli): stale process (#4367) - by @Horsty80 @kobenguyent
- fix(runner): screenshot error in beforeSuite/AfterSuite (#4385) - by @kobenguyent
- fix(cli): gherkin command init with TypeScript (#4366) - by @andonary
- fix(webApi): error message of dontSeeCookie (#4357) - by @a-stankevich
📖 Documentation
- fix(doc): Expect helper is not described correctly (#4370) - by @kobenguyent
- fix(docs): some strange characters (#4387) - by @kobenguyent
- fix: Puppeteer helper doc typo (#4369) - by @yoannfleurydev
New Contributors
- @yoannfleurydev made their first contribution in #4369
Full Changelog: 3.6.2...3.6.3
3.6.2
What's Changed
- fix(playwright): set the record video resolution by @kobenguyent in #4311
- chore: disable redundant ppt tests by @kobenguyent in #4312
- chore(deps-dev): bump playwright from 1.43.0 to 1.43.1 by @dependabot in #4301
- chore(deps): bump joi from 17.12.2 to 17.12.3 by @dependabot in #4299
- chore(deps): bump mocha from 10.3.0 to 10.4.0 by @dependabot in #4298
- chore(deps): bump pactum from 3.6.6 to 3.6.7 by @dependabot in #4316
- fix(docs): wrong method is mentioned by @kobenguyent in #4320
- feat: locate element with withClassAttr by @kobenguyent in #4321
- chore(deps-dev): bump electron from 28.2.1 to 30.0.1 by @dependabot in #4324
- chore(deps-dev): bump webdriverio from 8.35.1 to 8.36.1 by @dependabot in #4325
- chore(deps): bump joi from 17.12.3 to 17.13.0 by @dependabot in #4326
- Update README.md by @kobenguyent in #4329
- fix: wrong format docs by @kobenguyent in #4330
- chore(deps-dev): bump @wdio/utils from 8.33.1 to 8.36.1 by @dependabot in #4327
- feat(wd): screenshots for sessions by @kobenguyent in #4322
- fix: several issues of stepByStep report by @kobenguyent in #4331
- feat(REST): support httpAgent conf by @kobenguyent in #4328
- release 3.6.2 by @kobenguyent in #4332
Full Changelog: 3.6.1...3.6.2
3.6.1
Fixed regression in interactive pause.
3.6.0
3.6.0
🛩️ Features
- Introduced healers to improve stability of failed tests. Write functions that can perform actions to fix a failing test:
heal.addRecipe('reloadPageIfModalIsNotVisisble', {
steps: [
'click',
],
fn: async ({ error, step }) => {
// this function will be executed only if test failed with
// "model is not visible" message
if (error.message.include('modal is not visible')) return;
// we return a function that will refresh a page
// and tries to perform last step again
return async ({ I }) => {
I.reloadPage();
I.wait(1);
await step.run();
};
// if a function succeeds, test continues without an error
},
});
-
Breaking Change AI features refactored. Read updated AI guide:
- removed dependency on
openai
- added support for Azure OpenAI, Claude, Mistal, or any AI via custom request function
--ai
option added to explicitly enable AI features- heal plugin decoupled from AI to run custom heal recipes
- improved healing for async/await scenarios
- token limits added
- token calculation introduced
OpenAI
helper renamed toAI
- removed dependency on
-
feat(puppeteer): network traffic manipulation. See #4263 by @kobenguyent
startRecordingTraffic
grabRecordedNetworkTraffics
flushNetworkTraffics
stopRecordingTraffic
seeTraffic
dontSeeTraffic
-
feat(Puppeteer): recording WS messages. See #4264 by @kobenguyent
Recording WS messages:
I.startRecordingWebSocketMessages();
I.amOnPage('https://websocketstest.com/');
I.waitForText('Work for You!');
const wsMessages = I.grabWebSocketMessages();
expect(wsMessages.length).to.greaterThan(0);
flushing WS messages:
I.startRecordingWebSocketMessages();
I.amOnPage('https://websocketstest.com/');
I.waitForText('Work for You!');
I.flushWebSocketMessages();
const wsMessages = I.grabWebSocketMessages();
expect(wsMessages.length).to.equal(0);
Examples:
// recording traffics and verify the traffic
I.startRecordingTraffic();
I.amOnPage('https://codecept.io/');
I.seeTraffic({ name: 'traffics', url: 'https://codecept.io/img/companies/BC_LogoScreen_C.jpg' });
// check the traffic with advanced params
I.amOnPage('https://openai.com/blog/chatgpt');
I.startRecordingTraffic();
I.seeTraffic({
name: 'sentry event',
url: 'https://images.openai.com/blob/cf717bdb-0c8c-428a-b82b-3c3add87a600',
parameters: {
width: '1919',
height: '1138',
},
});
- Introduce the playwright locator:
_react
,_vue
,data-testid
attribute. See #4255 by @kobenguyent
Scenario('using playwright locator @Playwright', () => {
I.amOnPage('https://codecept.io/test-react-calculator/');
I.click('7');
I.click({ pw: '_react=t[name = "="]' });
I.seeElement({ pw: '_react=t[value = "7"]' });
I.click({ pw: '_react=t[name = "+"]' });
I.click({ pw: '_react=t[name = "3"]' });
I.click({ pw: '_react=t[name = "="]' });
I.seeElement({ pw: '_react=t[value = "10"]' });
});
Scenario('using playwright data-testid attribute @Playwright', () => {
I.amOnPage('/');
const webElements = await I.grabWebElements({ pw: '[data-testid="welcome"]' });
assert.equal(webElements[0]._selector, '[data-testid="welcome"] >> nth=0');
assert.equal(webElements.length, 1);
});
- feat(puppeteer): mockRoute support. See #4262 by @kobenguyent
Network requests & responses can be mocked and modified. Use mockRoute
which strictly follows Puppeteer's setRequestInterception API.
I.mockRoute('https://reqres.in/api/comments/1', request => {
request.respond({
status: 200,
headers: { 'Access-Control-Allow-Origin': '*' },
contentType: 'application/json',
body: '{"name": "this was mocked" }',
});
})
I.mockRoute('**/*.{png,jpg,jpeg}', route => route.abort());
// To disable mocking for a route call `stopMockingRoute`
// for previously mocked URL
I.stopMockingRoute('**/*.{png,jpg,jpeg}');
To master request intercepting use HTTPRequest object passed into mock request handler.
🐛 Bug Fixes
- Fixed double help message #4278 by @masiuchi
- waitNumberOfVisibleElements always failed when passing num as 0. See #4274 by @kobenguyent
New Contributors
Full Changelog: 3.5.15...3.6.0
3.5.15
3.5.15
❤️ Thanks all to those who contributed to make this release! ❤️
🛩️ Features
- feat: improve code coverage plugin (#4252) - by KobeNguyenT
We revamp the coverage plugin to make it easier to use
Once all the tests are completed, codecept
will create and store coverage in output/coverage
folder, as shown below.
Open index.html
in your browser to view the full interactive coverage report.
🐛 Bug Fixes
- fix: bump puppeteer to v22.x (#4249) - by KobeNguyenT
- fix: improve dry-run command (#4225) - by KobeNguyenT
dry-run command now supports test level grep.
Tests from /Users/t/Desktop/projects/codeceptjs-rest-demo:@jaja
GET tests -- /Users/t/Desktop/projects/codeceptjs-rest-demo/src/GET_test.ts -- 4 tests
☐ Verify getting a single user **[jaja](https://github.com/jaja)**
☐ Verify getting list of users **[jaja](https://github.com/jaja)**
PUT tests -- /Users/t/Desktop/projects/codeceptjs-rest-demo/src/PUT_test.ts -- 4 tests
☐ Verify creating new user **[Jaja](https://github.com/Jaja)**
Total: 2 suites | 3 tests
--- DRY MODE: No tests were executed ---
➜ codeceptjs-rest-demo git:(master) ✗ npx codeceptjs dry-run
Tests from /Users/t/Desktop/projects/codeceptjs-rest-demo:
DELETE tests -- /Users/t/Desktop/projects/codeceptjs-rest-demo/src/DELETE_test.ts -- 4 tests
☐ Verify deleting a user
GET tests -- /Users/t/Desktop/projects/codeceptjs-rest-demo/src/GET_test.ts -- 4 tests
☐ Verify a successful call
☐ Verify a not found call
☐ Verify getting a single user **[jaja](https://github.com/jaja)**
☐ Verify getting list of users **[jaja](https://github.com/jaja)**
POST tests -- /Users/tDesktop/projects/codeceptjs-rest-demo/src/POST_test.ts -- 4 tests
☐ Verify creating new user
☐ Verify uploading a file
PUT tests -- /Users/tDesktop/projects/codeceptjs-rest-demo/src/PUT_test.ts -- 4 tests
☐ Verify creating new user **[Jaja](https://github.com/Jaja)**
Total: 4 suites | 8 tests
--- DRY MODE: No tests were executed ---
- Several internal fixes and improvements for github workflows
Full Changelog: 3.5.14...3.5.15
3.5.14
3.5.13
3.5.13
❤️ Thanks all to those who contributed to make this release! ❤️
🛩️ Features
- feat: mock server helper (#4155) - by @kobenguyent
- feat(webdriver): network traffics manipulation (#4166) - by @kobenguyent
[Webdriver] Added commands to check network traffics - supported only with devtoolsProtocolstartRecordingTraffic
grabRecordedNetworkTraffics
flushNetworkTraffics
stopRecordingTraffic
seeTraffic
dontSeeTraffic
Examples:
// recording traffics and verify the traffic
I.startRecordingTraffic();
I.amOnPage('https://codecept.io/');
I.seeTraffic({ name: 'traffics', url: 'https://codecept.io/img/companies/BC_LogoScreen_C.jpg' });
// check the traffic with advanced params
I.amOnPage('https://openai.com/blog/chatgpt');
I.startRecordingTraffic();
I.seeTraffic({
name: 'sentry event',
url: 'https://images.openai.com/blob/cf717bdb-0c8c-428a-b82b-3c3add87a600',
parameters: {
width: '1919',
height: '1138',
},
});
- feat(webapi): add waitForCookie (#4169) - by @kobenguyent
Waits for the specified cookie in the cookies.
I.waitForCookie("token");
🐛 Bug Fixes
- fix(appium): update performSwipe with w3c protocol v2 (#4181) - by @MykaLev
- fix(webapi): selectOption method (#4157) - by @dyaroman
- fix: waitForText doesnt throw error when text doesnt exist (#4195) - by @kobenguyent
- fix: use this.options instead of this.config (#4186) - by @kobenguyent
- fix: config path without selenium (#4184) - by @kobenguyent
- fix: bring to front condition in _setPage (#4173) - by @kobenguyent
- fix: complicated locator (#4170) - by @kobenguyent
Adding of':nth-child'
into the array
const limitation = [':nth-of-type', ':first-of-type', ':last-of-type', ':nth-last-child', ':nth-last-of-type', ':checked', ':disabled', ':enabled', ':required', ':lang'];
fixes the issue. Then an old conversion way over css-to-xpath
is used.
📖 Documentation
- fix(docs): missing docs for codecept UI (#4175) - by @kobenguyent
- fix(docs): Appium documentation sidebar menu links (#4188) - by @mirao
🛩️ Several bugfixes and improvements for Codecept-UI
- Several internal improvements
- fix: title is not showing when visiting a test
- fix: handle erros nicely
New Contributors
Full Changelog: 3.5.12...3.5.13
3.5.12
3.5.12
❤️ Thanks all to those who contributed to make this release! ❤️
🛩️ Features
-
feat: upgrade wdio (#4123) - by @kobenguyent
🛩️ With the release of WebdriverIO version
v8.14.0
, and onwards, all driver management hassles are now a thing of the past 🙌. Read more here.
One of the significant advantages of this update is that you can now get rid of any driver services you previously had to manage, such as
wdio-chromedriver-service
,wdio-geckodriver-service
,wdio-edgedriver-service
,wdio-safaridriver-service
, and even@wdio/selenium-standalone-service
.
For those who require custom driver options, fear not; WebDriver Helper allows you to pass in driver options through custom WebDriver configuration.
If you have a custom grid, use a cloud service, or prefer to run your own driver, there's no need to worry since WebDriver Helper will only start a driver when there are no other connection information settings like hostname or port specified.
Example:
{
helpers: {
WebDriver : {
smartWait: 5000,
browser: "chrome",
restart: false,
windowSize: "maximize",
timeouts: {
"script": 60000,
"page load": 10000
}
}
}
}
Testing Chrome locally is now more convenient than ever. You can define a browser channel, and WebDriver Helper will take care of downloading the specified browser version for you.
For example:
{
helpers: {
WebDriver : {
smartWait: 5000,
browser: "chrome",
browserVersion: '116.0.5793.0', // or 'stable', 'beta', 'dev' or 'canary'
restart: false,
windowSize: "maximize",
timeouts: {
"script": 60000,
"page load": 10000
}
}
}
}
- feat: wdio with devtools protocol (#4105) - by @kobenguyent
Running with devtools protocol
{
helpers: {
WebDriver : {
url: "http://localhost",
browser: "chrome",
devtoolsProtocol: true,
desiredCapabilities: {
chromeOptions: {
args: [ "--headless", "--disable-gpu", "--no-sandbox" ]
}
}
}
}
}
Find an element with exact text
locate('button').withTextEquals('Add');
- feat: waitForNumberOfTabs (#4124) - by @kobenguyent
Waits for number of tabs.
I.waitForNumberOfTabs(2);
- feat: I.say would be added to Test.steps array (#4145) - by @kobenguyent
Currently I.say
is not added into the Test.steps
array. This PR aims to add this to steps array so that we could use it to print steps in ReportPortal for instance.
🐛 Bug Fixes
- fix: reduce the package size to 2MB (#4138) - by @kobenguyent
- fix(webapi): see attributes on elements (#4147) - by @kobenguyent
- fix: some assertion methods (#4144) - by @kobenguyent
Improve the error message for seeElement
, dontSeeElement
, seeElementInDOM
, dontSeeElementInDOM
The current error message doesn't really help when debugging issue also causes some problem described in #4140
Actual
expected visible elements '[ELEMENT]' to be empty
+ expected - actual
-[
- "ELEMENT"
-]
+[]
Updated
Error: Element "h1" is still visible
at seeElementError (lib/helper/errors/ElementAssertion.js:9:9)
at Playwright.dontSeeElement (lib/helper/Playwright.js:1472:7)
- fix: css to xpath backward compatibility (#4141) - by @kobenguyent
- css-to-xpath: old lib, which works perfectly unless you have hyphen in locator. (#3563)
- csstoxpath: new lib, to solve the issue locator with hyphen but also have some limitations
- fix: grabRecordedNetworkTraffics throws error when being called twice (#4143) - by @kobenguyent
- fix: missing steps of test when running with workers (#4127) - by @kobenguyent
Scenario('Verify getting list of users', async () => {
let res = await I.getUserPerPage(2);
res.data = []; // this line causes the issue
await I.expectEqual(res.data.data[0].id, 7);
});
at this time, res.data.data[0].id would throw undefined error and somehow the test is missing all its steps.
process.env.profile
is the string "undefined" instead of type undefined when no --profile is specified in the mode "run-multiple"
- fix: session doesn't respect the context options (#4111) - by @kobenguyent
Helpers: Playwright
Plugins: screenshotOnFail, tryTo, retryFailedStep, retryTo, eachElement
Repro --
[1] Starting recording promises
Timeouts:
› [Session] Starting singleton browser session
Reproduce issue
I am on page "https://example.com"
› [Browser:Error] Failed to load resource: the server responded with a status of 404 ()
› [New Context] {}
user1: I am on page "https://example.com"
user1: I execute script () => {
return { width: window.screen.width, height: window.screen.height };
}
sessionScreen is {"width":375,"height":667}
✔ OK in 1890ms
OK | 1 passed // 4s
-
fix(plugin): retryTo issue (#4117) - by @kobenguyent
-
fix(types): CustomLocator typing broken for custom strict locators (#4120) - by @kobenguyent
-
fix: wrong output for skipped tests - by @kobenguyent
-
fix: no retry failed step after tryto block (#4103) - by @kobenguyent
-
fix: deprecate some JSON Wire Protocol commands (#4104) - by @kobenguyent
deprecate some JSON Wire Protocol commands: grabGeoLocation
, setGeoLocation
- fix: cannot locate complicated locator (#4101) - by @kobenguyent
Locator issue due to the lib changes
The locator locate(".ps-menu-button").withText("Authoring").inside(".ps-submenu-root:nth-child(3)") is translated to
3.5.8: //*[contains(concat(' ', normalize-space(./@class), ' '), ' ps-menu-button ')][contains(., 'Authoring')][ancestor::*[(contains(concat(' ', normalize-space(./@class), ' '), ' ps-submenu-root ') and count(preceding-sibling::*) = 2)]] and works well
3.5.11: //*[contains(@class, "ps-menu-button")][contains(., 'Authoring')][ancestor::*[3][contains(@class, "ps-submenu-root")]] and doesn't work (no clickable element found). Even if you test it in browser inspector, it doesn't work.
Full Changelog: 3.5.11...3.5.12
3.5.11
3.5.11
❤️ Thanks all to those who contributed to make this release! ❤️
🛩️ Features
- feat: other locators from playwright (#4090) - by @kobenguyent
- CodeceptJS - Playwright now supports other locators like
🐛 Bug Fixes
- fix: step object is broken when step arg is a function (#4092) - by @kobenguyent
- fix: step object is broken when step arg contains joi object (#4084) - by @kobenguyent
- fix(expect helper): custom error message as optional param (#4082) - by @kobenguyent
- fix(puppeteer): hide deprecation info (#4075) - by @kobenguyent
- fix: seeattributesonelements throws error when attribute doesn't exist (#4073) - by @kobenguyent
- fix: typo in agrs (#4077) - by @kobenguyent
- fix: retryFailedStep is disabled for non tryTo steps (#4069) - by @kobenguyent
- fix(typings): scrollintoview complains scrollintoviewoptions (#4067) - by @kobenguyent
📖 Documentation
- fix(docs): some doc blocks are broken (#4076) - by @kobenguyent
- fix(docs): expect docs (#4058) - by @kobenguyent
Full Changelog: 3.5.10...3.5.11