Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into docs5704-vpn-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
DIRECTcut committed Dec 16, 2020
2 parents f7e6c96 + 9303aa8 commit 3595ce1
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
layout: post
title: "v1.10.0: New Compiler Options API, Resize and Screenshot Support for Child Windows"
permalink: /blog/:title.html
---
# v1.10.0: New Compiler Options API, Resize and Screenshot Support for Child Windows

...and the selector API for shadow DOM access, plus multiple bugfixes.

<!--more-->

## Enhancements

### Window Resize and Screenshot Support for Child Windows in Chrome ([PR #5661](https://github.com/DevExpress/testcafe/pull/5661), [PR #5567](https://github.com/DevExpress/testcafe/pull/5567))

You can now use the following actions in Google Chrome when you switch the test context to a [child window](../documentation/guides/advanced-guides/multiple-browser-windows.md):

* [t.maximizeWindow](../documentation/reference/test-api/testcontroller/maximizewindow.md)
* [t.resizeWindow](../documentation/reference/test-api/testcontroller/resizewindow.md)
* [t.resizeWindowToFitDevice](../documentation/reference/test-api/testcontroller/resizewindowtofitdevice.md)
* [t.takeElementScreenshot](../documentation/reference/test-api/testcontroller/takeelementscreenshot.md)
* [t.takeScreenshot](../documentation/reference/test-api/testcontroller/takescreenshot.md)

### New API to Specify Compiler Options ([#5519](https://github.com/DevExpress/testcafe/issues/5519))

In previous versions, you used the following methods to specify TypeScript compiler options:

* the [--ts-config-path](../documentation/reference/command-line-interface.md#--ts-config-path-path) command line flag

```sh
testcafe chrome my-tests --ts-config-path path/to/config.json
```

* the [runner.tsConfigPath](../documentation/reference/testcafe-api/runner/tsconfigpath.md) method

```js
runner.tsConfigPath('path/to/config.json');
```

* the [tsConfigPath](../documentation/reference/configuration-file.md#tsconfigpath) configuration file property

```json
{
"tsConfigPath": "path/to/config.json"
}
```

In v1.10.0, we introduced a new easy-to-use API that allows you to specify the compiler options in the command line, API or TestCafe configuration file, without creating a separate JSON file. The new API is also designed to accept options for more compilers (for instance, Babel) in future releases.

The API consists of the following members:

* the [--compiler-options](../documentation/reference/command-line-interface.md#--compiler-options-options) command line flag

```sh
testcafe chrome my-tests --compiler-options typescript.experimentalDecorators=true
```

* the [runner.compilerOptions](../documentation/reference/testcafe-api/runner/compileroptions.md) method

```js
runner.compilerOptions({
typescript: {
experimentalDecorators: true
}
});
```

* the [compilerOptions](../documentation/reference/configuration-file.md#compileroptions) configuration file property

```json
{
"compilerOptions": {
"typescript": {
"experimentalDecorators": true
}
}
}
```

If you prefer to keep compiler settings in a configuration file, you can use the new API to specify the path to this file:

```sh
testcafe chrome my-tests --compiler-options typescript.configPath='path/to/config.json'
```

In v1.10.0, you can customize TypeScript compiler options only.

For more information, see [TypeScript and CoffeeScript](../documentation/guides/concepts/typescript-and-coffeescript.md).

### Added a Selector Method to Access Shadow DOM ([PR #5560](https://github.com/DevExpress/testcafe/pull/5560) by [@mostlyfabulous](https://github.com/mostlyfabulous))

This release introduces the [selector.shadowRoot](../documentation/reference/test-api/selector/shadowroot.md) method that allows you to access and interact with the shadow DOM elements. This method returns a shadow DOM root hosted in the selector's matched element.
```js
import { Selector } from 'testcafe'
fixture `Target Shadow DOM elements`
.page('https://devexpress.github.io/testcafe/example')
test('Get text within shadow tree', async t => {
const shadowRoot = Selector('div').withAttribute('id', 'shadow-host').shadowRoot();
const paragraph = shadowRoot.child('p');
await t.expect(paragraph.textContent).eql('This paragraph is in the shadow tree');
});
```
Note that you should chain other [selector methods](../documentation/guides/basic-guides/select-page-elements.md#member-tables) to [selector.shadowRoot](../documentation/reference/test-api/selector/shadowroot.md) to access elements in the shadow DOM. You cannot interact with the root element (an error occurs if you specify `selector.shadowRoot` as an action's target element).

## Bug Fixes

* Browsers now restart correctly on BrowserStack when the connection is lost ([#5238](https://github.com/DevExpress/testcafe/issues/5238))
* Fixed an error that occurs if a child window is opened in an `iframe` ([#5033](https://github.com/DevExpress/testcafe/issues/5033))
* TestCafe can now switch between the child and parent windows after the parent window is reloaded ([#5463](https://github.com/DevExpress/testcafe/issues/5463), [#5597](https://github.com/DevExpress/testcafe/issues/5597))
* Fixed an issue when touch and mouse events fired on mobile devices even though the mouse event was prevented in page code ([#5380](https://github.com/DevExpress/testcafe/issues/5380))
* Cross-domain `iframes` are now focused correctly in Safari ([#4793](https://github.com/DevExpress/testcafe/issues/4793))
* Fixed an excessive warning displayed when an assertion is executed in a loop or against an element returned by a `selector.xxxSibling` method ([#5449](https://github.com/DevExpress/testcafe/issues/5449), [#5389](https://github.com/DevExpress/testcafe/issues/5389))
* Cross-domain `iframe` source links now have the correct protocol when SSL is used ([PR testcafe-hammerhead/#2478](https://github.com/DevExpress/testcafe-hammerhead/pull/2478))
* A page error is no longer emitted if the destination server responded with the `304` status ([#5025](https://github.com/DevExpress/testcafe/issues/5025))
* Fixed an issue when TestCafe could not authenticate websites that use MSAL ([#4834](https://github.com/DevExpress/testcafe/issues/4834))
* The `srcdoc` attributes for `iframes` are now processed ([testcafe-hammerhead/#1237](https://github.com/DevExpress/testcafe-hammerhead/issues/1237))
* The `authorization` header is now preserved in response headers of fetch requests ([testcafe-hammerhead/#2334](https://github.com/DevExpress/testcafe-hammerhead/issues/2334))
* The `document.title` for an `iframe` without `src` can now be correctly obtained in Firefox ([PR testcafe-hammerhead/#2466](https://github.com/DevExpress/testcafe-hammerhead/pull/2466))
* TestCafe UI is now displayed correctly if the tested page's body content is added dynamically ([PR testcafe-hammerhead/#2454](https://github.com/DevExpress/testcafe-hammerhead/pull/2454))
* Service Workers now receive `fetch` events ([testcafe-hammerhead/#2412](https://github.com/DevExpress/testcafe-hammerhead/issues/2412))
* Fixed the case of headers sent to the web app server ([testcafe-hammerhead/#2344](https://github.com/DevExpress/testcafe-hammerhead/issues/2344))
* `Location` objects in `iframes` without `src` now contain the correct data ([PR testcafe-hammerhead/#2448](https://github.com/DevExpress/testcafe-hammerhead/pull/2448))
* Native function wrappers are now converted to strings correctly ([testcafe-hammerhead/#2394](https://github.com/DevExpress/testcafe-hammerhead/issues/2394))
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,32 @@ To set the timeout for all selectors, pass it to the [runner.run](../../referenc

During the timeout, the selector is re-executed until it returns a DOM node or the timeout is exceeded. If TestCafe cannot find the corresponding node in the DOM, the test fails.

> Note that you can specify that the node returned by the selector should also be visible. To do this, use the [visibilityCheck](../../reference/test-api/selector/constructor.md#optionsvisibilitycheck) option.
> You can specify that the selector should only return visible nodes. To do this, use the [visibilityCheck](../../reference/test-api/selector/constructor.md#optionsvisibilitycheck) option.
Selector timeouts have no effect on [Selector.exists](../../reference/test-api/selector/exists.md) and [Selector.count](../../reference/test-api/selector/count.md) properties. These properties are evaluated immediately regardless of a timeout. To apply a timeout to `exists` and `count` assertions, pass the timeout to the assertion method (`expect.ok`, `expect.eql`, etc.).

```js
import { Selector } from 'testcafe';

fixture `My fixture`
.page `http://www.example.com/`;

const timedOutSelector = Selector('#element-id', {timeout: 10000});
const immediateSelector = Selector('#element-id');

test('Test timeouts', async t => {
await t.expect(timedOutSelector.exists).ok();
await t.expect(immediateSelector.exists).ok();
await t.expect(timedOutSelector.count).eql(1);
await t.expect(immediateSelector.count).eql(1);
//these assertions execute immediately regardless of the selector timeout

await t.expect(immediateSelector.exists).ok({timeout: 10000});
await t.expect(timedOutSelector.exists).ok({timeout: 10000});
await t.expect(immediateSelector.count).eql(1, 'count elements', {timeout: 10000});
await t.expect(timedOutSelector.count).eql(1, 'count elements', {timeout: 10000});
//these assertions retry within the assertion timeout specified
```
## Debug Selectors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Property | Description
`executor` | An [executor](https://circleci.com/docs/2.0/configuration-reference/#executors-requires-version-21) that defines the environment in which this job runs. This example uses the default executor from the `node` orb. The `tag` property specifies that the LTS version of Node.js should be used.
`steps` | The job's [steps](https://circleci.com/docs/2.0/jobs-steps/#steps-overview).
`checkout` | Checks out code from the `testcafe-ci-demo` repository. This is a pre-defined step (see [checkout](https://circleci.com/docs/2.0/configuration-reference/#checkout)).
`node/install-packages` | A step from the `node` orb that installs the project's dependencies (see [install-packages](https://circleci.com/developer/orbs/orb/circleci/node#commands-install-packages)).
`node/install-packages` | A step from the `node` orb that installs the project's dependencies (see [install-packages](https://circleci.com/developer/orbs/orb/circleci/node)).
`run` | The [run](https://circleci.com/docs/2.0/configuration-reference/#run) step invokes shell commands. In this example, `run` executes the `npm test` script.
`store_test_results` | Uploads test results to the specified directory (see [store_test_results](https://circleci.com/docs/2.0/configuration-reference/#store_test_results)).
`workflows` | A [workflow](https://circleci.com/docs/2.0/workflows/) that runs the `test` job.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "testcafe",
"description": "Automated browser testing for the modern web development stack.",
"license": "MIT",
"version": "1.10.0-rc.4",
"version": "1.10.0-rc.5",
"author": {
"name": "Developer Express Inc.",
"url": "https://www.devexpress.com/"
Expand Down
14 changes: 9 additions & 5 deletions src/compiler/test-file/test-file-parser-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ import { RUNTIME_ERRORS } from '../../errors/types';
const METHODS_SPECIFYING_NAME = ['only', 'skip'];
const COMPUTED_NAME_TEXT_TMP = '<computed name>(line: %s)';

function cleanLoc (loc) {
function getLoc (loc) {
// NOTE: Don't modify the Babel's parser data structure
const locCopy = Object.assign({}, loc);

// NOTE: 'fileName' and 'identifierName' fields with 'undefined' values added in the SourceLocation class constructor.
// https://github.com/babel/babel/blob/d51aa6d76177b544590cdfe3868f9f4d33d8813d/packages/babel-parser/src/util/location.js#L22
// Since this is useless information, we remove it.
delete locCopy.filename;
delete locCopy.identifierName;

delete loc.filename;
delete loc.identifierName;
return locCopy;
}

export class Fixture {
constructor (name, start, end, loc, meta) {
this.name = name;
this.loc = cleanLoc(loc);
this.loc = getLoc(loc);
this.start = start;
this.end = end;
this.meta = meta;
Expand All @@ -29,7 +33,7 @@ export class Fixture {
export class Test {
constructor (name, start, end, loc, meta) {
this.name = name;
this.loc = cleanLoc(loc);
this.loc = getLoc(loc);
this.start = start;
this.end = end;
this.meta = meta;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -794,3 +794,11 @@ test('messages formatting', async t => {
.expect(messages.warn.length).eql(0)
.expect(messages.error.length).eql(0);
});

test('action result coercion', async t => {
function test (): Promise<void> {
return t.expect(1).ok();
}

test();
});
Original file line number Diff line number Diff line change
Expand Up @@ -789,3 +789,11 @@ const getInputValue = ClientFunction(() => (<HTMLInputElement>document.getElemen
.expect(messages.warn.length).eql(0)
.expect(messages.error.length).eql(0);
})();

(async () => {
function test (): Promise<void> {
return t.expect(1).ok();
}

test();
})();
8 changes: 8 additions & 0 deletions test/server/parse-fixture-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ function testFixtureParser (dir, expectedStructure, fileParser, codeParser) {
.then(function (structure) {
expect(structure).eql(expected);
expect(codeParser(fileContent)).eql(expected);

Object.values(structure).forEach(fixture => {
expect(fixture.loc).not.undefined;

fixture.tests.forEach(test => {
expect(test.loc).not.undefined;
});
});
});
});

Expand Down
4 changes: 2 additions & 2 deletions ts-defs-src/test-api/test-controller.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,9 @@ interface TestController {
removeRequestHooks(...hooks: object[]): TestControllerPromise;
}

interface TestControllerPromise extends TestController, Promise<unknown> {
interface TestControllerPromise<T=any> extends TestController, Promise<T> {
}

interface WindowDescriptorPromise extends TestControllerPromise, Promise<WindowDescriptor> {
interface WindowDescriptorPromise extends TestControllerPromise<WindowDescriptor> {
}

0 comments on commit 3595ce1

Please sign in to comment.