Releases: DevExpress/testcafe
v0.14.0-alpha3
Update hammerhead version. Bump version (#1293)
v0.14.0-alpha2
Bump version (#1277)
v0.14.0-alpha1
Update hammerhead. Bump version
v0.13.0 (2017-2-16)
Enhancements
⚙️ IDE Plugins
With this release, we have prepared test runner plugins for VSCode and SublimeText. These plugins allow you to
- Run a particular test, fixture, all tests in a file or directory via the context menu or built-in commands,
- Automatically detect browsers installed on the local machine,
- Repeat last test run,
- Debug tests,
- View test results in the
Debug Console
panel.
⚙️ Fixture hooks (#903)
You can now specify fixture hooks that will be executed before the first test in a fixture is started and after the last test is finished.
fixture `My fixture`
.page `http://example.com`
.before( async ctx => {
/* fixture initialization code */
})
.after( async ctx => {
/* fixture finalization code */
});
Unlike test hooks, fixture hooks are executed between test runs and do not have access to the tested page. Use them to perform server-side operations like preparing the server that hosts the tested app.
Sharing variables between fixture hooks and test code
Use the ctx
parameter passed to fixture.before
and fixture.after
methods (fixture context) to share values and objects with test code. You can assign to ctx
parameter's properties or add new properties.
In test code, use the t.fixtureCtx
property to access the fixture context.
fixture `Fixture1`
.before(async ctx => {
ctx.someProp = 123;
})
.after(async ctx => {
console.log(ctx.newProp); // > abc
});
test('Test1', async t => {
console.log(t.fixtureCtx.someProp); // > 123
});
test('Test2', async t => {
t.fixtureCtx.newProp = 'abc';
});
⚙️ Speed option for test actions (#865)
You can now specify speed for individual test actions using the speed
option.
import { Selector } from 'testcafe';
const nameInput = Selector('#developer-name');
fixture `My Fixture`
.page `http://devexpress.github.io/testcafe/example/`
test('My Test', async t => {
await t
.typeText(nameInput, 'Peter')
.typeText(nameInput, ' Parker', { speed: 0.1 });
});
If speed is also specified for the whole test, the action speed setting overrides test speed.
⚙️ Setting test speed from test code (#865)
You can now specify test speed from code using the t.setTestSpeed
method.
import { Selector } from 'testcafe';
fixture `Test Speed`
.page `http://devexpress.github.io/testcafe/example/`;
const nameInput = Selector('#developer-name');
test(`Test Speed`, async t => {
await t
.typeText(nameInput, 'Peter')
.setTestSpeed(0.1)
.typeText(nameInput, ' Parker');
});
⚙️ Using test controller outside of test code (#1166)
You may sometimes need to call test API from outside of test code. For instance, your page model can contain methods that perform common operations used in many tests, like authentication.
import { Selector } from 'testcafe';
export default class Page {
constructor () {
this.loginInput = Selector('#login');
this.passwordInput = Selector('#password');
this.signInButton = Selector('#sign-in-button');
}
async login (t) {
await t
.typeText(this.loginInput, 'MyLogin')
.typeText(this.passwordInput, 'Pa$$word')
.click(this.signInButton);
}
}
In this instance, you need to access the test controller from the page model's login
method.
TestCafe allows you to avoid passing the test controller to the method explicitly. Instead, you can simply import t
to the page model file.
import { Selector, t } from 'testcafe';
export default class Page {
constructor () {
this.loginInput = Selector('#login');
this.passwordInput = Selector('#password');
this.signInButton = Selector('#sign-in-button');
}
async login () {
await t
.typeText(this.loginInput, 'MyLogin')
.typeText(this.passwordInput, 'Pa$$word')
.click(this.signInButton);
}
}
TestCafe will implicitly resolve test context and provide the right test controller.
⚙️ Inserting text with one keystroke with t.typeText action (by @ericyd) (#1230)
The new paste
option allows you to insert a portion of text with one keystroke, similar to the paste operation.
import { Selector } from 'testcafe';
fixture `My fixture`
.page `http://devexpress.github.io/testcafe/example/`;
const nameInput = Selector('#developer-name');
test(`My test`, async t => {
await t
.typeText(nameInput, 'Peter')
.typeText(nameInput, ' Parker', { paste: true });
});
⚙️ prevSibling and nextSibling selector's DOM search methods (#1218)
The new prevSibling
and nextSibling
methods allow you to search among sibling elements that reside before and after the selector's matching elements in the DOM tree.
Selector('li .active').prevSibling(2);
Selector('li').nextSibling('.checked');
⚙️ Deprecated functionality removed (#1167)
The following deprecated members have been removed from the API.
t.select
method - useSelector
instead:
const id = await t.select('.someClass').id;
// can be replaced with
const id = await Selector('.someClass').id;
selectorOptions.index
- use selector.nth() instead.selectorOptions.text
- use selector.withText() instead.selectorOptions.dependencies
- use filtering and hierarchical methods to build combined selectors instead.
Bug Fixes
- Fixed a bug where tests failed with a script error (#1188)
- Text can now be typed to an input field with type "email" in Firefox (#1187)
npm install
no longer displays warnings (#769)- Dev Tools can now be opened with a keyboard shortcut or right click on macOS (#1193)
- A warning no longer appears when using ClientFunction with dependencies (#1168)
- Tests can now run against React Storybook (#1147)
- Script error is no longer thrown in iOS webviews (Firefox, Chrome of iOS) (#1189)
- XhrSandbox.createNativeXHR now works correctly (testcafe-hammerhead/#1042)
- Window.prototype is no longer used for NativeMethods initialization (testcafe-hammerhead/#1040)
- Functions from the 'vm' module are now overridden on the client (testcafe-hammerhead/#1029)
- Input type is now changed while setting the selection range in Firefox (testcafe-hammerhead/#1025)
- An iframe with the
about:blank
src can now sendpostMessage
(testcafe-hammerhead/#1026) - The
formaction
attribute is now overridden correctly after it is appended in DOM (testcafe-hammerhead/#1021) - Fixed a bug where the Authorization Header was wrongly removed (testcafe-hammerhead/#1016)
- The
file://
protocol is now supported (testcafe-hammerhead/#908)
v0.13.0-alpha3
Versions is updated (#1243)
v0.13.0-alpha2
Bump version (#1217)
v0.13.0-alpha1
Update testcafe-hammerhead (10.3.2). Bump version. (#1183)
v0.12.1 (2017-1-20)
v0.12.0 (2017-1-19)
Enhancements
⚙️ HTTP authentication support (#955, #1109)
TestCafe now supports testing webpages protected with HTTP Basic and NTLM authentication.
Use the httpAuth function in fixture or test declaration to specify the credentials.
fixture `My fixture`
.page `http://example.com`
.httpAuth({
username: 'username',
password: 'Pa$$word',
// Optional parameters, can be required for the NTLM authentication.
domain: 'CORP-DOMAIN',
workstation: 'machine-win10'
});
test('Test1', async t => {}); // Logs in as username
test // Logs in as differentUserName
.httpAuth({
username: 'differentUserName',
password: 'differentPa$$word'
})
('Test2', async t => {});
⚙️ Built-in CI-friendly way to start and stop the tested web app (#1047)
When launching tests, you can now specify a command that starts the tested application.
TestCafe will automatically execute this command before running tests and stop the process when tests are finished.
testcafe chrome tests/ --app "node server.js"
runner
.startApp('node server.js')
.run();
You can also specify how long TestCafe should wait until the tested application initializes (the default is 1 sec).
testcafe chrome tests/ --app "node server.js" --app-init-delay 4000
runner
.startApp('node server.js', 4000)
.run();
⚙️ Screenshot and window resize actions now work on Linux (#1117)
The t.takeScreenshot
, t.resizeWindow
, t.resizeWindowToFitDevice
and t.maximizeWindow
actions can now be executed on Linux machines.
⚙️ Adding custom properties to the element state (#749)
The state of webpage elements can now be extended with custom properties.
We have added the addCustomDOMProperties method to the selector, so that you can add properties to the element state like in the following example.
import { Selector } from 'testcafe'
fixture `My fixture`
.page `https://devexpress.github.io/testcafe/example/`;
test('Check Label HTML', async t => {
const label = Selector('label').addCustomDOMProperties({
innerHTML: el => el.innerHTML
});
await t.expect(label.innerHTML).contains('input type="checkbox" name="remote"');
});
⚙️ Skipping tests (#246)
TestCafe now allows you to specify that a particular test or fixture should be skipped when running tests.
Use the fixture.skip
and test.skip
methods for this.
fixture.skip `Fixture1`; // All tests in this fixture will be skipped
test('Fixture1Test1', () => {});
test('Fixture1Test2', () => {});
fixture `Fixture2`;
test('Fixture2Test1', () => {});
test.skip('Fixture2Test2', () => {}); // This test will be skipped
test('Fixture2Test3', () => {});
You can also use the only
method to specify that only a particular test or fixture should run while all others should be skipped.
fixture.only `Fixture1`;
test('Fixture1Test1', () => {});
test('Fixture1Test2', () => {});
fixture `Fixture2`;
test('Fixture2Test1', () => {});
test.only('Fixture2Test2', () => {});
test('Fixture2Test3', () => {});
// Only tests in Fixture1 and the Fixture2Test2 test will run
⚙️ Specifying the start webpage for a test (#501)
An individual test can now override the fixture's page
setting and start on a different page.
fixture `MyFixture`
.page `http://devexpress.github.io/testcafe/example`;
test('Test1', async t => {
// Starts at http://devexpress.github.io/testcafe/example
});
test
.page `http://devexpress.github.io/testcafe/blog/`
('Test2', async t => {
// Starts at http://devexpress.github.io/testcafe/blog/
});
⚙️ Initialization and finalization methods for a test (#1108)
We have added the before and after methods to the test declaration.
Use them to provide code that will be executed before a test is started and after it is finished.
test
.before( async t => {
/* test initialization code */
})
('My Test', async t => {
/* test code */
})
.after( async t => {
/* test finalization code */
});
⚙️ Sharing variables between hooks and test code (#841)
You can now share variables between fixture.beforeEach
, fixture.afterEach
, test.before
, test.after
functions and test code by using the test context object.
Test context is available through the t.ctx
property.
Instead of using a global variable, assign the object you want to share directly to t.ctx
or create a property like in the following example.
fixture `Fixture1`
.beforeEach(async t => {
t.ctx.someProp = 123;
});
test
('Test1', async t => {
console.log(t.ctx.someProp); // > 123
})
.after(async t => {
console.log(t.ctx.someProp); // > 123
});
⚙️ Assertion methods to check for regexp match (#1038)
We have added match
and notMatch
methods to check if a string matches a particular regular expression.
await t.expect('foobar').match(/^f/, 'this assertion passes');
await t.expect('foobar').notMatch(/^b/, 'this assertion passes');
⚙️ Improved filtering by predicates in selectors (#1025 and #1065)
Selector's filter predicates now receive more information about the current node, which enables you to implement more advanced filtering logic.
The filter
, find
, parent
, child
and sibling
methods now pass the node's index to the predicate.
The find
, parent
, child
and sibling
methods now also pass a node from the preceding selector.
Selector('ul').find((node, idx, originNode) => {
// node === the <ul>'s descendant node
// idx === index of the current <ul>'s descendant node
// originNode === the <ul> element
});
In addition, all these methods now allow you to pass objects to the predicate's scope on the client. To this end, we have added an optional dependencies
parameter.
const isNodeOk = ClientFunction(node => { /*...*/ });
const flag = getFlag();
Selector('ul').child(node => {
return isNodeOk(node) && flag;
}, { isNodeOk, flag });
⚙️ Filtering by negative index in selectors (#738)
You can now pass negative index
values to selector methods. In this instance, index is counted from the end of the matching set.
const lastChild = Selector('.someClass').child(-1);
⚙️ Improved cursor positioning in test actions (#981)
In action options, X and Y offsets that define the point where action is performed can now be negative.
In this instance, the cursor position is calculated from the bottom-right corner of the target element.
await t.click('#element', { offsetX: -10, offsetY: -30 });
⚙️ Client functions as an assertion's actual value (#1009)
You can now pass client functions to assertion's expect
method. In this instance, the Smart Assertion Query Mechanism will run this client function and use the return value as the assertion's actual value.
import { ClientFunction } from 'testcafe';
const windowLocation = ClientFunction(() => window.location.toString());
fixture `My Fixture`
.page `http://www.example.com`;
test('My Test', async t => {
await t.expect(windowLocation()).eql('http://www.example.com');
});
⚙️ Automatic waiting for scripts added during a test action (#1072)
If a test action adds scripts on a page, TestCafe now automatically waits for them to finish before proceeding to the next test action.
⚙️ New ESLint plugin (#1083)
We have prepared an ESLint plugin.
Get it to ensure that ESLint does not fail on TestCafe test code.
Bug Fixes
- Remote browser connection timeout has been increased (#1078)
- You can now run tests located in directories with a large number of files (#1090)
- Key identifiers for all keys are now passed to key events (#1079)
- Touch events are no longer emulated for touch monitors (#984)
- v8 flags can now be passed to Node.js when using TestCafe from the command line (#1006)
- ShadowU...
0.12.0-alpha6
Bump version. Release candidate (#1150)