TestCafe v0.11.0 Released
Redesigned selector system, built-in assertions and lots of bug fixes! 🚀🚀🚀
Enhancements
âš™ Redesigned selector system. (#798)
New selector methods
Multiple filtering and hierarchical methods were introduced for selectors. Now you can build flexible, lazily-evaluated functional-style selector chains.
Here are some examples:
Selector('ul').find('label').parent('div.someClass')
Finds all ul elements on page. Then, in each found ul element finds label elements.
Then, for each label element finds a parent that matches the div.someClass selector.
Like in jQuery, if you request a property of the matched set or try evaluate a snapshot, the selector returns values for the first element in the set.
// Returns id of the first element in the set
const id = await Selector('ul').find('label').parent('div.someClass').id;
// Returns snapshot for the first element in the set
const snapshot = await Selector('ul').find('label').parent('div.someClass')();
However, you can obtain data for any element in the set by using nth filter.
// Returns id of the third element in the set
const id = await Selector('ul').find('label').parent('div.someClass').nth(2).id;
// Returns snapshot for the fourth element in the set
const snapshot = await Selector('ul').find('label').parent('div.someClass').nth(4)();
Note that you can add text and index filters in the selector chain.
Selector('.container').parent(1).nth(0).find('.content').withText('yo!').child('span');
In this example the selector:
- finds the second parent (parent of parent) of
.containerelements; - peeks the first element in the matched set;
- in that element, finds elements that match the
.contentselector; - filters them by text
yo!; - in each filtered element, searches for a child with tag name
span.
Getting selector matched set length
Also, now you can get selector matched set length and check matching elements existence by using selector count and exists properties.
Unawaited parametrized selector calls now allowed outside test context
Previously selector call outside of text context thrown an error:
const selector = Selector(arg => /* selector code */);
selector('someArg'); // <-- throws
test ('Some test', async t=> {
...
});
Now it’s not a case if selector is not awaited. It’s useful when you need to build a page model outside the test context:
const selector = Selector(arg => /* selector code */);
const selector2 = selector('someArg').find('span'); // <-- doesn't throw anymore
test ('Some test', async t=> {
...
});
However, once you’ll try to obtain element property outside of test context it will throw:
const selector = Selector(arg => /* selector code */);
async getId() {
return await selector('someArg').id; // throws
}
getId();
test ('Some test', async t=> {
...
});
Index filter is not ignored anymore if selector returns single node
Previously if selector returned single node index was ignored:
Selector('#someId', { index: 2 } ); // index is ignored and selector returns element with id `someId`
however it’s not a case now:
Selector('#someId').nth(2); // returns `null`, since there is only one element in matched set with id `someId`
Deprecated API
t.selectmethod - useSelectorinstead:
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.
âš™ Built-in assertions. (#998)
TestCafe now ships with numerous built-in BDD-style assertions. If the TestCafe assertion receives a Selector’s DOM node state property as an actual value, TestCafe uses the smart assertion query mechanism: if an assertion did not passed, the test does not fail immediately. The assertion retries to pass multiple times and each time it re-requests the actual shorthand value. The test fails if the assertion could not complete successfully within a timeout. This approach allows you to create stable tests that lack random errors and decrease the amount of time required to run all your tests due to the lack of extra waitings.
Example page markup:
<div id="btn"></div>
<script>
var btn = document.getElementById('btn');
btn.addEventListener(function() {
window.setTimeout(function() {
btn.innerText = 'Loading...';
}, 100);
});
</script>
Example test code:
test('Button click', async t => {
const btn = Selector('#btn');
await t
.click(btn)
// Regular assertion will fail immediately, but TestCafe retries to run DOM state
// assertions many times until this assertion pass successfully within the timeout.
// The default timeout is 3000 ms.
.expect(btn.textContent).contains('Loading...');
});
âš™ Added selected and selectedIndex DOM node state properties. (#951)
⚙ It’s now possible to start browser with arguments. (#905)
If you need to pass arguments for the specified browser, write them right after browser alias. Surround the browser call and its arguments with quotation marks:
testcafe "chrome --start-fullscreen",firefox tests/test.js
See Starting browser with arguments.
Bug Fixes
- Action keyboard events now have
event.keyandevent.keyIdentifierproperties set (#993). document.body.nextSibling, that was broken is some cases previously, now operates properly (#958).- Now it’s possible to use
t.setFilesToUploadandt.clearUploadmethods with the hidden inputs (#963). - Now test not hangs if object
toStringmethod usesthis.locationgetter (#953). - Touch events now correctly dispatched in latest Chrome versions with touch monitor (#944).
- Now test compilation doesn’t fail if imported helper contains module re-export (e.g.
export * from './mod') (#969). - Actions now scroll to element to make it completely visible (there possible) (#987, #973).
- Dispatched key events now successfully pass
instanceofcheck (#964). - Ember elements doesn’t throw
Uncaught TypeError: e.getAttribute is not a functionanymore (#966). - First run wizards now automatically disabled in Chrome in Firefox (testcafe-browser-tools#102).
<td>now correctly focused on actions.document.baseURInow returns correct value.Function.constructornow returns correct value.- Setting
locationto the URL hash value doesn’t lead to JavaScript error anymore. - Fixed corruption of
<template>content. - Fixed
querySelectorforhrefattribute if value contains URL hash. - HTTP responses with Brotli encoding now processed correctly.
Element.attributesnow behaves as a live collection.- TestCafe doesn’t fail with
Error: Can't set headers after they are sent.error on network errors. - Element property value setters now return correct value.
window.fetchwithout parameters now returns rejected promise as expected.- Hyperlinks created in iframe and added to the top window now have correct URL.
autocompleteattribute now not forced on all elements.- Cookies set via XHR response now available from client code.
- Fixed client rendering problems caused by incorrect DOM element determination.