Releases: codeceptjs/CodeceptJS
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
3.5.10
❤️ Thanks all to those who contributed to make this release! ❤️
🛩️ Features
- feat: expose WebElement (#4043) - by @kobenguyent
Now we expose the WebElements that are returned by the WebHelper and you could make the subsequence actions on them.
// Playwright helper would return the Locator
I.amOnPage('/form/focus_blur_elements');
const webElements = await I.grabWebElements('#button');
webElements[0].click();
- feat(playwright): support HAR replaying (#3990) - by @kobenguyent
Replaying from HAR
// Replay API requests from HAR.
// Either use a matching response from the HAR,
// or abort the request if nothing matches.
I.replayFromHar('./output/har/something.har', { url: "*/**/api/v1/fruits" });
I.amOnPage('https://demo.playwright.dev/api-mocking');
I.see('CodeceptJS');
[Parameters]
harFilePath [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) Path to recorded HAR file
opts [object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)? [Options for replaying from HAR](https://playwright.dev/docs/api/class-page#page-route-from-har)
- feat(playwright): support HAR recording (#3986) - by @kobenguyent
A HAR file is an HTTP Archive file that contains a record of all the network requests that are made when a page is loaded.
It contains information about the request and response headers, cookies, content, timings, and more.
You can use HAR files to mock network requests in your tests. HAR will be saved to output/har.
More info could be found here https://playwright.dev/docs/api/class-browser#browser-new-context-option-record-har.
...
recordHar: {
mode: 'minimal', // possible values: 'minimal'|'full'.
content: 'embed' // possible values: "omit"|"embed"|"attach".
}
...
- improvement(playwright): support partial string for option (#4016) - by @kobenguyent
await I.amOnPage('/form/select');
await I.selectOption('Select your age', '21-');
🐛 Bug Fixes
- fix(playwright): proceedSee could not find the element (#4006) - by @hatufacci
- fix(appium): remove the vendor prefix of 'bstack:options' (#4053) - by @mojtabaalavi
- fix(workers): event improvements (#3953) - by @kobenguyent
Emit the new event: event.workers.result.
CodeceptJS also exposes the env var `process.env.RUNS_WITH_WORKERS` when running tests with run-workers command so that you could handle the events better in your plugins/helpers.
const { event } = require('codeceptjs');
module.exports = function() {
// this event would trigger the `_publishResultsToTestrail` when running `run-workers` command
event.dispatcher.on(event.workers.result, async () => {
await _publishResultsToTestrail();
});
// this event would not trigger the `_publishResultsToTestrail` multiple times when running `run-workers` command
event.dispatcher.on(event.all.result, async () => {
// when running `run` command, this env var is undefined
if (!process.env.RUNS_WITH_WORKERS) await _publishResultsToTestrail();
});
}
- fix: ai html updates (#3962) - by @DavertMik
replaced minify library with a modern and more secure fork. Fixes html-minifier@4.0.0 Regular Expression Denial of Service vulnerability #3829
AI class is implemented as singleton
refactored heal.js plugin to work on edge cases
add configuration params on number of fixes performed by ay heal
improved recorder class to add more verbose log
improved recorder class to ignore some of errors
- fix(appium): closeApp supports both Android/iOS (#4046) - by @kobenguyent
- fix: some security vulnerability of some packages (#4045) - by @kobenguyent
- fix: seeAttributesOnElements check condition (#4029) - by @kobenguyent
- fix: waitForText locator issue (#4039) - by @kobenguyent
Fixed this error:
locator.isVisible: Unexpected token "s" while parsing selector ":has-text('Were you able to resolve the resident's issue?') >> nth=0"
at Playwright.waitForText (node_modules\codeceptjs\lib\helper\Playwright.js:2584:79)
- fix: move to sha256 (#4038) - by @kobenguyent
- fix: respect retries from retryfailedstep plugin in helpers (#4028) - by @kobenguyent
Currently inside the _before() of helpers for example Playwright, the retries is set there, however, when retryFailedStep plugin is enabled, the retries of recorder is still using the value from _before() not the value from retryFailedStep plugin.
Fix:
- introduce the process.env.FAILED_STEP_RETIRES which could be access everywhere as the helper won't know anything about the plugin.
- set default retries of Playwright to 3 to be on the same page with Puppeteer.
- fix: examples in test title (#4030) - by @kobenguyent
When test title doesn't have the data in examples:
Feature: Faker examples
Scenario Outline: Below are the users
Examples:
| user | role |
| John | admin |
| Tim | client |
Faker examples --
[1] Starting recording promises
Timeouts:
Below are the users {"user":"John","role":"admin"}
✔ OK in 4ms
Below are the users {"user":"Tim","role":"client"}
✔ OK in 1ms
When test title includes the data in examples:
Feature: Faker examples
Scenario Outline: Below are the users - <user> - <role>
Examples:
| user | role |
| John | admin |
| Tim | client |
Faker examples --
[1] Starting recording promises
Timeouts:
Below are the users - John - admin
✔ OK in 4ms
Below are the users - Tim - client
✔ OK in 1ms
- fix: disable retryFailedStep when using with tryTo (#4022) - by @kobenguyent
- fix: locator builder returns error when class name contains hyphen (#4024) - by @kobenguyent
- fix: seeCssPropertiesOnElements failed when font-weight is a number (#4026) - by @kobenguyent
- fix(appium): missing await on some steps of runOnIOS and runOnAndroid (#4018) - by @kobenguyent
- fix(cli): no error of failed tests when using retry with scenario only (#4020) - by @kobenguyent
- fix: set getPageTimeout to 30s (#4031) - by @kobenguyent
- fix(appium): expose switchToContext (#4015) - by @kobenguyent
- fix: promise issue (#4013) - by @kobenguyent
- fix: seeCssPropertiesOnElements issue with improper condition (#4057) - by @kobenguyent
📖 Documentation
- docs: Update clearCookie documentation for Playwright helper (#4005) - by @Hellosager
- docs: improve the example code for autoLogin (#4019) - by @kobenguyent
New Contributors
- @Hellosager made their first contribution in #4005
- @mojtabaalavi made their first contribution in #4053
Full Changelog: 3.5.8...3.5.10
3.5.9
❤️ Thanks all to those who contributed to make this release! ❤️
🛩️ Features
- feat: expose WebElement (#4043) - by @kobenguyent
Now we expose the WebElements that are returned by the WebHelper and you could make the subsequence actions on them.
// Playwright helper would return the Locator
I.amOnPage('/form/focus_blur_elements');
const webElements = await I.grabWebElements('#button');
webElements[0].click();
- feat(playwright): support HAR replaying (#3990) - by @kobenguyent
Replaying from HAR
// Replay API requests from HAR.
// Either use a matching response from the HAR,
// or abort the request if nothing matches.
I.replayFromHar('./output/har/something.har', { url: "*/**/api/v1/fruits" });
I.amOnPage('https://demo.playwright.dev/api-mocking');
I.see('CodeceptJS');
[Parameters]
harFilePath [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) Path to recorded HAR file
opts [object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)? [Options for replaying from HAR](https://playwright.dev/docs/api/class-page#page-route-from-har)
- feat(playwright): support HAR recording (#3986) - by @kobenguyent
A HAR file is an HTTP Archive file that contains a record of all the network requests that are made when a page is loaded.
It contains information about the request and response headers, cookies, content, timings, and more.
You can use HAR files to mock network requests in your tests. HAR will be saved to output/har.
More info could be found here https://playwright.dev/docs/api/class-browser#browser-new-context-option-record-har.
...
recordHar: {
mode: 'minimal', // possible values: 'minimal'|'full'.
content: 'embed' // possible values: "omit"|"embed"|"attach".
}
...
- improvement(playwright): support partial string for option (#4016) - by @kobenguyent
await I.amOnPage('/form/select');
await I.selectOption('Select your age', '21-');
🐛 Bug Fixes
- fix(playwright): proceedSee could not find the element (#4006) - by @hatufacci
- fix(appium): remove the vendor prefix of 'bstack:options' (#4053) - by @mojtabaalavi
- fix(workers): event improvements (#3953) - by @kobenguyent
Emit the new event: event.workers.result.
CodeceptJS also exposes the env var `process.env.RUNS_WITH_WORKERS` when running tests with run-workers command so that you could handle the events better in your plugins/helpers.
const { event } = require('codeceptjs');
module.exports = function() {
// this event would trigger the `_publishResultsToTestrail` when running `run-workers` command
event.dispatcher.on(event.workers.result, async () => {
await _publishResultsToTestrail();
});
// this event would not trigger the `_publishResultsToTestrail` multiple times when running `run-workers` command
event.dispatcher.on(event.all.result, async () => {
// when running `run` command, this env var is undefined
if (!process.env.RUNS_WITH_WORKERS) await _publishResultsToTestrail();
});
}
replaced minify library with a modern and more secure fork. Fixes html-minifier@4.0.0 Regular Expression Denial of Service vulnerability #3829
AI class is implemented as singleton
refactored heal.js plugin to work on edge cases
add configuration params on number of fixes performed by ay heal
improved recorder class to add more verbose log
improved recorder class to ignore some of errors
- fix(appium): closeApp supports both Android/iOS (#4046) - by @kobenguyent
- fix: some security vulnerability of some packages (#4045) - by @kobenguyent
- fix: seeAttributesOnElements check condition (#4029) - by @kobenguyent
- fix: waitForText locator issue (#4039) - by @kobenguyent
Fixed this error:
locator.isVisible: Unexpected token "s" while parsing selector ":has-text('Were you able to resolve the resident's issue?') >> nth=0"
at Playwright.waitForText (node_modules\codeceptjs\lib\helper\Playwright.js:2584:79)
- fix: move to sha256 (#4038) - by @kobenguyent
- fix: respect retries from retryfailedstep plugin in helpers (#4028) - by @kobenguyent
Currently inside the _before() of helpers for example Playwright, the retries is set there, however, when retryFailedStep plugin is enabled, the retries of recorder is still using the value from _before() not the value from retryFailedStep plugin.
Fix:
- introduce the process.env.FAILED_STEP_RETIRES which could be access everywhere as the helper won't know anything about the plugin.
- set default retries of Playwright to 3 to be on the same page with Puppeteer.
- fix: examples in test title (#4030) - by @kobenguyent
When test title doesn't have the data in examples:
Feature: Faker examples
Scenario Outline: Below are the users
Examples:
| user | role |
| John | admin |
| Tim | client |
Faker examples --
[1] Starting recording promises
Timeouts:
Below are the users {"user":"John","role":"admin"}
✔ OK in 4ms
Below are the users {"user":"Tim","role":"client"}
✔ OK in 1ms
When test title includes the data in examples:
Feature: Faker examples
Scenario Outline: Below are the users - <user> - <role>
Examples:
| user | role |
| John | admin |
| Tim | client |
Faker examples --
[1] Starting recording promises
Timeouts:
Below are the users - John - admin
✔ OK in 4ms
Below are the users - Tim - client
✔ OK in 1ms
- fix: disable retryFailedStep when using with tryTo (#4022) - by @kobenguyent
- fix: locator builder returns error when class name contains hyphen (#4024) - by @kobenguyent
- fix: seeCssPropertiesOnElements failed when font-weight is a number (#4026) - by @kobenguyent
- fix(appium): missing await on some steps of runOnIOS and runOnAndroid (#4018) - by @kobenguyent
- fix(cli): no error of failed tests when using retry with scenario only (#4020) - by @kobenguyent
- fix: set getPageTimeout to 30s (#4031) - by @kobenguyent
- fix(appium): expose switchToContext (#4015) - by @kobenguyent
- fix: promise issue (#4013) - by @kobenguyent
- fix: seeCssPropertiesOnElements issue with improper condition (#4057) - by @kobenguyent
📖 Documentation
- docs: Update clearCookie documentation for Playwright helper (#4005) - by @Hellosager
- docs: improve the example code for autoLogin (#4019) - by @kobenguyent
New Contributors
- @Hellosager made their first contribution in #4005
- @mojtabaalavi made their first contribution in #4053
Full Changelog: 3.5.8...3.5.9
3.5.8
What's Changed
- fix: missing exit condition by @kobenguyent in #3984
- fix: improve the way to show deprecated appium v1 message by @kobenguyent in #3992
- chore(deps-dev): bump express from 4.17.2 to 4.18.2 by @dependabot in #3996
- chore(deps-dev): bump jsdoc from 3.6.10 to 3.6.11 by @dependabot in #3997
- chore(deps-dev): bump electron from 27.0.2 to 27.0.4 by @dependabot in #3995
- chore(deps-dev): bump dtslint from 4.1.6 to 4.2.1 by @dependabot in #3999
- fix(appium): type of setNetworkConnection() by @mirao in #3994
- release 3.5.8 by @kobenguyent in #4004
Full Changelog: 3.5.7...3.5.8
3.5.7
What's Changed
- Bump playwright to 1.39.0 by @kobenguyent in #3924
- chore(deps-dev): bump testcafe from 3.0.1 to 3.3.0 by @dependabot in #3929
- chore(deps-dev): bump xml2js from 0.6.0 to 0.6.2 by @dependabot in #3927
- chore(deps-dev): bump typescript from 5.1.6 to 5.2.2 by @dependabot in #3913
- fix(playwright): some wait funcs draw error due to switchTo iframe by @kobenguyent in #3918
- fix: relax grabCookie type by @kobenguyent in #3919
- docs(appium): update to v2 by @kobenguyent in #3932
- fix: proceedSee by @kobenguyent in #3939
- docs: improve BDD Gherkin docs by @kobenguyent in #3938
- fix: customLocator draws error in dry-mode by @kobenguyent in #3940
- fix(gherkin): long text cuts off by @kobenguyent in #3936
- fix: gherkin supports i18n by @kobenguyent in #3934
- fix: move to waitFor by @kobenguyent in #3933
- fix: ensure docs include
@returns Promise<void>
where appropriate by @fwouts in #3954 - chore(deps-dev): bump electron from 26.1.0 to 27.0.2 by @dependabot in #3945
- feat(autoLogin): improve the check method by @kobenguyent in #3935
- fix: handle the way to load apifactory nicely by @kobenguyent in #3941
- feat: expect helper by @kobenguyent in #3923
- fix: AppiumTestDistribution/appium-device-farm requires 'platformName' by @rock-tran in #3950
- fix: rename haveRequestHeaders of ppt and pw helpers by @kobenguyent in #3937
- fix: autologin with empty fetch by @andonary in #3947
- chore(deps): bump actions/setup-node from 3 to 4 by @dependabot in #3961
- chore(deps-dev): bump eslint-plugin-import from 2.25.4 to 2.29.0 by @dependabot in #3960
- chore(deps-dev): bump typedoc from 0.24.8 to 0.25.3 by @dependabot in #3959
- chore(deps-dev): bump @wdio/utils from 8.16.22 to 8.20.3 by @dependabot in #3957
- chore(deps-dev): bump sinon from 15.2.0 to 17.0.0 by @dependabot in #3956
- fix 3968 by @hatufacci in #3969
- fix: playwright v1.38 and later update by @kobenguyent in #3967
- fix: appium helper docs update by @kobenguyent in #3966
- fix: crypto complaint by @kobenguyent in #3975
- Update advanced.md by @aarifkhamdi in #3951
- chore(deps): bump joi from 17.6.0 to 17.11.0 by @dependabot in #3977
- chore(deps-dev): bump sinon from 17.0.0 to 17.0.1 by @dependabot in #3976
- chore(deps-dev): bump contributor-faces from 1.0.3 to 1.1.0 by @dependabot in #3979
- chore(deps-dev): bump eslint from 8.50.0 to 8.53.0 by @dependabot in #3978
- fix: remove node 16 by @kobenguyent in #3982
- feat(puppeteer): support trace recording by @kobenguyent in #3981
- feat: parallel execution by workers on multiple browsers results with multiple output folders by @kobenguyent in #3971
- release 3.5.7 by @kobenguyent in #3983
New Contributors
- @fwouts made their first contribution in #3954
- @rock-tran made their first contribution in #3950
- @aarifkhamdi made their first contribution in #3951
Full Changelog: 3.5.6...3.5.7
3.5.6
What's Changed
- fix: cicrcle ci by @kobenguyent in #3884
- fix: error cannot require JSONResponse by @kobenguyent in #3893
- chore(deps-dev): bump expect from 29.6.2 to 29.7.0 by @dependabot in #3890
- chore(deps-dev): bump eslint from 8.45.0 to 8.50.0 by @dependabot in #3889
- FileSystem: JSDoc: Fixed a typo in writeToFile(), added a unit test by @mirao in #3897
- fix: debug info causes error by @kobenguyent in #3882
- fix: multiple elements returned by @kobenguyent in #3883
- fix: masked value issue in data table by @kobenguyent in #3885
- fix: session typing by @kobenguyent in #3899
- feat(translation): add more french keywords by @andonary in #3906
- fix: increase UT timeout by @kobenguyent in #3909
- chore(deps-dev): bump runok from 0.9.2 to 0.9.3 by @dependabot in #3905
- chore(deps-dev): bump @pollyjs/adapter-puppeteer from 6.0.5 to 6.0.6 by @dependabot in #3887
- fix: highlight issue by @kobenguyent in #3896
- fix: improve the versioning function by @kobenguyent in #3911
- fix: switchTo - within block by @kobenguyent in #3892
- chore(deps-dev): bump husky from 8.0.1 to 8.0.3 by @dependabot in #3917
- chore(deps-dev): bump @wdio/utils from 8.3.0 to 8.16.22 by @dependabot in #3916
- chore(deps): bump js-beautify from 1.14.0 to 1.14.9 by @dependabot in #3915
- chore(deps-dev): bump playwright from 1.35.1 to 1.38.1 by @dependabot in #3914
- release 3.5.6 by @kobenguyent in #3912
Full Changelog: 3.5.5...3.5.6