From f314aa6f45741bc98a837744f523f2b6fdc07fee Mon Sep 17 00:00:00 2001 From: Natu <11683678+Nuarat@users.noreply.github.com> Date: Thu, 28 Jun 2018 14:03:13 +0300 Subject: [PATCH 001/184] Updated the link to StackOverflow (#2569) Instead of "TestCafe" selected "questions with the TestCafe tag", because it is precisely what one will see when clicks the link. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 02e871f6..847bedde 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ To display this badge, add the following code to your repository readme: ## Contributing Report bugs and request features on our [issues page](https://github.com/DevExpress/testcafe/issues).
-Ask and answer questions on StackOverflow. We review and answer questions with the [TestCafe](https://stackoverflow.com/questions/tagged/testcafe) tag.
+Ask and answer questions on StackOverflow. We review and answer [questions with the TestCafe tag](https://stackoverflow.com/questions/tagged/testcafe).
For more information on how to help us improve TestCafe, see the [CONTRIBUTING.md](https://github.com/DevExpress/testcafe/blob/master/CONTRIBUTING.md). You can use these plugin generators to create your own plugins: From a9a8146a0988fe207669cf88b088bac27894e64e Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 29 Jun 2018 18:41:19 +0300 Subject: [PATCH 002/184] Add info about running remote browsers from Docker (#2574) --- .../using-testcafe-docker-image.md | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/using-testcafe-docker-image.md b/docs/articles/documentation/using-testcafe/using-testcafe-docker-image.md index 03152315..5d60139f 100644 --- a/docs/articles/documentation/using-testcafe/using-testcafe-docker-image.md +++ b/docs/articles/documentation/using-testcafe/using-testcafe-docker-image.md @@ -47,16 +47,44 @@ This command takes the following parameters: You can run tests in the Chromium and Firefox browsers preinstalled to the Docker image. Add the `--no-sandbox` flag to Chromium if the container is run in the unprivileged mode. - Use the [remote browser](command-line-interface.md#remote-browsers) to run tests on a mobile device. To do this, you need to add the `-P` flag to the `docker run` command and specify the `remote` keyword as the browser name. - - `docker run -v //d/tests:/tests -P -it testcafe/testcafe remote /tests/test.js` - You can pass a glob instead of the directory path in TestCafe parameters. `docker run -v //d/tests:/tests -it testcafe/testcafe firefox /tests/**/*.js` > If tests use other Node.js modules, these modules should be located in the tests directory or its child directories. TestCafe will not be able to find modules in the parent directories. +## Testing in Remote Browsers + +You need to add the following options to the `docker run` command to run tests in a [remote browser](command-line-interface.md#remote-browsers), e.g. on a mobile device. + +* add the `-P` flag to publish all exposed ports; +* use the [--hostname](command-line-interface.md#--hostname-name) TestCafe flag to specify the host machine name; +* specify the `remote` keyword as the browser name. + +The example below shows a command that runs tests in a remote browser. + +```sh +docker run -v /d/tests:/tests -P -it testcafe/testcafe --hostname $EXTERNAL_HOSTNAME remote /tests/test.js +``` + +where `$EXTERNAL_HOSTNAME` is the host machine name. + +If Docker reports that the default ports `1337` and `1338` are occupied by some other process, kill this process or choose different ports. Use the `netstat` command to determine which process occupies the default ports. + +OS | Command +------- | --------- +Windows | `netstat -ano` +macOS | `netstat -anv` +Linux | `netstat -anp` + +If you choose to use different ports, publish them in the Docker container (use the `-p` flag) and specify them to TestCafe (use the [--ports](command-line-interface.md#--ports-port1port2) option). + +```sh +docker run -v /d/tests:/tests -p $PORT1 -p $PORT2 -it testcafe/testcafe --hostname $EXTERNAL_HOSTNAME --ports $PORT1,$PORT2 remote /tests/test.js +``` + +where `$PORT1` and `$PORT2` are vacant container's ports, `$EXTERNAL_HOSTNAME` is the host machine name. + ## Testing Heavy Websites If you are testing a heavy website, you may need to allocate extra resources for the Docker image. From ca2b2dc167ae23a22dd0f01533a2a01e1bfa2e07 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Fri, 29 Jun 2018 18:51:22 +0300 Subject: [PATCH 003/184] enable `noImplicitAny` and disable `skipLibCheck` in TS compiler (closes #2497,#2457) (#2561) * enable `noImplicitAny` and disable `skipLibCheck` in TS compiler (closes #2497,#2457) * add separate test to --noImplicitAny * change --implicitAny to --strict * remove unrequired test --- test/server/compiler-test.js | 17 +++++++++++ .../test-suites/typescript-basic/testfile1.ts | 2 +- .../implicitAny.d.ts | 1 + .../typescript-defs/client-functions.ts | 14 ++++----- .../typescript-defs/request-hooks.ts | 29 +++++++++++++------ .../test-suites/typescript-defs/selectors.ts | 28 +++++++++--------- .../typescript-defs/test-controller.ts | 6 ++-- ts-defs/index.d.ts | 6 ++-- 8 files changed, 66 insertions(+), 37 deletions(-) create mode 100644 test/server/data/test-suites/typescript-compile-errors/implicitAny.d.ts diff --git a/test/server/compiler-test.js b/test/server/compiler-test.js index dd93089d..4b1a8eda 100644 --- a/test/server/compiler-test.js +++ b/test/server/compiler-test.js @@ -8,6 +8,7 @@ const exportableLib = require('../../lib/api/exportable-lib'); const createStackFilter = require('../../lib/errors/create-stack-filter.js'); const assertError = require('./helpers/assert-error').assertError; const compile = require('./helpers/compile'); +const { exec } = require('child_process'); describe('Compiler', function () { var testRunMock = { id: 'yo' }; @@ -197,6 +198,22 @@ describe('Compiler', function () { }); }); + it('Should complile ts-definitions successfully with the `--strict` option enabled', function () { + var tscPath = path.resolve('node_modules/typescript/bin/tsc'); + var defsPath = path.resolve('ts-defs/index.d.ts'); + var args = '--strict'; + var command = `node ${tscPath} ${defsPath} ${args}`; + + return new Promise(resolve => { + exec(command, (error, stdout) => { + resolve({ error, stdout }); + }); + }).then(value => { + expect(value.stdout).eql(''); + expect(value.error).is.null; + }); + }); + it('Should provide API definitions', function () { const typescriptDefsFolder = 'test/server/data/test-suites/typescript-defs/'; const src = []; diff --git a/test/server/data/test-suites/typescript-basic/testfile1.ts b/test/server/data/test-suites/typescript-basic/testfile1.ts index dc202efc..6e587e47 100644 --- a/test/server/data/test-suites/typescript-basic/testfile1.ts +++ b/test/server/data/test-suites/typescript-basic/testfile1.ts @@ -26,7 +26,7 @@ test('Fixture2Test1', async() => { // Decorators function foo () { - return function (target, propertyKey: string, descriptor: PropertyDescriptor) { + return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { Object.assign({}, { msg: `target is ${target}` }); }; } diff --git a/test/server/data/test-suites/typescript-compile-errors/implicitAny.d.ts b/test/server/data/test-suites/typescript-compile-errors/implicitAny.d.ts new file mode 100644 index 00000000..69ba4793 --- /dev/null +++ b/test/server/data/test-suites/typescript-compile-errors/implicitAny.d.ts @@ -0,0 +1 @@ +export function log (text): boolean; \ No newline at end of file diff --git a/test/server/data/test-suites/typescript-defs/client-functions.ts b/test/server/data/test-suites/typescript-defs/client-functions.ts index bd2a33f7..2d3478b0 100644 --- a/test/server/data/test-suites/typescript-defs/client-functions.ts +++ b/test/server/data/test-suites/typescript-defs/client-functions.ts @@ -17,7 +17,7 @@ test('Dispatch', async() => { }); test('Call with arguments', async() => { - const getElementText = ClientFunction((className, idx) => { + const getElementText = ClientFunction((className: string, idx: number) => { return document.querySelectorAll('.' + className)[idx].textContent; }); @@ -91,11 +91,11 @@ test('Error in Promise', async() => { await fn(); }); -const selectByClassName = ClientFunction(className => document.querySelectorAll('.' + className)); -const nthByClass = ClientFunction((className, n) => selectByClassName(className)[n], {dependencies: {selectByClassName}}); +const selectByClassName: any = ClientFunction((className: string) => document.querySelectorAll('.' + className)); +const nthByClass = ClientFunction((className: string, n: number) => selectByClassName(className)[n], {dependencies: {selectByClassName}}); test('ClientFunction call with complex argument types', async() => { - const fn = ClientFunction((re, err, undef, nan) => { + const fn = ClientFunction((re: any, err: any, undef: any, nan: any) => { return re instanceof RegExp && re.source === '\\S+' && err instanceof Error && @@ -131,20 +131,20 @@ test('ClientFunction with function argument', async() => { }); } - const hfn = ClientFunction(fn => fn()); + const hfn = ClientFunction((fn: Function) => fn()); const answer = await hfn(getAnswer); expect(answer).eql(42); }); test('Async/await in function argument of ClientFunction', async() => { - const hfn = ClientFunction(fn => fn()); + const hfn = ClientFunction((fn: Function) => fn()); await hfn(async() => Promise.resolve()); }); test('ClientFunction with ClientFunction argument', async() => { - const hfn = ClientFunction(fn => fn()); + const hfn = ClientFunction((fn: Function) => fn()); const location = await hfn(getLocation); expect(location).eql('http://localhost:3000/fixtures/api/es-next/client-function/pages/index.html'); diff --git a/test/server/data/test-suites/typescript-defs/request-hooks.ts b/test/server/data/test-suites/typescript-defs/request-hooks.ts index a4a32220..2fe13353 100644 --- a/test/server/data/test-suites/typescript-defs/request-hooks.ts +++ b/test/server/data/test-suites/typescript-defs/request-hooks.ts @@ -6,17 +6,21 @@ class CustomRequestHook extends RequestHook { super(); } - onRequest(event) { + onRequest (event: object) { } - onResponse(event) { + onResponse (event: object) { } } const customHook = new CustomRequestHook(); -const logger = RequestLogger('example.com', {logRequestBody: true}); +const logger1 = RequestLogger('example.com', {logRequestBody: true}); + +const logger2 = RequestLogger(req => { + return req.url === 'example.com'; +}); const mock = RequestMock() .onRequestTo(/example.com/) @@ -24,18 +28,25 @@ const mock = RequestMock() .onRequestTo({url: 'https://example.com'}) .respond(null, 204) .onRequestTo('https://example.com') - .respond(null, 200, {'x-frame-options': 'deny'}); + .respond(null, 200, {'x-frame-options': 'deny'}) + .onRequestTo(req => { + return req.url === 'https://example.com'; + }).respond((req, res) => { + if (req.url === 'https://example.com') + res.statusCode = '200'; + }); + fixture `Request Hooks` - .requestHooks(mock, logger, customHook); + .requestHooks(mock, logger1, logger2, customHook); test - .requestHooks(logger) + .requestHooks(logger1) ('Request hook', async t => { await t .addRequestHooks(mock) .removeRequestHooks(mock) - .expect(logger.contains(t => t.request.statusCode === 200)).ok() - .expect(logger.count(t => t.request.statusCode === 200)).eql(1) - .expect(logger.requests[0].request.body === 'test').ok(); + .expect(logger1.contains((t: any) => t.request.statusCode === 200)).ok() + .expect(logger1.count((t: any) => t.request.statusCode === 200)).eql(1) + .expect(logger1.requests[0].request.body === 'test').ok(); }); diff --git a/test/server/data/test-suites/typescript-defs/selectors.ts b/test/server/data/test-suites/typescript-defs/selectors.ts index 839d84b0..eda92537 100644 --- a/test/server/data/test-suites/typescript-defs/selectors.ts +++ b/test/server/data/test-suites/typescript-defs/selectors.ts @@ -517,7 +517,7 @@ test('Combination of filter methods', async t => { expect(el.id).eql('el4'); // Selector should maintain filter when used as parameter - const getId = ClientFunction(getEl => getEl().id); + const getId = ClientFunction((getEl: Function) => getEl().id); let id = await getId(selector); @@ -708,30 +708,30 @@ test('Selector "count" and "exists" properties', async() => { expect(await Selector('form').find('input').count).eql(2); expect(await Selector('.notexists').count).eql(0); - const witClass = Selector(className => document.getElementsByClassName(className)); + const withClass = Selector(className => document.getElementsByClassName(className)); - expect(await witClass('idxEl').count).eql(4); - expect(await witClass('idxEl').withText('Hey?!').count).eql(2); + expect(await withClass('idxEl').count).eql(4); + expect(await withClass('idxEl').withText('Hey?!').count).eql(2); expect(await Selector('.idxEl').exists).to.be.true; expect(await Selector('.idxEl').nth(2).exists).to.be.true; expect(await Selector('form').find('input').exists).to.be.true; expect(await Selector('.notexists').exists).to.be.false; - expect(await witClass('idxEl').exists).to.be.true; - expect(await witClass('idxEl').withText('Hey?!').exists).to.be.true; - expect(await witClass('idxEl').withText('testtesttest').exists).to.be.false; + expect(await withClass('idxEl').exists).to.be.true; + expect(await withClass('idxEl').withText('Hey?!').exists).to.be.true; + expect(await withClass('idxEl').withText('testtesttest').exists).to.be.false; }); test('Selector filter dependencies and index argument', async t => { - const isOne = ClientFunction(i => i === 1); - const isTwo = ClientFunction(i => i === 2); - const firstNode = ClientFunction((node, i) => isOne(i)); + const isOne = ClientFunction((i: number) => i === 1); + const isTwo = ClientFunction((i: number) => i === 2); + const firstNode = ClientFunction((node: Node, i: number) => isOne(i)); await t - .expect(Selector('.idxEl').filter((node, i) => !!isTwo(i), {isTwo}).id).eql('el3') - .expect(Selector('.find-parent').find((node, i) => !!isOne(i), {isOne}).id).eql('find-child2') - .expect(Selector('#childDiv').parent((node, i) => !!isTwo(i), {isTwo}).id).eql('p2') - .expect(Selector('.find-parent').child((node, i) => !!isOne(i), {isOne}).id).eql('find-child3'); + .expect(Selector('.idxEl').filter((node: Node, i: number) => !!isTwo(i), {isTwo}).id).eql('el3') + .expect(Selector('.find-parent').find((node: Node, i: number) => !!isOne(i), {isOne}).id).eql('find-child2') + .expect(Selector('#childDiv').parent((node: Node, i: number) => !!isTwo(i), {isTwo}).id).eql('p2') + .expect(Selector('.find-parent').child((node: Node, i: number) => !!isOne(i), {isOne}).id).eql('find-child3'); }); test('Selector filter origin node argument', async t => { diff --git a/test/server/data/test-suites/typescript-defs/test-controller.ts b/test/server/data/test-suites/typescript-defs/test-controller.ts index 30d45975..3f9bc638 100644 --- a/test/server/data/test-suites/typescript-defs/test-controller.ts +++ b/test/server/data/test-suites/typescript-defs/test-controller.ts @@ -216,7 +216,7 @@ test('Get UA', async t => { throw await t.eval(() => navigator.userAgent); }); -const getById = ClientFunction(id => document.getElementById(id)); +const getById = ClientFunction((id: string) => document.getElementById(id)); test('Eval with dependencies', async t => { @@ -463,7 +463,7 @@ test('Expected confirm after an action', async t => { }); test('Expected confirm after an action (with dependencies)', async t => { - var dialogHandler = ClientFunction((type, text) => { + var dialogHandler = ClientFunction((type: string, text: string) => { if (type === 'confirm' && text === 'Confirm?') return true; @@ -478,7 +478,7 @@ test('Expected confirm after an action (with dependencies)', async t => { }); test('Expected confirm after an action (client function)', async t => { - var dialogHandler = ClientFunction((type, text) => { + var dialogHandler = ClientFunction((type: string, text: string) => { if (type === 'confirm' && text === 'Confirm?') return true; diff --git a/ts-defs/index.d.ts b/ts-defs/index.d.ts index f771b2a3..9d141a2d 100644 --- a/ts-defs/index.d.ts +++ b/ts-defs/index.d.ts @@ -918,14 +918,14 @@ interface RequestMock { * Specifies requests to intercept * @param filter - Specifies which requests should be mocked with a response that follows in the `respond` method. */ - onRequestTo(filter: string | RegExp | object | ((req, res) => boolean)): RequestMock; + onRequestTo(filter: string | RegExp | object | ((req: any) => boolean)): RequestMock; /** * Specifies the mocked response. * @param body - The mocked response body. * @param statusCode - The response status code. * @param headers - Custom headers added to the response in the property-value form. */ - respond(body?: object | string | ((req, res) => any), statusCode?: number, headers?: object): RequestMock; + respond(body?: object | string | ((req: any, res: any) => any), statusCode?: number, headers?: object): RequestMock; } interface Request { @@ -1570,7 +1570,7 @@ declare module 'testcafe' { /** * Creates a request logger */ - export function RequestLogger(filter?: string | RegExp | object | ((req, res) => boolean), options?: RequestLoggerOptions): RequestLogger; + export function RequestLogger(filter?: string | RegExp | object | ((req: any) => boolean), options?: RequestLoggerOptions): RequestLogger; /** The RequestHook class used to create a custom HTTP request hook **/ export class RequestHook { From 4b78d821024c5c6a51456b8a9894faae7565c460 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Sat, 30 Jun 2018 16:14:10 +0300 Subject: [PATCH 004/184] [docs] Add info about waiting for redirect (#2547) * Add info about waiting for redirect * Fix a broken link * Address Miher's remarks * Address more miher's remarks * Fix a broken link --- docs/README.md | 2 +- .../2017-4-26-testcafe-v0-15-0-released.md | 2 +- .../articles/documentation/test-api/README.md | 2 +- .../test-api/actions/navigate.md | 5 ++++- ...pear.md => built-in-waiting-mechanisms.md} | 19 ++++++++++++------- .../selectors/selector-options.md | 2 +- docs/nav/nav-menu.yml | 4 ++-- 7 files changed, 22 insertions(+), 14 deletions(-) rename docs/articles/documentation/test-api/{waiting-for-page-elements-to-appear.md => built-in-waiting-mechanisms.md} (84%) diff --git a/docs/README.md b/docs/README.md index c886dd8c..5afa119d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -70,7 +70,7 @@ * [Specifying Which Requests are Handled by the Hook](articles/documentation/test-api/intercepting-http-requests/specifying-which-requests-are-handled-by-the-hook.md) * [Attaching Hooks to Tests and Fixtures](articles/documentation/test-api/intercepting-http-requests/attaching-hooks-to-tests-and-fixtures.md) * [requestOptions Object](articles/documentation/test-api/intercepting-http-requests/requestoptions-object.md) - * [Waiting for Page Elements to Appear](articles/documentation/test-api/waiting-for-page-elements-to-appear.md) + * [Built-In Waiting Mechanisms](articles/documentation/test-api/built-in-waiting-mechanisms.md) * [Authentication](articles/documentation/test-api/authentication/README.md) * [User Roles](articles/documentation/test-api/authentication/user-roles.md) * [HTTP Authentication](articles/documentation/test-api/authentication/http-authentication.md) diff --git a/docs/articles/blog/2017-4-26-testcafe-v0-15-0-released.md b/docs/articles/blog/2017-4-26-testcafe-v0-15-0-released.md index 53fe367c..e1b75c96 100644 --- a/docs/articles/blog/2017-4-26-testcafe-v0-15-0-released.md +++ b/docs/articles/blog/2017-4-26-testcafe-v0-15-0-released.md @@ -103,7 +103,7 @@ docker pull testcafe/testcafe docker run -v //user/tests:/tests -it testcafe/testcafe firefox tests/**/*.js ``` -To learn more, see [Using TestCafe Docker Image](https://devexpress.github.io/testcafe/documentation/using-testcafe/installing-testcafe.html#using-testcafe-docker-image) +To learn more, see [Using TestCafe Docker Image](https://devexpress.github.io/testcafe/documentation/using-testcafe/using-testcafe-docker-image.html) ### ⚙ Support for Internet access proxies ([#1206](https://github.com/DevExpress/testcafe/issues/1206)) diff --git a/docs/articles/documentation/test-api/README.md b/docs/articles/documentation/test-api/README.md index 96874e4f..8e0f20dd 100644 --- a/docs/articles/documentation/test-api/README.md +++ b/docs/articles/documentation/test-api/README.md @@ -20,7 +20,7 @@ The following topics describe the API used to manipulate the webpage and check i * [Assertions](assertions/README.md) * [Obtaining Data From the Client](obtaining-data-from-the-client/README.md) * [Intercepting HTTP Requests](intercepting-http-requests/README.md) -* [Waiting for Page Elements to Appear](waiting-for-page-elements-to-appear.md) +* [Built-In Waiting Mechanisms](built-in-waiting-mechanisms.md) * [Authentication](authentication/README.md) * [Pausing the Test](pausing-the-test.md) * [Handling Native Dialogs](handling-native-dialogs.md) diff --git a/docs/articles/documentation/test-api/actions/navigate.md b/docs/articles/documentation/test-api/actions/navigate.md index 47f7efa8..9fff7af3 100644 --- a/docs/articles/documentation/test-api/actions/navigate.md +++ b/docs/articles/documentation/test-api/actions/navigate.md @@ -40,4 +40,7 @@ test('Navigate to local pages', async t => { .navigateTo('file:///user/my-website/index.html') .navigateTo('../my-project/index.html'); }); -``` \ No newline at end of file +``` + +TestCafe automatically waits for the server to respond after a redirect happens. +The test is resumed if the server does not respond within **15** seconds. \ No newline at end of file diff --git a/docs/articles/documentation/test-api/waiting-for-page-elements-to-appear.md b/docs/articles/documentation/test-api/built-in-waiting-mechanisms.md similarity index 84% rename from docs/articles/documentation/test-api/waiting-for-page-elements-to-appear.md rename to docs/articles/documentation/test-api/built-in-waiting-mechanisms.md index 0578c918..50b7cd01 100644 --- a/docs/articles/documentation/test-api/waiting-for-page-elements-to-appear.md +++ b/docs/articles/documentation/test-api/built-in-waiting-mechanisms.md @@ -1,14 +1,14 @@ --- layout: docs -title: Waiting for Page Elements to Appear -permalink: /documentation/test-api/waiting-for-page-elements-to-appear.html +title: Built-In Waiting Mechanisms +permalink: /documentation/test-api/built-in-waiting-mechanisms.html --- -# Waiting for Page Elements to Appear +# Built-In Waiting Mechanisms -TestCafe has a built-in automatic waiting mechanism, so that it does not need dedicated API to wait for page elements to appear. +TestCafe has built-in automatic waiting mechanisms, so that it does not need dedicated API to wait for page elements to appear or redirects to happen. -This topic describes how the automatic waiting mechanism works with [test actions](actions/README.md), -[assertions](assertions/README.md) and [selectors](selecting-page-elements/selectors/README.md). +This topic describes how these mechanisms work with [test actions](actions/README.md), +[assertions](assertions/README.md), [selectors](selecting-page-elements/selectors/README.md) and navigation. ## Waiting for Action Target Elements @@ -109,4 +109,9 @@ test('My test', async t => { // or the timeout passes. .expect(nameInput.value).eql('Peter Parker'); }); -``` \ No newline at end of file +``` + +## Waiting for Redirects + +When an action triggers a redirect, TestCafe automatically waits for the server to respond. +The test is resumed if the server does not respond within **15** seconds. \ No newline at end of file diff --git a/docs/articles/documentation/test-api/selecting-page-elements/selectors/selector-options.md b/docs/articles/documentation/test-api/selecting-page-elements/selectors/selector-options.md index e232dc4a..c3346ba6 100644 --- a/docs/articles/documentation/test-api/selecting-page-elements/selectors/selector-options.md +++ b/docs/articles/documentation/test-api/selecting-page-elements/selectors/selector-options.md @@ -65,7 +65,7 @@ This option is in effect when TestCafe waits for the selector to return a page e If the target element is not visible, the selector throws an exception in all these cases. Note that when a selector is passed to a [test action](../../actions/README.md) as an identifier for the target element, -TestCafe [requires](../../waiting-for-page-elements-to-appear.md#waiting-for-action-target-elements) that the target element is visible regardless of the `visibilityCheck` option. +TestCafe [requires](../../built-in-waiting-mechanisms.md#waiting-for-action-target-elements) that the target element is visible regardless of the `visibilityCheck` option. Unlike filter functions, the `visibilityCheck` option does not change the matching set of the selector. diff --git a/docs/nav/nav-menu.yml b/docs/nav/nav-menu.yml index 99700380..59bf7312 100644 --- a/docs/nav/nav-menu.yml +++ b/docs/nav/nav-menu.yml @@ -150,8 +150,8 @@ url: /documentation/test-api/intercepting-http-requests/attaching-hooks-to-tests-and-fixtures.md - name: requestOptions Object url: /documentation/test-api/intercepting-http-requests/requestoptions-object.md - - name: Waiting for Page Elements to Appear - url: /documentation/test-api/waiting-for-page-elements-to-appear.md + - name: Built-In Waiting Mechanisms + url: /documentation/test-api/built-in-waiting-mechanisms.md - name: Authentication url: /documentation/test-api/authentication/README.md content: From 73c7f13f6e9d867934ecc87173e99a00d606492b Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Thu, 5 Jul 2018 12:48:41 +0300 Subject: [PATCH 005/184] [WIP] Fix unnecessary waiting for page loading on a Logify page (#2503) --- src/client/core/utils/event.js | 51 +++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/client/core/utils/event.js b/src/client/core/utils/event.js index 82bbfa12..f84b64a8 100644 --- a/src/client/core/utils/event.js +++ b/src/client/core/utils/event.js @@ -38,37 +38,44 @@ export function unbind (el, event, handler, useCapture) { // Document ready const waitForDomContentLoaded = () => { - return new Promise(resolve => { - var isReady = false; + // NOTE: We can't use a regular Promise here, because window.load event can happen in the same event loop pass + // The default Promise will call resolve handlers in the next pass, and load event will be lost. + const resolveHandlers = []; - function ready () { - if (isReady) - return; + function createPromiseResolver (resolveHandler) { + return new Promise(resolve => resolveHandlers.push(() => resolve(resolveHandler()))); + } - if (!document.body) { - nativeMethods.setTimeout.call(window, ready, 1); - return; - } + let isReady = false; - isReady = true; + function ready () { + if (isReady) + return; - resolve(); + if (!document.body) { + nativeMethods.setTimeout.call(window, ready, 1); + return; } - function onContentLoaded () { - if (!domUtils.isIFrameWindowInDOM(window) && !domUtils.isTopWindow(window)) - return; + isReady = true; - unbind(document, 'DOMContentLoaded', onContentLoaded); - ready(); - } + resolveHandlers.forEach(handler => handler()); + } + + function onContentLoaded () { + if (!domUtils.isIFrameWindowInDOM(window) && !domUtils.isTopWindow(window)) + return; + unbind(document, 'DOMContentLoaded', onContentLoaded); + ready(); + } + + if (document.readyState === 'complete') + nativeMethods.setTimeout.call(window, onContentLoaded, 1); + else + bind(document, 'DOMContentLoaded', onContentLoaded); - if (document.readyState === 'complete') - nativeMethods.setTimeout.call(window, onContentLoaded, 1); - else - bind(document, 'DOMContentLoaded', onContentLoaded); - }); + return { then: handler => createPromiseResolver(handler) }; }; const waitForWindowLoad = () => new Promise(resolve => bind(window, 'load', resolve)); From bd034a1dee1f58ec4cc5244d6b3dc6f14de0a760 Mon Sep 17 00:00:00 2001 From: Artem Lavrov Date: Thu, 5 Jul 2018 13:11:54 +0300 Subject: [PATCH 006/184] update hammerhead (close #2534, close #2539) (#2588) * update hammerhead * fix tests after hammerhead update --- package.json | 2 +- src/client/automation/playback/move/index.js | 4 --- src/client/automation/playback/rclick.js | 4 +-- test/client/fixtures/automation/click-test.js | 26 +++++++++-------- .../client/fixtures/automation/rclick-test.js | 28 +++++++++++-------- 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 9a8bdbc3..42c1a125 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.3", - "testcafe-hammerhead": "14.1.0", + "testcafe-hammerhead": "14.1.1", "testcafe-legacy-api": "3.1.7", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", diff --git a/src/client/automation/playback/move/index.js b/src/client/automation/playback/move/index.js index fad02a3b..77ff80da 100644 --- a/src/client/automation/playback/move/index.js +++ b/src/client/automation/playback/move/index.js @@ -18,7 +18,6 @@ import dragAndDropFirstMoveEventSequence from './event-sequence/drag-and-drop-fi var Promise = hammerhead.Promise; var nativeMethods = hammerhead.nativeMethods; -var browserUtils = hammerhead.utils.browser; var featureDetection = hammerhead.utils.featureDetection; var htmlUtils = hammerhead.utils.html; var urlUtils = hammerhead.utils.url; @@ -270,7 +269,6 @@ export default class MoveAutomation { } _emulateEvents (currentElement) { - var whichButton = this.holdLeftButton ? eventUtils.WHICH_PARAMETER.leftButton : eventUtils.WHICH_PARAMETER.noButton; var button = this.holdLeftButton ? eventUtils.BUTTONS_PARAMETER.leftButton : eventUtils.BUTTONS_PARAMETER.noButton; var devicePoint = getDevicePoint({ x: this.x, y: this.y }); @@ -279,8 +277,6 @@ export default class MoveAutomation { clientY: this.y, screenX: devicePoint.x, screenY: devicePoint.y, - button: 0, - which: browserUtils.isWebKit ? whichButton : 1, buttons: button, ctrl: this.modifiers.ctrl, alt: this.modifiers.alt, diff --git a/src/client/automation/playback/rclick.js b/src/client/automation/playback/rclick.js index 0476a4e9..f779e229 100644 --- a/src/client/automation/playback/rclick.js +++ b/src/client/automation/playback/rclick.js @@ -87,9 +87,7 @@ export default class RClickAutomation extends VisibleElementAutomation { clientY: clientPoint.y, screenX: devicePoint.x, screenY: devicePoint.y, - button: eventUtils.BUTTON.right, - which: eventUtils.WHICH_PARAMETER.rightButton, - buttons: eventUtils.BUTTONS_PARAMETER.rightButton + button: eventUtils.BUTTON.right }, this.modifiers) }; diff --git a/test/client/fixtures/automation/click-test.js b/test/client/fixtures/automation/click-test.js index e80a24d5..ac6cf6ea 100644 --- a/test/client/fixtures/automation/click-test.js +++ b/test/client/fixtures/automation/click-test.js @@ -762,7 +762,7 @@ $(document).ready(function () { equal(e.button, 0); - if (browserUtils.isIE || browserUtils.isFirefox) + if (!browserUtils.isSafari) equal(e.buttons, 1); ok(!mouseupRaised && !clickRaised, 'mousedown event was raised first'); @@ -772,8 +772,8 @@ $(document).ready(function () { equal(e.button, 0); - if (browserUtils.isIE || browserUtils.isFirefox) - equal(e.buttons, 1); + if (!browserUtils.isSafari) + equal(e.buttons, 0); ok(mousedownRaised && !clickRaised, 'mouseup event was raised second'); }) @@ -782,8 +782,8 @@ $(document).ready(function () { equal(e.button, 0); - if (browserUtils.isIE || browserUtils.isFirefox) - equal(e.buttons, 1); + if (!browserUtils.isSafari) + equal(e.buttons, 0); ok(mousedownRaised && mouseupRaised, 'click event was raised third '); }); @@ -791,7 +791,12 @@ $(document).ready(function () { var pointerHandler = function (e) { equal(e.pointerType, browserUtils.version > 10 ? 'mouse' : 4); equal(e.button, 0); - equal(e.buttons, 1); + + if (e.type === 'pointerdown') + equal(e.buttons, 1); + + if (e.type === 'pointerup') + equal(e.buttons, 0); }; if (browserUtils.isIE && browserUtils.version > 11) { @@ -803,13 +808,12 @@ $(document).ready(function () { $el[0].onmspointerup = pointerHandler; } - - if (browserUtils.isFirefox || browserUtils.isIE9) - expect(10); - else if (browserUtils.isIE) + if (browserUtils.isIE) expect(16); - else + else if (browserUtils.isSafari) expect(7); + else + expect(10); var click = new ClickAutomation($el[0], new ClickOptions({ offsetX: 5, offsetY: 5 })); diff --git a/test/client/fixtures/automation/rclick-test.js b/test/client/fixtures/automation/rclick-test.js index ada0a23c..ae458326 100644 --- a/test/client/fixtures/automation/rclick-test.js +++ b/test/client/fixtures/automation/rclick-test.js @@ -105,7 +105,7 @@ $(document).ready(function () { equal(e.button, 2); - if (browserUtils.isIE || browserUtils.isFirefox) + if (!browserUtils.isSafari) equal(e.buttons, 2); ok(!mouseupRaised && !contextmenu, 'mousedown event was raised first'); @@ -116,8 +116,8 @@ $(document).ready(function () { equal(e.button, 2); - if (browserUtils.isIE || browserUtils.isFirefox) - equal(e.buttons, 2); + if (!browserUtils.isSafari) + equal(e.buttons, 0); ok(mousedownRaised && !contextmenu, 'mouseup event was raised second'); }); @@ -127,16 +127,20 @@ $(document).ready(function () { equal(e.button, 2); - if (browserUtils.isIE || browserUtils.isFirefox) - equal(e.buttons, 2); + if (!browserUtils.isSafari) + equal(e.buttons, 0); ok(mousedownRaised && mouseupRaised, 'click event was raised third '); }); var pointerHandler = function (e) { equal(e.pointerType, browserUtils.version > 10 ? 'mouse' : 4); - equal(e.button, 2); - equal(e.buttons, 2); + + if (e.type === 'pointerdown') + equal(e.buttons, 2); + + if (e.type === 'pointerup') + equal(e.buttons, 0); }; if (browserUtils.isIE && browserUtils.version > 11) { @@ -155,12 +159,12 @@ $(document).ready(function () { .then(function () { ok(mousedownRaised && mousedownRaised && contextmenu, 'mouse events were raised'); - if (browserUtils.isFirefox || browserUtils.isIE9) - expect(10); - else if (browserUtils.isIE) - expect(16); - else + if (browserUtils.isIE) + expect(14); + else if (browserUtils.isSafari) expect(7); + else + expect(10); startNext(); }); From 053e44f3cdecc296c04dbba1ad0d11dbd495ba89 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Thu, 5 Jul 2018 15:19:00 +0300 Subject: [PATCH 007/184] [docs] Add Studio promo (#2342) * Add Studio promo * Fix a link * Fix an article * Fix a broken link --- .../2018-05-15-testcafe-v0-20-0-released.md | 2 +- .../images/landing-page/studio-promo.png | Bin 0 -> 80740 bytes docs/articles/index.html | 11 +++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 docs/articles/images/landing-page/studio-promo.png diff --git a/docs/articles/blog/2018-05-15-testcafe-v0-20-0-released.md b/docs/articles/blog/2018-05-15-testcafe-v0-20-0-released.md index df57daf2..bb19fac6 100644 --- a/docs/articles/blog/2018-05-15-testcafe-v0-20-0-released.md +++ b/docs/articles/blog/2018-05-15-testcafe-v0-20-0-released.md @@ -21,7 +21,7 @@ See [Intercepting HTTP Requests](https://devexpress.github.io/testcafe/documenta TestCafe now allows you to bypass the proxy server when accessing specific resources. -To specify resources that require direct access, use the [--proxy-bypass](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--proxy-bypass-rules) flag in the command line or the [useProxy](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html) API method's parameters. +To specify resources that require direct access, use the [--proxy-bypass](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--proxy-bypass-rules) flag in the command line or the [useProxy](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#useproxy) API method's parameters. ```sh testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com --proxy-bypass localhost:8080,internal-resource.corp.mycompany.com diff --git a/docs/articles/images/landing-page/studio-promo.png b/docs/articles/images/landing-page/studio-promo.png new file mode 100644 index 0000000000000000000000000000000000000000..362c06dbd1c1cfabbe464714c58fa8c2f3585341 GIT binary patch literal 80740 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 it works +
+
+
+
+
IDE for end-to-end web testing
+
How about e2e automation without coding?
Meet TestCafe Studio: all the perks of TestCafe + GUI + Visual Test Recorder.
+ Check it out! +
+
+
+
From 1ad1b20fdfd36fc1667a3630cff62ad08a457bad Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Thu, 5 Jul 2018 16:58:35 +0300 Subject: [PATCH 008/184] Add TestCafe Studio animation for Readme --- media/testcafe-studio-get-started.gif | Bin 0 -> 2138848 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 media/testcafe-studio-get-started.gif diff --git a/media/testcafe-studio-get-started.gif b/media/testcafe-studio-get-started.gif new file mode 100644 index 0000000000000000000000000000000000000000..f51ee2a978461a751892f4433b79a4e695d81ed0 GIT binary patch literal 2138848 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

gm@ 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

Vl;M=BO_A4AA>*UsdEc3oV|$ReJ5$z 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

2|BX8e`SC!l1cUH| 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

P)6Cktw(AF^9G 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 z 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 z⫝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%0A>K1Zmwj=j>6ab3*kuO$X6#Z)T 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

)z2Zd`SW;laW|dksO8=JBs85*&N_w;?(To?@ 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�HPT- zMrpq&^q@CXUJ_$#-o9C`frWnzt0?^KW+%V3^K+Q;1oW-7ZMOF4a{c~>?eQ2@6jXRz zC|szrD24e$GqZX4CG>dh?BN8{Car;*QN+>L!sBDz#HRvBD8tU$R;hta`<+u1p7kR| z3dN>K&t^!$KNm|W1m?BF&Yq=U(^h9Wj|j&31c>k5Cu#Z|n>qrUI-5JF*!WF>qo?o9 zSD21s1diT))FyBo{XIvnGMXZHYMbG2xuL{7#saWie_p>=$Fd%caUDHnq5>@6{lc69 zS??d#+ZNS7EFS!%e(LNd3~Xwb@gJ=wAJ3ZPKYfxowxUfa1tn*$1{1#1f81eU+7W)g zC8t}GvMjes9fafP9rYnB^^dm=2NwnpY-PNuE2ECc{orQ|MBMhBEehmIoo~$aWa+5- zg8|*o`jC?$s1+qHUY7lXdi33B;>n^Ze!r3_C#!kzle_xIKO>aEihh~opR|{P%&n{k zC_4Ja+YFmK)V=AREw;?g(Rsi1k$Fgm6{l0c z(K}c&h^R0aXfU#~GorW|b+C*sL?k;Ml2;UoqC;XHo0QCn&76Z9J4S_FS()A7G`r=Q|Eul@CBnha&4Cf%5XN#C2Xh1^aWS%RvD0y} zi*WJMbE%kcIY)7GD{&K|xqSk-sZMi2kta$dYJR|p&D_6<4+i9X877e&PLsY&ta8t@sM=CkrR@t!;D@IRpsMwQ>_ z%t;JRa58^H#7O`S3%vk4w*X2+0K+37EG{6aDj=&YU}1}vmO|T~M!N@`h>@tSb5ujR ze~jnYMFjci1XYcxVK{;j`9i3_VK`3F{{}!*hn6jwd5pOX+^lfddp80k~> zNK%#rtbwDnqn8Yiu#8ijEFnbJBbAzUBO8$}7Z@QQ^jCxA60EAKqGoEW5s;!0o~~2A z;ZpS}wPCiiv->VJWqx9IcJBFK;`99VyM_PVo#y^6L;A14dh0hgS}-PsgShQyrvDDC zrzYN56r;}mE3jTI!k2BjtM0!!%~2C?*l;wBr|Qhv<*11_O^zMDFV>XIZ@Kh`$n#nB z-g3U=Hs5^aVedItr_P~FZHqfp;sf$qef#iE+xrJp8Pc)E!Jd?9S+|efco(5 zjxm=dQ)XMXHTdJ+Y z#q#17hlJ9`C_7U3FpY`zlqFIygOEQpkuA3@k7*Vy0t^d&a^30@p;!PB@&4CG7?b_O zZAIhz^z^|yGjr$eRM`}DJqdOj!J)!y^pSi;hRf4dJ~Z<35@Gc;08~)r`YLlsu-;Ep zQT?_agB7b%j*zz^gVB6y{ZX34#o4fo2CZSHmzTiWwe*qI?da;S=BwusrPPg zchE5@`ddZyJ$1>8q~o5S32enVA`ewV?ktsm`mSRv`m;R^9{QY;$%;LdqIdh#|TNC9mX`IdEO!KlFsL2+$UhW)7k_Zs;|LF1#DFoe@CyO${JUHT+bxnvw zVq;CEFxoStLU5CqJ(^Mq>4m4Nr3NXJvZ0bH_XW`D-hsd2P>RDAxQNd%)YOm{0{sEi zR}!QZaZP9QDZ3#j3^?l{E&O?8J2E8&cXmZydfi*qwsB5iV`0SR}2`76V7;( z>X4T=%7ww|uL?YQ<*WydaknERaAo@2PWO?MDU87$jAE7*9C=sd&%^!LzR~IbD4I}J zK!aE$Oov2rn(oFwn#x_f>m@i7jYPQ=rkIy452U71pkn?Ep>JCJ5cbIKF@UA<(V7_l zuLkuLcSe|_ngCDmR-2UjX*HpP(uX+ogLixvv(ESv9v}ldVLxl4JCw3N6*VXtwSFj7 zVzcJ66-{FtV+#0s3nf5|$vE$P+o;}RgspWBpEmWFEwsc5WK*N~Ew(uP>mU#z8K}XY zk^=UeO6PgBI@e>g%)p1kY4${rg81bMO-j5`V{L2ZeUL3HzgyIfD#Q4lRB|Jvy^%0^8<4QPZks+897FExX$mwFpq(wDMNUEU zZ)t~l3XKRgji@j7&OdmKGr0bFUC$B?$z7Y*QN`>4-k}r! zTZkU^Nb%+2qzufjc9j3_ofds9%Z=ha1+XJqdO`LV{`wyq3}@ zgxlK0MSh?G6PY2m0&=&*qi207eLz=+z^bGO`?*rZZ+G3gH!pqPo_18DxeqkvkFqF0 zYZ_(@oNLckoO|;ONmKoPBLCS@Ol^xnCzP=1moND?@S{JgY)sT7>l+nSb~_cJu+YFHVmIRpDGQ$l9f}GSEFZW zxpjUhRy_>q0Cf=a@v}9HbUMe*v$G7-n~MF^V13p>>}7FmK(|eny>zW!_)tXNHM!K~ zSQ%IiIHAbLvJonT=CLI}FBMtRo<`vCU@(pC!ES+NEUi5$e$GL)XNXNHiX1XJ8nmM^K;! zsvEgn2sbxtPkEvS_cn=)0%Sd&P{CXlkDe&;GLG|FqoS56=klkGh*P;)$> zl(MW?Pvd+PYqM8&Z7mM3BJYCpD>N~aQ1b%Qd@f9GuR1EOR{U_Le>dN7LSngIb1J~} zwR4RUvmRGXHf@K&^;Z%X+0-+LXMQi1ALNh%;Ss4dSFUZtZ}#bUqv2QNt}i-Y|GcPe zLzYOQapVhhS`dwHzJ9tyjCR4d;D z!AJ%cLTerh*J;h7lq3n~4RfncO@*-g)oYtyRFp?VDb|Ht4Sua(`G;Hfg&hDG=oDq! zu)oNnsj5#mqkfGLWIxjoM7m5e@Hp#KBH2(C!Xvx-G8@TWyJFhlI^$dO+3fmUV-Uq5 z9((%Cs|9U`A!-bCosmm}{>{1u5|B={Hu)~%^$S?o7+l-A@yPQ`Akm;Erl41)V0D?L zqNZdtz3e9PdU<#g%{&<2P#;rNne>`PeG3koRt~`zUwu};8V<~#Qm&>c=#;o36$VT3 zatb3z-^snjMf5pU3cIn_A|+Ue=`Dp15ht5(dB0sAhmcGp}V;fuUw=#is}G%xx-K^$ z1EaLESlG#d7v{9-iN47u9bac67Ow)!hoCHzE%$R}HeW+0r(##;C9y@SUX(PYTZGFS ztL-=UbBb0aWws#a=L3V<%iLxImDnpV4PdO)#l(!evP@f8V}nsR~t`>nlirKvy+;&HIshfZ#b8XLCPCSavV$ zE_(_nRV=SwlleUU%1vJ8pBx~arMoP8R|uE^)*sL^{{a@}nx>Y4is|(EQliYtK+dO< zxZhXDD&m)>u1vQK!nyjn76!NUVFnWS5PI#Me)s5}N}sE{w@?8tq^#ca6pjsC4-;&^ z^tu8fz2_Yza=+dG+H!pN%LMq^L?IW)#pQ=I(FVv%l6`+FG!H8jmR;`$Ne#WT$Ooo` zK8qU?7r&nu4Gkp^MT!j@-zZwv1PRrh`S@k%Wq88!#PGscg8S9`c{R~CGs7@qmTW0p zCGZ}X*2o+LE*L+2W;#j#^~f_<>AuNGm|W3nP}0#<{dYQm8vB@V-0T0ivi*D0C!48Y66Xqn%3d`YZmW4iV@-?+)1pFuT9xD5xZZ+r6xNb$Xy3KgM0qO^M z%ZiT^N!b>>nO2p6+n0$iqK4r#j{2|S{WesDuPS4eA?hd!WZ<8P}gk z+@G_(Z-*zyq3>To5oq=BAx-y8@2YYK&DzjUq`m~rMh^eEJH?U@+P8R$%CGku1Zi!J zb)je%cRgK^1*>$_R9DRm|HmOi0Ygpal=7kfgSYpNhO>LyzsK~^G8ny$-Wk0!dhfkP ziylVrj2gW}j}SdV2uVbQ=sgmIkb(%2NOVC+G4HtV@AJIR?=Am6)@JQ}UgtjdwZ!pQ-srh}7%cV;vV1qr0yf09&Fv(;Szi7eK6cVl^V|{OjEu|V ze*W??fOg`;B;mKtbgvWD#Js(2dA!fdADXj|1xdI?7WIBtTIdhYZpgDt8-8cK?F5*C z$*YjuH%_2PFvY)eWm@cO@zBKfC^Xjl|5+-+xJu(lQ^rO_|9t4N2i3}6OQkTbvMG9K zH&c+EVlIGG`@7NwZj{M-E9xlbBe0whw+0}ejuhzuaJBUC$v@XyJqd0Q3%_%;TazZ; zcKy!^vF89VOOj^02NKm_I$82L4lt%LbM0Wv%4piKtH7Cco~CfR!6-wua*nUktFdf7 zdw?`-L;28QhVoqhb#_R#c5kNp)!-~C*{a@%N`M3+RQyN2!=BBKg;dI|K=s^uS*fjn zM@>fQU#tn$2AQj0d!8@q8f*IKZpn^7+{v~UD~66Nq_S2a$hGG8BK|j>)xn!90c=3y zcAr~qUxJHnzo!tH(Q$ov*Psr)xk_el1XgSqxK)Nyd+q1Q@4a0!n~N!F4-TNEzoL^D25q$oy%p=L!IEN9^vxs^-r^iMih^fdjj%Y?3v|Jr0*| zy3T4pEZ|*~`&80aJ8eBik?=~~wt(qwf0(3#-P&7q;F9I;N*nOo-ba@5C827GN{qwT zyix~VX?wsNkK~?2l>}~0 zpN(L$yQ#7(`)DsOK$La_P#Ai+asjJc+dugOIKS9ac>pv=n?pbc=*8Wjwc~kX$-Sn7 z=0a(E4Y*FfI7g_T*j3Ssdf;Y&DtR4{&V|I%Xw_);z;Qra=L+`E&@sycad-47c_9J` zeoESZAjS0q9C~sG54>-DXyKutfRXYu`RQlUd_wMF_wlDC@-V#ghyQ?tZQfZP`!O~5 z*^7FN%l;V)=#IRY7(e>-2H~tUkodsaiTT<&d59!a&-}v{aPY=qWt_S(%$kZnlVk4y7`}Ix<7tjx5&1*ioM@oVGn>J`}UI#t&EST4$E)O1p-gh0t(k5qB( zs;dOe{w~5_YOD+h_8SBv24y5&{_6Gqek38Y@fYVJxp~!MbKhX+amUn~K>PN?MtfuCY*FDZ! zX`T+NMloVSX2^q5`;O+J#)OzI9*2jp51l1Bf)O$85e^SaquZ64BoZ7RCcJ2bDb_T< z?!27G+)Mb-IQhCWGHb(WyR{+yUgU@M(qFae@m*ivuSY0qi|joSS?#PM<@!$-B`{#+ z(qeA{P)3qZasw!13E|;|Qj$X%u0TaGFfB(o9F5R2Bo$;KRdFOWH7E5CC1c_x<3x~C zP>?f|QlQ8vP;?Z`3=~}K6rvak2^|VmIZED3g6T?dJkmdf%IP}Q)mSPYA1a^7OI3@R z*hqCH;q3GCH=p3x+yyNHn5i+ig)?~jGT;&zoqQRcA}--3pFGCE zp#MYax`dnlTk2wG;wAd-2{VaEGfBuW$w)EDC^6}pGFdn=c{(zA$1yAGFcT3c3Q`sd zIu;5Z7A_Qvgb<6dGfQ+jE4Koxk|L{`HLJQFtDY09qur$kA2mH29g2;Pg^dZt#>Da; z07_7vO;nmq!jer=i%rj*&GPD{F6I@==9|D4Ky>9J`th-_iwLoM`CRs4Vj?0@JZMQd zG?oGF=!a5LW( z8dK8dQdZ*9v*t3r%H?Rw%_Yx`wc)n3;L+9K@y_9;VdWLI;&t@p^^D~8OyTv7=JieC z4IpAuXg*e=a~~Il-KDQ`74?jL!2wza{B{qePj#H2C%@b)R{nT4UMpjwek1iZv&u`2XSqx`hYFqCf!6oA)9?|8n zil?qC0Bci4*_0!$OiFN*ab(gY%n@m(r|qt{^{88huqSywMD z_U?hW0m`>Y-_*}X{Tz}*!$@eb16v3H8pbCA9ASM4?dL zbLKhM@t(YePR+_LT`zUM1$jw#5gTXH6piZ>M`;;Hj3}hk{tMnsjIxZcf9#jY1 zYw6r$jW6t9zbvigAa`3|PmbhB;Yd>?m%W`OR~7z|ZON)j2U)HAP(MSHPVX(xHy-!* zz(^~Lmxf-NQBXAxCD%_p4+3gumTSs3o?-u!ccV z2i|uDbSX>lz#zM?%h<3lO`r8Yb#$wveR!L z1{)0{mo*IdU4t8ykQw?t|NWH5Bem_dgh{xmpyj}*qmal=m)i>bYg6~B?yJ8B+=*W* zq%kHw2zcj_RNWd?5#^^(qynQ<+nt))>o-_6`0p)Mq?U0EU0W5fMm3GD0=|(Oz|~E= zB@Bbs*w+NpCwRkR6L(q@*-O-PXZ_hUG&tg!EpCl40#A?ws% zEZz;uR5Swq=q=^5x`~M$%rDBRkM*syQ3EuIC9uWVvrCPz&)0C&pZxBdb=*=eeV{Xu zdy`DX&?TiKdOP&A{i0k&%{Pg09>bkE?KT}~VWW&mVe^(^X%K%Y(eUF=xMNAun;<+# z#@YfuN|$Cd(#t`x7OXDU{se`|O(F|T7Ft8`r)A&wKxZSqI49p%NjG77C#jp4Ur%P; zfRkrfzFNreu#5TO6`m%GL3)DH%_IxJ18PTj;uU509&2$91|7|H>fu^Rt90P?G#Xuu z`hws=lS`(zn)ST38YEpSPiM6P%}_^ln@#^@{9KQ@y0)fSG&?BAQ=pU`wIv0S?LK%jW7HW~VylE)YPbL~uw8gFDJZ2WTNYSBK z7`Vxq?;eoYR5OXZOD+|r>mzvPqTx+xd(Afgbyv@d7E{BJ2fJXhy3=Y36vCMlNSDDh zKg*x-=zD`WETb)vTcpfKj%1-R%1~vQ6C{~J#i=h2Z*$45@aNXQcjVT0XOfd4DW62a z@AUxNyK9xoy7(8T0fgAoiOo?noUD2ZE@%>CI z)3wiY;dApJh`b!!*srkFYV(!r0Fvt zK0>=j={Z|kN3km%`3D4WmpO}#r!sWD0p!oAox$G#knb+f2GHl1c|<0(^^=8Uxs_@i{=o4syr2wtfjZ(;*3QMMh50 zC~9H!dz0&2E!Ym*Mw*-=bDVJ^?lKB5c)?p0%X`&-MhU7GM9qLvsy7ADTAU_6d+Nx| z7a2wHdascP;57RpnPnTp3Fodb(4?j%PxR6qTM6tO_?*0O_$=m2i1E3L6wp7{!=cQl zmbNoRu<@EVj*RwJmTxB5M8QlJso51xO4qS6@XBuN`0iZMyt;9DKh94iti7nns_xs= zBZ<`yzG;3Y^^9gua%n004E;(}mCnzWHp*QcLAsc!_Pd8!dLd(^BW#!3|J^MG z0_QQ94kWaMp&NdTEl#_OIm*e%)3LS!)4j*F%I7gMF{=Ah_{Dd;S0~#%cRhv47;rV$ zet{VCD)hK37}V3;ejR%TmMXJkN|I84WB!#sfe-h!=X#!2#xIYQtTXI@v&4=-;X7`L z{1DQ7gIgqmMF?F6!<8Y{Yn%gYGA8K}fQAyre92ZBLcqf^{a2;W(W5K0trk4;tkTP~ zvKv`_z>%zw<;<$2!8peC>+R^f6(7s?4D+FktobvsWstCf+^osFDiO><$9Xx*wan?k zeZeYUcZ2qqLmyRZ(&eW?^~r3z6f9?k@0>LwZzh&q;oMiV;+#T+le%;B{t|d0K;T=K zYmB%jrZ`Bg$+zf!N*BxgCx?FIG0i&))0A7wQ*+OJ~HEP4vC7Cgp4jF zVz>mtfU$8hwkW8y!5GefAjJ=Ncn^7qqhR95`qr*w6xrMIWjo>@@1Vc@G z>rIlLhBWheSW}}bsi(Dor(Ol_dbq6=K0i!56bV|xV;b!Eu)g}pbQ!`1)Wd?*Xe=Zn z-PI@!pUZIFuk_m9SLlrzMU7PCjkCD&ri|7D0QGvD-$91Z0Vn=pY>aKD#V|b7O$BSs z08VGWvTptmo@Pxn>BMKGh{J!7xZGRFvZ%94I8c;~VA%Ld{-~YJt6G18KmDq?%4{S{ z(j0W1!&m{A-ej92L!+sH26H@tgQ%1%^ zZ{K7;w#`!*B%k5R$wz0q6)-%^SN)(v%6UivMdpia5kE?VYgpM7VkjQ2(O#nx^W-de z$_47b5j_63pd%#@eeON7#nu;U<7oz)B-*?n6rY6%HA+)(5?tt>qMasX3iF;go$``; z=jYdQTnmT@RgstO#-y;idQJkw2d)u8oo$&I%2jKHe+ z6~jGrX>ap{r1~hBVqlFNjx1X!j{!1?^Rj$-Q1t;{epkBbAwnB%cB@;Sd(KSW23#|X z(wfs>jZA4cPlrwFh#qlUn%S<8fLN(29wLBBrb=D!q6qxKy#o2dNNhjDZ7(_G8!xyh zMqASKHVq?;3+rs9W0a<8V8&JH_QO-*I5gl$)r0W09CDWwhACM-PnRAu##TFwd(kA} z0Gp7qZ{^v1rpYf+-YXrtgQ1Eic2cb#y5W!;q8w7IK?UA?$j7ES1Vl9z8u)S2nB#`9 zSWtxPL{-{AHHBb4>gFAhV<;^XYRVD|63@BSS<@?H7;x_7b5KJ&CHnY`3s-OSAf;A> zf%@mUlg?T#M3CvdZghl89c6QV0yW;aX#UH@DjwDgoS5=UnEgJ0QR z^F5+r>>Ru|YV3AO9Tru&X-B#^)Nm_ZekE8-`3HzIhz4kR!#mo)TC*WaTmttCW-oWQ zxl3JM|9TjnCJmV_GjKP@OU)2TQGYE3M^F$I@@{(i)7lf4*Hm*?Obs?~CddQ37nj+j z62i1*2@|S!s=q}PHdw$l0dAA`v}BtNF;-DQU@vTQ9jVydq)(Vdt<_+2!87%8d=0|9 zeASpyn4ART&0jZTC_t+j{hH}j0wQ5RU$jddX59dlFEhexH{ zerHiJ3|iHcgHRj1z#w55F8<`r;;<_nqV-9N=?Z&iTpjgvO@l9P;OVv` zdnmMfkp?_K0wXd_&D8n%`#)er#{vN<7FZ+;hLrLPsHrm6|j^OYc!`>v$ zRO7=6-^d-Y8CXN3mkQNdu@$YzX9p!C3nO4I`|BNBBL<%YAN?%1oW2EAYh!{ABkYjLn#{?v#&qU8G&%^`sDT5JB-(L>%Bq;tGTtr&dW3&||uqv#;~!h-=r z=`337C4lfaIh8cC{Mi(2=j}8liPH&`Uj)sxu!HOkc^MG`k$d`*yn~ca;PEZKSBOvG z<5P5NHD>ERvUE`SOCf^ff#r ziqjmvb~e+m$XWv&w_PJ77~ZfyGZ(u)F985C*+rZ!`9<7%^6{ImJ2%E(6hCzI+t*IsXY)*_B0k(Srxoc$JJ(FKdMz1G(_mHg3XZ}V= zR!QYd`E}&3+FS(%ze5C>Oe^CGj(o2;cjo8ZsLSh~0cBiyo;2-TVOHDK)H_#7CxK3} zaXwtFm+$3TyC39e=C9t%#r?JwBmIAZH2V) zd=8}f``lY)m{;jX^R*}JB5YF)*X+MoynRjuX%k4*Ahlth*Kd?OW2Mim)AM4Q3;YY5 zz>#fotoyhmpnaFSl>z+~%Uror{CzVVuXz~z)?Wc0^2Cw7mgvaA!3LY;#g*llUTs9+ z$j0&S*hL`AoR{y;Fw7`|jZ{+fbALOzTP0`^yY2{}SHGAn9{fm;CU?ujPG^eG@}} z!Rmh7jRPuFf3J}Es)7d;SFYWDhrM+{r-CG<6Uqx%osJj$9x%9l^Y8^3g_v*0_t8CI zgfnzB_KPwHPwy)_j%3S5%C~XV2)BUUH*63~`QgBLwS{;{uPBt={Ck(eo@Nc5>g-NH z0gxZLJ9+W&rYUrva{qai%M!(kYd%n={ks5K6x%-BVJ(%OrF;gHU+bMEk zhuzv8VqSY}WpW&z{p#8(<2#hN&WGseZ_9jpBlu^eXFamv@7Qx__KulpAYYok&EpYTseQ& zWm0_Q?4Cc+;p!P#|6$0-wh_B2B@%}GkH6Xo^z6USk=s*or(zaYf1%Jox;tlnj#E~_ zz-NSCX){uRn{TZ-#VP_%9H=Mm-8rzo`RAtCN&LX3%$2{667Uq<8dLEHa>Dolnb_ZC z_6v`)89#rjn$PyY*(J3K%8E~dq4^X zyeokyDjf$BV9s4+B7~Efi?#TZ*w~|mq>G)agte-;v8$*P0#TVV;sZ=MD+}RC7)}$` zh+E|RczA-2lCJE%_aNY@AT|Ur071al@%)=GKJ)XSUtNn>{0hTb08ha;CfEL%wogps z34bmJ0sLI-1#xLjT}~VYjOF7G_I|OW#`iB13Ve9XTL}(P|70fonfv_tl*Q;#@a2-2 zX|3KeBzi{N)fV(;oW1-`!gT!Kgg6jE4GI=FBj$$mP)gxNVO7tN(FKIQKt_5D3r>5EdpO z2Q*zaU4qafAwp6JO)FAvG^wOEsb3U1B_%mCFS(#Uxeyb%s06vWCAp&w1uZoN3oQk& z427~VrMetZ|DkdYqPp(+pUz57DbzmE)S=NRE>4sn0}7*wl9HjN<)vjIsy(u_!Wdd* z1zKf&T5Tg*6D+N{Egc2TCFDf=U$W1?nh!HM9nrz=vc(dL0T;yRXm_dbxDrk5h&oR+ zV_*VfQ1<_Du;XQ7WBw1!q#(>>9>C<2$1Et!Y-Yj2CC4Hy$D*mnO3BS??!rdFNVK~9 zua-$NY?9h+Qo?LX+H4wDZ2DGg-l1&X@$9t!pi6Xo?A$!;DvIomKI}xBI-*J=YKacO zqj4eVpzKStIwdO(i$D$!ze`rhGnUgch4WI7N#Kl0<6@NO;*{so(&N&$<}$m=y`V0!X|IC`HwdD`3CJ2o~l zJ3F_qytcTwu(&+?{{8aC#`^a5&d%D-(b4hI(VwH!v*VqEH29p6t5xwM>Gm4|(`MB0>dT&pafb)mw5%sfU56VJtc^~>LVibI zXA2Sn_LQETY&TX&-mM~&Q@6Qq*+8JytBMx+vGwB4-QvFIzkeQVytrf1-}m?T*^ljy zGyVMp0szYIBG{Y)s}j1Gy>vTz=iXPBWN#7vPbnzvGjuGSTa#-VOW)F`8_Y?OuIbwu za_bqq0qN_R7ah88shGydnryM?t=b%^TJ<%d`v(*5Ni`6GdVvOVyZQo6wtF5o4P?G? z3mB@{aTl4J+iez`d1f?}SO!$$$j~2QaPKqYBQ+6Zwcl|2>R3)sVMj~+;GnP)>s<;{oCDY zw)B;z`V!yo_nI1;zc=51^8I^D`xrrR`~Kra-|g0?Uz)eudQZP^KNx@t?X-{lpG}wk zZ-2YDo-MmimczGqyVlZ#_MUz&@!RX(YHZniw)13rujgP)XutP((Qp6x*_W36zCWki z`~3iz@WB9>-v3|_&UgP{h+KB(U>K<*d^m!#@jo18@Vb9E#uBk}IF7y{d^Evb>VGuJ zfA{{;lyKM1(F@GD@Q-P!CI25U<-Xqk@k;6E&W{-^Oyqc0lm7bgoGxGM@oPib-Q#&v z9g&j-OPlK_Z*09*;&{uHDlQxN(u6%b`oxf38G+ zZT-0#`;)Ny^CKQ6dbXBAA8__5ov-a|JzI9~Y$IPs^!#&?O~CnPnOEESm)jA0=U=OD zi2mBDFAezht?6#tukZJ}_I_=*kBk1^dAtcbKjWq8>;NW68XGCISkehU z63r_w2qdwfS&fe<_D!KBb(_*t948TzZ7>C9`dE=_7p;q8fX)wmqOiy4R(u zeC7GLYXS?n)phhj_U&u}g+2gHY+wfD_pbptJWU4fn?C#M>Ix9WVM*hMVDfM^xVfA< zOdXfBRV)@+oLqHOjfIGUlai9Qfb2(JX`I=BEARcVn?QcJfeZ0>cARkmHG|Wwwv504UI((3h@T!9CJC4g|}lNbR*;@D6lqMTvHw2k>}my0;z}`L+z2|`2HFAiQ4LW zDDVIRlLIpvmZ>s=gY%O9)KOVQ>MGGa%t-U+V58)C&L(G`MK|q!afa2-E=q(xsGp$m z)H9$k|5T#82ImtlNaI|bO>s>b=I>b?BassWcgIeM+D#6lIKer*m_ZXdq><WJ4$y1#2V)ipw0NTuP!YA5H&i#Hr~f0Y1dwOjH5@%n2joB@pRno#IEY%s%<~N4c(N|c#@vKQ>P^I{}7VCUGfEu7C?D3%B z_P1&fhwUf>(z-(aYzyx8ucebs3BF{fak>T#L{4uXiosCK2JTA$*ra6H$ z)OQm6McWN5XH&b=tlksO@qlq>Ra5Vp{RS{FOCImWUj0E+kYO3>ww9Ao}?F@+-s1l0*bi$yzWz%^I*qiXh{aSR{s@ zqhoj%Gd|Y6tc2^N;jfR@9Z;)Q~KiTb@20;@#Tb$q2Fn#9>tw zvH%l2oWABHu{V4N$1DeO@C!Oduuz%I0LI1ku;de5Ot%!* zkh9}dsQ8q8#D)$q@J{orrUgoJkAizy^uzk%jQ}=yH{)Td_tFazHVlBx(qKfe5Rg0K zXA^ESX`M)K3&>O+9#qDsce2rOh*_VU^r8>X&0-7h5}e%_v!f2=@vglWb$F!)m`czC zzdqo-c3Y7))h5B(kCPB*M5aQj^r^vnIVW*Hc67gRVax1*pNxjK{Aiun5{1nxP?9`@ z`+F7To~Wj$>g2B;7(`%zdMN=-r9ammd{m=Byz(lo^A9ViDW(1F}fpATJ zqK3DERr0G{^H0xSLDm;XP8lJez5}{UR7NOd{4*W%Nt~{-IR$8=BM->vO?qbEz8Ve& zaE67_Q69M0RmB!%QY?LG#Rg?(Ezb=<2f@*1=|IiWQmL|$VUes>>O36HcgIa`@Afn- z=9$}1r+5aN^LfSN@>xu!AB8a`tnq`R+lZt(VZD-Jg^_=)ASeKUI+#d{v|m2Y;_kb} zamT}$p$P5!lJA)a@~bQ^<_IK?NDs50mDSlm0khF@iI2?&>w{*gud%J!Lu!m$v?Oj^ z^Yk`#k-~>e9jW<-xt{$r<(c<%9gX`wEc_YeQ;NdJR|9M{C1|Sw@kktyLwor%v~fiE zMs=W0Y61yBc_P(5kr(%?6DqleA3ri@pC$QY1r>2epl}+ZC+4GWO1e1pYmH#LSqT^b zL9yhv_62Aanff@w3q2yChy$40cy3t>pO%=xNsNb*(*}P)XHd{YG-8lC%>sABvHFJ8 z53iCGq^g|5^I8xTn{b|cUDD2#&JU-S&Rk;1dHgzTCN$az1TYB;wwBUCh66d*a;(Osm<|91XwZWtz?$yW zv?p<}!yC&_YaMri(8M06K$3 zTMa84%OML+SyCI7dP|CQMxjPm>RSpZB z3RsBXJHu4|G{<@60(@ekCd3O~YKn9g_J%rOLsGseUvxz#kHbs{65QVX%qm9$%d8MmYv^5emx*7K697~5z?3#pATUx)<4H}-5!2V6o>yFNWqp)}U=6v|gxvJl^cr8&Z$Dr!h!@>*a?&no$t?Tf_&% z%Y<#=sk3lrjAH=_zyS^AvypvG@8?RJmY=Bgs<IpGW|(TIPtOyq9z-aAM4cU<+DUpM3X{d%%GdRxGaELTrw{0eH8l%T>@H72WLcv1PPML$!U59 z-2(2~CP(qWky!V{y1Rc18`BnxA2LCc-n%5yM9N`7&zRuKp%v#Il|2Z#d^&rd=u%^* zY86wt^6pse@8vFP^=SA#4oqvxFtI^Yt!z2*UpP80m)d6x)=zX=-}1M0<4ue3_k0Hp zofY7rKU)vJHSd#_IMvvBzHf2CBkXY=XHy`YtQ)8Rdyb$T;i=I{)k&Mp+p#Y(-n7p! z^(XIX0e8eEwkIrDv>T%#vL&h+TEUFW;mk3h#97djYw3_Ipx%^)u%(h&M++svE_n#n zaKoaN9|nz^YCkP$b3(#}$K`Cm85@H43_D`N)`IG~o3pr7v~Z7p+rvn)CiR}jlisqwRjyse|Y(Hc+ z3DTs!YbfJqyRVQ z>j`ym8k_^3S@|PTA`G(ixNoUPzDB<@c#ULiqqp~WeB`YBd!|-N{YP6Z@n=sS_zrZH z5q(a(o+(j*-pl*ZKEBmZs9vAmw;f^m5(QmR7>qr5B-#OL^?K&C25%5hSmp*OR8T7n z0E&Df7sm&6;578Yk8um~hspU9&9^X#7E;+b8GjXhQ@uV?8h74Db1en4lk%R$NZShEB0x`+u_hJK1*B9S#%Z)7JHMmGm=6 zCMrSenU_k#i;k}b45<>n&E)OaD83y6ip(Nwylk=*PXD|pWc2U`1l0S#q9loiS1arY zBUhz+?=sIFEhBRr!S^1`ZW^X}LSZHErjaBri{LrVRv-tVdit|HNkR84#R>rCQrPhg z_7S^uqfrr)`XuUO7_f-*a+)`KpOF!gR#w z$bAa;683`hjmFBO7?<$q9K9zeOXjV4G119XE3*+k{T0=^H$~p)n*u^cb#4!2#nZaz zi}aq|fZtYLdh9S|;aS_RTw#_oN1>LnJ9;l;S6)M;cIcV)sm7~@oOjdoFMV1+sL6g9 zOEr8HI>*1F#n<$`R>kMNMXy*FzT+Z^lxan6$DwTw|Wy#i+TjWbie}~teudH8x zPv<(Vu%^g7xVqO$b-?rU4!m9 zpR=r*U0*vD=rR|1NwQbMO}1}?L3=|*)K8iIGvaVvGybz~)o1-Gn(5M5koXgo zwm1gzO~uvE-Z;DQtPN|G%~I{p{ZH$<(U6jFn`!l9woIP|uYbw1-?(~F>V44YwYTwM zXGCxBX5F*T1S8$ZDl(?(uaQ+iz_ZWLYU>zE(_Y7|c0%*h7|MKn#pi6w0sS^*H^4W& zfVe{EEkD#P4&9rYedcP+PGEei;vQ)1tc~E zSdI9kyWFdL@xbCSBll`QwW|3c+_d6=D7U_CM zJYK;d_fy%NH?#+wuVlp!Q(BFze7m92ZL0YFwqiG}()Jsc*>0upb^t?H<^8q*63Ob$ z^r?w^7g^^&%pMx=i%#Cre5L&Dmk&YVyLUwwdC9&ofMm99{WY5^qI-{TwRd6l9>diQ zqs+uXn!w=PcIh*4r_%PfB2}&N6_qNmSH_EbD(NJIbP(^I@4d^5F_rsUhH;7|+daO~ zh}m!IS{rMffalI*W5!=;KZ1^K9mD!{g{5+JbHkO+G#B4|mu~A7WcVVSwWm>`v-0=| zW&+4_$^H2B%j-RW&$g{a8XVXB;~v;57=U=V^&>98<%Z>5Ba?l-{4mWiqaQJ!BWF&x zcn8c@^&(Sr=(ktY+Tb#DKQ$ceG;?9kPV~J|aGC=sY1DygiN2%DIlA3)_yTmN->88A zy|c4ph*NDyP@51qzFB?NIs*tV`<(aj*F^ceCL1=&MfL8TAm>&8J|gXe1Mp;TfCqj* z4|E4&q2v2Ii7*7x3Mz$~s54f7!H)e|n0r9DfZl)bH?a77edFJ2=)XS4$2}j^KPCk5 z-u+eY4BjRfeZ2UTkoxz))^pZRsU)=9vWP6d*h+HP=Dwn)`?7o{|qsZ-nkHTAv^`cAR{(=>|;2b>Q71R zSJ>eW9V{CF`+3D|@MIsHV(`?%2_&$anF6=K8$6YQ;7*=G<9%-aGq=PQ2>7o}y@6g{ z3N`4RIOoNyfm76in^uKh9fPGHPq_`lb@sW56DjOP{UNQ1>C+Sg5K09Z2p3H;zyV-^ z7@%M8aReT$yQWTD;s^lPX4nK-m6Lr690Z0DLl(1f%l+#o#gLmw7$-48?IIwwH#OW1$vUs4fyxe9jp@z4$D-pHhTVP{TQ}xgC$;N3dJsLv>J#ZB3-bN)oO4Q3G3|Z`aS|i z%ODZ}A>Ick5~AwzaISCd&?etL6iY1rB4>xI$`J+tJ|e!%q2Rju_SmZZG#4}Cb|w^9 z2M-&l+$33bp`(S=p@=VpnkE)p-%I#J57flNh)ZGuljbJW`Mq}oF(1N|0z;rWPx!nDx(Z)B}r_e^Eo@9{EmNxTE%SosBN5!tO{_$QyZWwzA>yJyhvczKEG zGKi^HTEAkErwP_KT-P68UIy* zCw}(udc@^T{Bz37;pzF8M|(N1Z9=thnp3g&4)8iE*3IIgz;K z|=IWZhl2!{%=pL^ZGn-WBd^d zvBEz^zFo)5(;xvH=U@m3u=-yJ9-ia|@r?yVQ9+q0q1twr@SS%ksh~fphBm3GH5mmZ z88>22oLh=qRFquV{J$tXG71(33MJXg_F?vpl%6R_M;tORjLIvV8bx|3 z#4^!Qv(Zy43R4H9plEqebXXK84T_5e#m#@&P0YfKmg1i#VvkqPT0}`d{!} zJX=5lI~_SYCks2b06PzgT~d(U!I#}RoZZV8%_xHw;zvu!{x^Kbfw3YocO1AJju1R2 zEfXg#&!x)C!gC4VVUV1PTAWsaoSu&VL-+j`#Ea+Rl;u*i zB=R&3xXsPEEnK*rQ@MSzc~Rt-oy)wNczt94VeyjqP(&7whL4wvDtT6?Rf#P_t2$eKqgL~I^a_iW7CTxA*Pq$qNkiQ7rgz46M}R?9Mk)6b4C z@38}+@a%-X-QWqjt2;PGCe)(@e$sYb4qVj6(uP>x&WJowP3 z>z^xdPq@=fN!Idd5qlbgY`T$7}fp9$7jlF*f)O^pdgjWmSx)0=ZQ ztDxJTqvf000Za$y2)J}p?U}sl=h;Yyh1bMYFtQE z2uxF3UtK2=qMyaaZtgE=m3fu*EG4)s_@R~vV|c}PzU!HOxF|t;HK@j0E8u4+|E#$7 z-Du99FQNj^P3^AmN(UW`*IAhfA_HDVI5O#`jS6^aSP}p1+%2P?0(OVe0Vd=U79FIf zMK$j{ZaZtXqO7F!2AQJO?+4}R-mA{q+l@{3r zX->^WN;c%h@kYYyq^UK@Wa1-#yij=MF1f1$-;YbKlsYg4Z2L9W0i&M5Efs1j$R82ZlM0J zs|F}^nv;}pDD+za|7%kP7l8x!))>}$v~51=8+8;IVFeR~_X9Ad`u$YSVXpuP?R=!i z%ir_eTN+JH*LFdlVrn#kYdh~3&ETmP=28hM)x*V=x>tBH8e*hRr8w#4cy+1N1xub( z4jeYis7KW%*P2R_vJ8l_)Kdiu-W|O~4pIKUcze&NCcka%I|-=}G=b0qgx)*S!O*Kn z??^AwJ4g+^caW+CP(cKx3MeYQNG~Ey1Vlvy1q5th-uU19>~qF>pRdm|#yv9TnrqIL zuetME^SU?#rx3)kv{(^ie^)RHZ1FWEqMGg?h7-XAh=^1UR0FT+wZ5B17J38!~rq>I#FK zo^DRD2=mHCqy=0+D^S~5ac@K?5s;}@#|f9(GoVe+%Tq)+^_8hCxR@v0(v50?bG=ui zR_Pd{)QC5=1F0E-fNub4Ln(JSUnZ>D@@d{byy*-WZs4&?lsuvXYu`vq-T-}eG|AJ@ z?}b#u592}ZsCLnY4vu8g0fc*B<`>bRKas9onx zZCz^L*!HIU!7!X7K>ca?UTe9NkgTU0Z<2u;UWa1eI;&q(W2Pos3z6skGU#eo8Cwa04#g$%q7u07c$cqnA zd2+^YsXjyLFU|BtRLfWC@Pt@i6KH{FsM^(h(ZRiG!k^{rZmm^vBZUbMla6I6>9&3E zb#ELBgvn&TV|01Qn(mNqdPB*-a)WlYUZR}veabSai2o8l(P!w%`;RCq66M;cu|(<$ zaA?xByCT~$hG;DIxuaWtq!1+Wuv+ximwpquu5Z|bom==csTQuYZ;3fK6BZ>RJLf$& zm8v;739JhtWM__Ko@}Sw9&4CkmSD9PFxx@0m(PLV%fYL<%X@{>oc_{ixZ=Cfm8>oG znx_aUGd zExvwQo5n)$Ow0_P+nIJVr%-I|^L2Z!JfPT_UP053w1@!#%5S0x*DX=i3^%Kpv^=?9 zpPk>!$pSP$HXpZA-)?x$w(V`>9#L4&*8}6vTS?bYy>scBbac5|NiGRjc_au*j|>lh zS8;dOCCt@d4R?F5(A6%@E&=&Iww6|*lUVz_Jt%}jBT(>%d>!)6Y@%HvjBvp7A*~C+kt8=jg{)0*K zy>b6;SY|lKi{JA|yUN!a9B8)hilc0K4Npu%8vcwg7b)3M(F(A+$}Yt}4c(=1irlzP zeD{zMaN}oFc(08Z!!WA(fOcm5Zr3_~*jO*FnU*6Fm)cmIF#iEBT2y>$H2#|fk)WUd zSp*!xpNt_~yd>LYZ=3jQvpR8%W{enOqj+_`5}s5Qam~ zToKa*1(qsuJMu(*^yr+`^bSC#qasa8Q)1HOX#*giNI`)xXV+iD$R*Y2+V8HJ@Gz+v zJX|$E{-&M}9e6Z8O?(7+r8K?Vlj6PwN)-<&c6X)5A-3wgSQ9d~67_jJ?b7pEFnGeS zsxiqU^CkIL6yud$6RMv6%-iB|Vz2!BOO3W5z01z#w z(_(M-R6gY(-ulf>s(8I(^&EB~B=}RQ0{ z7vZTweZeTn zy&BXB4dgr$b-kf%goih^u!rIzoLeYf24M$ew1dl(>@d2&1E~}P=uLj68M{HK8A}to z^PpWBMyjC-uZ$nC67KpaH$kMX1Yfg}uTGmSzNar7z zzIM42{ou%;c2~CN|Wv!2@*8IVyg+=bmg6*GDCU z^SHno)qXcZEaR(>tXSeooqVnV3AUdhN~_AwpWt2jM;gV(D|cjUs!+RfVTW=1U5mm}WY8B4@V|1yc}rtzjI zpijTc&IeQ^zy?cz3!3I4s^;VHO6Omf={J>%i4Hw8u6Bba2QFyo-FyCmD%@y5ZEulX z%RP~I<%~;pvAghXD7P6&wLbd*Q6w9k_Oei44%Mw|d*danT_#pk{Qm3U08ZzM=seG) z4Cm8N_g|Vq9G0s#tQ&T0sRs&4>>X|QM1M*>|D|@u zQ6db4ycnn+wrV8R8Y$#AruH^Y?lx|z`Q z-GM)}7?rRMz%t^qQP|aOoAfD zPI@7ucDTJX__E|@9+-to;=oOds17?LSPTH|BA&SWsVOob!y!s;Ek4VYO27sV8EAfN zsW0>dfEE|z#h`pc#vcz-py_8GoHN$MD8@7aD1ifwmUjx1Gi7pH@5g}TV3^CGnXaBr zU?-7UaTcDcYpi;`TW-KInb@5!Rmz8Wa@CY_$gJY-=jgi3Cvx8)90+vz{rl>7DVi&! zR5Bk*KLD^kd6ZT06!r}+$YPGVi*2_q-xKIzbPYLt4~X_gDII$McG4qH~t5Gh>W`w}WW8<&kc zz1W^g4qIb?@&0l+)j|d$KCg*COXfwtEiSrW3^|~pn&H3QPmQJwvly6)mu^g!w)g16 zPqe}M2DJ7D3d6KC4KSMW=FN2Mwd2UQrsdH67Al8=R0IOy}43)To+L z?6TY)x;s4RsML5#CekfS>w{X{I>F^m!>}E6SV<#`7c$~{<`6v5k(oHsV}-KnVQXC- z@gY^x1~+yx=#3`Uk3>bM1Xj}8DzbZXjR{kZJ%E_4AB^Zo!Rd-A3ysFK)l*3d-I+?# zvoFVdufKdC{PM2#%X`sdP5EQZjTH|K=pSGQAB?eIT4YW(9sX^O>RKDu?HRvXGuFW| zjz$b(`X&bMPxMrdd$?Y+ov(DsH@_v@xcQQV$jx#&XH(-u*8Y`$QYPL4_A@Cu1GhKs3 zG5~GD`Z{{C50&sZtdF982^H^z^aUe1p{%;q_==n3`RwwxOmWH|9#Q-`LanQoBUu{7W;kBb(IWg-c0qs6ighLe0^6=Y>l5MoY*S zIhbR@dzKlCZAYA_+cu_%O;U32^Xq&W8-l7HOsTsc{ zZ(XaHm7#d}T20xD_2Id}bBv?7yMLCIefgSx{-{d&;579cJ@Y`^L@A5Uo7QxrEz<6- zr=xG&0>OWH*593jPMp_W56!afue}mY(^!hXQ!soZ`-LW#_~g6tyFZ_{l%K0t z^~x&ThVyx5YpS3PW)N8gjd2cFc+>r9IUjIgLrg>L>z4wi zW5W$j2WX`c6o!L_pf=VYR@*t8I#l%uznyS=dlF@QdVQM7)*tFS%_p3@?_zSw+jo@Y zcPX+=rmDPTV;{hBdn{dq$Q zT5|E{W$F`$Z$EiBE#(G}s0onLxS#hDe^FBWyoHAe8*w%$pAK>UPGkT1=;-w0wrJFg z?+I0>n)$z5zWxSW|5B3tyDj&399^&KRXWSwvj=b2M=y)rRX@wGf*9nS36TIGSK_aY zN02iv436$_=m@a&0yOui$ouwjXVssr+}~N&zjZHD9LAA8#ogf}ozLa|wle-1JVQE+ zt9yJIaxO+18=9W}dbBxx_GDux^6h!sBk|w>WUF{G`}EK3K2R_o9?L-$>j)V&|H$-K zZWaEAoQXS}Lx25}9SDgPhf%7-W8Z#>tb)9`42unb#Ny#BwfAsjyD|3jByv}1T``Hl zas&2iDDvC1=Ig1DEom6}guh)5AHT3elF0ElhK-BHPmsH29ofMf48gsT#@n-dQ&*Bi2oeX(ELP=hFov%2yvYA2>*39s1|D3ob3qW4fmRx&gDD-ksEo* zpX9Bvi@c5|V&tVr?x!ZU5pqCY{(H;eZ}7J(;}ah_{--RF^5kDNjzM*$v3viH$=_o0 z^KVRk{^pOuZNyFr_|3%YYy8pa1^nscq~9Oqe13BLH~E$}{r!Jso9%?p7t|Mh)~;L| zGt&$`$ILeOyeDRbjB194XG~Sty>HI4(~!V9x=dEsZBHO&&@pxI?cQs)C^bjdIa0`Y zw!bGQ!zpDPxjrmnXVKI$n#MoT&t}mg9~viKqJ1at^}OG~PVe`;|C{t(vt^rI6rTM1 z=`$JF^Zswmv)RDhCzt<=d62QplU`(v(grw-CW$9FO=(J7g z>`ebR@cQes_K)l&*=LQ6y;STN=#b>sIYw#>BNoZXNz2HEV^k7mH1=Wi4`8C>Wl~mP zvU6i{4r6lvhktp-FnQ)M`4O0c;+Sce{@Zztg)B$O^bh>{hkTKRC`E;tb&Q$G*vmeY zIWUVwN|5D}B3XzMt9uP=WP-hBi}f*LmDXZ4wEu6^#quB2rNhQ0!zQS}CdAJsD$Rzs zXH&b%rfbS(>dfXI^N;2v8GFUEMW(V-GqN)v{whzBz1VEMaE#J8E*hMK70x~a=j{D& z?B(H&^AE-akcS%+IOxf;lfIl7=6|pk?_cJnpv7tU{|8=iTvA$Gctb8-b1q|3E_+LE zVM%UjS#BjIZXFFW?fT2PFj!t5{(op!*1u>MA2mH6mYt95GM`x>pY8R(V~}Jm%77rg zpag!bD8GH!U&uusgCujVpd0}%WzR<{f_rkyt=tnN-)q)qylxp=$>7{Qc}KgyEC+2dWUBNA+_w z+!{K(VnI@lsBEL++6z#|2iGQ_gqi_F)h_+c1Gnu@n8p;ZTtV50h)}b|ZErm3B99s} ztv?R&=;oPxR6{#Ba3}0jVPt{#+bQLJK?BD;9I5e&vc)l161PO%?xxI7)8f4))g?XJ zGVB}js3A#Qm^#b5>kz`4IGCgt^6^zQjt42j_|~uD5?^&F#V2BbjJjW1Hla#nyFHx7tbW&h ztH9u~+a2&7c-vT}tc+|DciZ5P+DuX2ps|w2@-U~+$t!$LdB_xTR=&KQpnj8DX|l1J z#X0a=<_^MnGirLUs1D}@X0FF7jcy`5uVF$Lj4h>CHu1>`lG=Hr*qz!eH%CsYTa{tE zb2ZEn5t>v=?b|%j$B=solHCAffH_c{1hAwK1VDL3O4e6Cs4g&U zU8upA!Wt^a>sjsgvWrfv5ga4D?rc9CX;4lnNbw7dxJ2QuJB*qwJ3*Af)U2+V+MUQL zdPZKfm$VMd&cOb2ch;5tu{Kx}xqPA)<>lFy zN{5ab(Bw)7m=tA_Jv!BGOi7khRA`L->4x`Mi)E?)!IexDH8|TppC7GAseRSCM_aN7 z(<-}KdSb`ENz~RX&=j7D*XeC+Uoqc7ym_NNFySk4o8EpV`%WKY^TXeU%sc~QdE@xw z1gt!&<*6D+jqptIM0Wa&NGDvtfMqX-uy?qm*goDmQ3W!7usY+*0^a-%GFJ5MB3K|DLbX5l&LI+RO~Jrf?{Hcm z)0DjCuTA9%L`C9MO9vmpU!<``7R?K-hN42~^7{pEhY2zS5E6{!HtXnuUIUf@fPA$A4(oy8Tge%k^R~2zy1kNK1zR^NM2QeBM6N z5Hbj%JTpPPfmb%r6=>ugCcVJO-`?ri$TzLF<+H(OT2>z7sGiWA6{U`SadgrP8Jzg_ z97SL)G6{(WI6~zPAm#B#)=m+FLfPsVrxqW^>G>;vF5F45Z_vz{vmO=4_O$|$<7DU6 z1kbJ11P1d0B}dPJd&C>`*6qMFYizQvLH}e_HsN{;F;DeC7A^rmalh};W49cYSDcv= zKJ*!9hi#IY)Rd+#+F(6?90|}d7R-WEh`sONf>*g3K(rGPDF|j6lvjI322#`D*97=+ z5RXW$$tO5kt_;Uy-f*FhMQ3RWGB<#qHlb^n#6^fFjCEiHwSiip(6Oe{KX5-#&wU&E zE-8i>g7<_`y3wtI1jAnwb%tj5bvU~g`t9=(^N0GN9sGhiVsNW-dn4kI4&(%X>cyWoYx?vJJHt{&HE{l(k5nWY`!AkVzLnR1j$B^!D&J0)f zClY2LFgOwD0|Dv$Y?r|dt@?U7zH-eK?$+UfuW_c*aj~N}9Vv^%%kmBGPbkMu1(7DoW&b3Gekv zO9Wm*AwS9=yokZ{5s3v^KA(jw1HTVG3>@?{F?(XBw*`td&clLBW|_0TmACXt#0j!w z)i_5`g>iYPq!SXQG2d>c;1UZ?xE^aK@u5=!nr$CU%*eERh6y=-y4fv7(@69sp*l_k zB<^b)X}dOML*&)UVa*@D93-LrpafV^C?4EhSkc9L(Vc$QLtdB52ChoY4nEKuGvX|D z6Tenl#tm>W@@U&?IHqKKrkCSWuFE`ook#3c&uK}`1O5s0)9~4yV$TE>1zIf*#D+F> zW<=A07+MG2uCYo5XL;lBE5j~Sy$D--;VvQm7YAG1E4Y=fARZ5wAA9oYuAmYqkF*Iv z>nY6<4tveM^F27J77TcuG@67|>@9R;PkMB0_kFVUW}evbVH{VpP`N|h*NT(PiIp7u zjiGSg+Z?VF4~6AkH6MZ8r3gI7RJ~c!QF&QeT3dtt1e34lcf;8q@qZ?b4^wd>kCIL{ zAzXWMC)>;lE#>m@yM8yGJn4TlsRyi0;)>@yICj$klII66~cZD4h z2NHsdiH*FB)zn(^_diXx8_d91X{%17X)gegwbzC6SuQ4W8g4{3xs>3#WSO%sR8V`M z;(MNnu`n?0|9rj{{?Si-Py}0f_J*$f#}n)8M&2SR?j6dvjGM^se~bhiJL|2?kXG>q zXG-bAwjA(Xrz4b8;FaoT^v$t7z zYoMSbL;{VpIi;gEovF7gz!WnYz%F6bI1&`SZD%(Vf6OH_7;r@hpsRaid+eU@G*PUp zPK5%PP}6N_e`*!fx;eQv7tf9wwWl@*`GZn1braRmw7nwO3j5qo!Q$fsFd=iuPH-{Cotw)Q4|0=Jy&d4^ z1qbuXP~5_YNPln&WlWSrLBEBgXt{0-1#;sZsfUxDlt`Ggr?qJaE7V19H+c&Xr8_U% z0rKk|P7nu1H&8fFM`n744P*tA!%6oXI~+6MtKjq;k{Lu=7=sBSZdCtDv9J3`vYWAT z^N-9{{;jRuUy%FlIO&W_i5^0@F|z z?%IyEKvL_omv=JPO2u6yEa1jq?rPTX)a;LP3ZLpj<`&GqTPWRW&+wSf`ooxUQYuQR zO&JZ<8`p46s|Lmy@j91+Z=v#7!Qj_K@I6lxt`bIWg1v`%^yU5()Quo~yAJk#RAx(j z!*Lk?d;StF5Ick9w3f{5qtws4Jl_J~tSew5S%QK9_URi)iI3dO;*|UwqFM*>a-ZU9 z4ybsWO^KoCj@Nl5L?ibD3hgpw77P$TjH^n@zl!o*?x%#B7xTgBPdkcdx51*iaq9K% z&Oc*0KZ4_Na61Yc?pHSh+9{Z?^NMUxcmu%`&9PzDn$bTZT1S$TzagpVOB0wN3j8V4 z0lMm!5VN(Vnb!fzoGEsBJV$1x*=5v{7U}VtW$r&z>uB8bI4S9!B`V^RhM7;WLi#0Xpt{>X$faZM-uAFD;+7p#?*R7RGuI6pUKO4CDEvxP|wd& z3ait3;A3x`maZ*Uo+OqiB|2Tfdz6td2piK#)qz`dr4;KQ%OV17n@zMB>7n}Zx8IZj zoi)0qbOY*I^JBsAKZ&%Y>O$=$ z_Y1of@B=omagKaGx~#rJ3*^b7a1$4A04=A^48ZW9YK&2FUfpzjkxGj0Q0fh{`Fx6- zp0wRRvf zZCJ;3eo}SGrwTShEyHO6Y|5)m3^cU#<98gJNC$EtO(_bf2ba zo@}}Rs!Rq0@ouJf0+%EpMEaT&eqkvj^x|b(NF$}oYA_~!`kTM1$+q!0mR7P(+&uxb zSBUqM?$)h&eDLuAsK(w+;qm*9FcHXKmxI;n;g-8JbBda@jbT}7z4x}Lp7g3R zHHJLd2oR5F+N0?|)#(=t#P_81TZD6=Ht#`#co#Y<>cswyUXjThXG01ZNEX?FGbS0Xg97?3yMU^x^ zzt$*fyZw016YjExayz5*FyPZkAQ%fhaXljhu5kw|*(NUz--v#S`aQDjQj?Dxb!Qw+ z!KSB?&S*~QJJWmE=eHp@PFYYuMAeT`9-6U2C4q}hV^;BF!f@x3{;`$dF(PuzmU}F6 zxw|{`Wu5{30$(?&CHG;EWbaWaV6vjpt;r$>hqO=Tal?P0yqz!_@lO8C<2Csdsm>PC(gk{f= z_A;qNxV{AEAdF{}(6cnRX1dL1>8Wr2KAVy1o#l9yiJ+b{-k$N*tmSPYe*2Lz`E;O! z)ZESZW=@I-7o(;-RGKYA&B#2Hs7afz?w%JXzdat#Co<1#_%0Yq%ud!XEMar^_ZB?j z7j$RC_wL5D`MmOsf2CI~V>`KU%~!|q83l`X{vSJ4H{V~3KcAicg# zw2sd}W!)kzC`!=Gd>fXqUikWI;9~d>yA~Hp-Q?-u1Jjh4B`aS@IUrb){>G=C!X(u4 zRgtCRMtBWS9VQnna4vQ>$bj!#mJD2MyoIqqal~=L?>DWaP`>^Vz3M*+ySHB+V>{P= zPSZvG%9}d#Q8r)Qo7ET8YyL5-lGLyAdzs`pD|yS;{3LqbM9RG>f4I$L72r>O)b6`f4SwfPN`$? zfnJZIBK*Ub`yUJh6RFp?Z2&R>v9upd_!H3E<#~{?;ExZQI8}*|gx2lgfOiDawN<3m zPLk6*(#;*QSv~!}oka8?4b>+}4&CAlAM(ZRbFw~(0Ab}DOflD>6*HjgG7H2%0)a$| z=xe(X?YkSyEcbF4s)`b(_1I5F@OA$&{lybMtuLA= zf#3rfi^~;VGaplrj<7Xas#Qu=00frvG#xa;?H|XUh^RU|Y79cFzD?J^dVGofvqdhQ zecpF5l3LXC_r;)7&x=48_8*^roO)fwM!lt#1AO~Xc!8eehvhrrM*S;6Mv+cK=##sf;fL)3+S}ZrKphp?VAu; z{mCgTfM4Wms`=IM!UJV`s#N`poU}NAU$QuL4E)pZ=-1rWhCYWG za`I!(-??3+!4iKhH~ji6Nt%5@^2bTgs6+O{HtWSC zXxc~yBO%opzuNuJY3BX*Pd9wULJaEu7=#z6jh>m!_;J1r*(Yg1F0!2)XhZfF{r+w& z9g;WpheODnW(OOy(;?*L-zT7WmEmA;@^AicvBfEI$&cJZ-ZHQ})#?i&pJnjc&+Y2$ zzmL*}r1{6Qzwt8@mzB@_RsEyg;5)}lt5bS@Ci3Cz_NNJxA^WGZY3v!NskWBg+3<_g z?2@uw=C6J}%x3(?5v=adz;>|g8OM3VVJW`_oSvG@4tvp0R-pg#X`=brX!GjFy_Ga! zauD}8`c2_<05Nhd*Nl#HCo@e_hNfZZ&v!B zuRZo%wG!ET{A_J}f3{zXZLKM0v)+Goe1Ca>ob_F8%FcPhwl<)=wp0I^yd2nHHh;D| zPOg5o*1x{eB(nE6_FaYa?2>oMr|{d4|3}4g^}o=PComO^r3K4qKZtM>49( zG1`SOk`a=u1e1*?lWPc*dkm9z2vcy(KZ8_^%*+^OW-K$7`@c-hn3*}b|BaLQFwFei zf5)lB1enFi?q*8N%392Z#>^&;%+7Yq?)A)GG0a|B%zkk!GTK;b1eTfs%PoghF~h3s zVXX|X{@$#tGOU7^Se2AmHOyJ{ud!O$vLSi?QYSVH8yl95gO81q`7dS?*JP7X`YW2L zXUb+`$7bTn<{tNN*c6%0&dk8h%)`#l&u-|0qvORfQQ^dd{%vh$pY#uGiotn$s@C#NBel{er|p(j-{eq`VWPd~*Jg;53sn zHjtNBP_S|RU+Cxm_L7X2I{y!7$w24R^n(mm$>-=c^vl9rHnohi87I^*4}Woym9=w9 zRtc@k%gTRz&Hklg`LUl1pE&%pHh*}$_L3jBd8_kvnmTR~J-6MqhF1@)+PvPpeAQr5 zCs4-8q<<4U$0iB5BBEctGxIRu-OF40oe%93;*X$DXw$_iUc@E0qa`1hZ)$WPXIBPG z0|h1T+v$WEj}^RsT1r;2oUs0wc&`~=zUR51PBm8IjJn-XZ1aE-Uf`rRP!msql|#ke zS?TWl`nI>_aq%}QRq&Ad4}MG6C5tuf7&X@bcR@|U#uC}r%r7|f(kG3uCDN|OddWkr zs@vKZuil1#C#zVxTyD~%@7vjtk68&_H_k`SoOjZ3IfUe6WB)Lvp-?_q30cu7E&gf^ zujJ$k9lpw-F~>`vK5j-lKGWU^ie7tNnWh<0vz0M%@)3K*qcm_tptu-nu0#8w-X*M4 z0yyH?+}^Ck;xSXOB+B|kXDj_@ncP^=B!r8HEauVakor=jO^2mq=Ep0o%U}3Elvdcg z(o5dww;&deJB{7T*U$0X5{z2twj*$T=uWNRuwu%hw4R}V1$U+Qs<*4gw~lefdUYp) zrgiS?rzV{fM((=VIVIm~znc%ecBQHJ6P;U;4b(C6EWoi~Tq)S`!8$oJ~tFW#CgyLCScesDzv8090UON~B;tA|sZUH)5X)#epwl0iQ(Z zJ>0$-g%ak*0^)@QzW~rErnI!%Ev-HvLA}s!=|zBOkuy>iam<8-Uf}b=d@(iL_I5D?SBrC33b19RNrG94`2)fXzf$?pU)5UUJ&-~g zym_c2jE$q8j}va1`PBn#$EV+^)Au0bszW(zon!oo?ZTnaPCH1dCpd6l9@_hP(&rM#2@v6h(uIY9?~7bK#zhH?>P`Ft?{AJNk#@wjuVl0OH=6rpb~*vA zv`p5ryi@#8_uyHhn<&E1M2e^iGZ=$@9jKIrn(?Sv&Za!QIHZ^<=scvVqh ziL*Te6*eJJPXp4ueE##ovkq#kbXI&;{zugXXxp8#+~?Ekh-IjB@zb3c(e|Z&#^L6+ z-%NQNvn+l5N-)+8Ww1R*8SBprR?pjdxanD5t{0w$pv>KL=|W~0A=*|b1pg+(>v59@ zW?=NHQxigiqk2}Hlkm9tE2QCQfaK`LNUf2Z1g-4G`kgn56??4Q^N=d)P5SwLrxn{ zp@2qZ7(wolQejA@Cw{=u$2c3(0mt~@9NC#X(mwe3#+u+)IJszwuM-e3E}82->QZfO_)9 zThtI7|9ykaqkekES~?C~nzy(@UQd^6U8#It9~j!~B~3wda}aCti1VhRFvz#yH%fp( z=IQ;FWC+6vMdzA4>Wj6WThf7``7D8oi)^^=`Uhx7w6{k>a*!4jX4q2@@fuNMzf^rrT9BEan`$5t%)d~>OK)qYa;+| znYY$cSLdNxO$K#D*+`T~+T9Q-(`jh)H0WH~FM$vUqV;3A&Pr65B62KHyCbST4jHm~ z#oty5tw!(L;}@~x3H!GPVFBfZEjWDr4``jh9u3qe`-HGm)wt|glnBTL+y_26fxJsRQw6~@;sK2^)H)d62dPduLb}awLen4O zgk(@G8aM#ci#nKN_N&l$zZR^1crtd}f{>mER1r^s$Ytg7{7xzQ?{x8f(dWSYT*vek zXSx?|=4eW-=zNjjGSWyQ9N=>)PvoKf7J|0EDdsoM40$oX!fz_a>JDN1iiX~Uz6r?1 zG&%Ej!x>zb9$Mz5{uX|OkDhlhCH0P{lVMsiNRkJLOWIzeQeK(UUepnE{ea*L1VKBF z2nHe&DWmTTB}I#X4fjv4vpgJrVRl1WuZjX><=actWX4$^yxG;-tD$Og_>#5kGAux!=|ny zw{c*)n*kJEAC!5CRtcCC0}C;A^OWeLO&T!YYaY&Xe|A>K0vCY+Nk8g@w2y+`6T~1E zec+^KB>r7D$qKdVxe;jBF$hA)PqVH((%k%Nj=%uzVZvIF;e9TtV9JAswM%?#_{<>!h84Z3V*iT z0AO0nba(k2pgmEt&{#i>1L}xp;bnd6*7DIkY zFm3aL`AQUVnzc$^e{T_&BM$Zwh%-*I%lX!!KmK<00jTrhSM^azHIdz%$YCHJml+Uh zZ2>}`s&55@hq^^A&G9C{;Vq=0Ks2y=L~B8*~L?i8|An8w)vsa7q2ww z^XoHdVGajAlta+2^4)&3<66^uwTWrf+e@;&GM22)z*V$90Id3CWBvaGANtp4@3DYfPDF&N;)=_f6 z^92F0G9gi1WNBTU+?j~nkA*&sMvfJI0r!gCPL}edjxl7ZWi4PT<`p==GSK}fj~S7V zmRD{=K_u?jmGzoHIRJ+AdMwwaS;umQPz6hY4&%)>LSq{7;$~^?03H&Nbq5$KHKwr* zr`%5kD=_)Azb@oj04znsuAo6BM!?^mMcQMA_NG~Dp_a=uAVIw67QEQtm|t?9Nz;Wg zdjGhsMK!g-Vml-~bk$D!fa;}r%0|M5oQf3kB`}RxEWV)Ji8&cv z6nkGY&L|R6Y#CRdFh3HMiqJ5a0hx6%h2ks)OF`n8vH}5$&IP9AL)O$(-AVyPDyZ-A{!zH`QJwGK?nXJs(u*HOgu{F25y@>G{TS4^MAfohllj;aA2<>aUQL zRxHh9)LC*Kf9+r+k-R*bu~A!TQgZp}(zTcybd9~Bp;ykYNO`GC0{UasI`ipqyv~{L zf9h^-CRzuAW{I-!Z<+h@y5cuLw#JlMGuGdY;hlk1h1--NCX{A8Dm_I>B0)eGZlX35 z6o&$O@G|>ZUBBI;QX`%|`i|)6L66+v`+h{J?Bpv%pu$1zv5|PgKE=_R7^O{nVO;5| zDF9WD7FY@YWCpn0o5|=2!b;TW8X+}H-7g#Y$?6rR5d{so(i9KT#og4QAd1uAJKFb4 zWp@g02U32hBkt+mW67F8hs7;-@xw3>LlKohX3pskPmEE`Z zX13Fk3RD+&V*>#y%Id~=qzmwY6xE0kzWPQt>17h;UL^_)Z>aBhMPXS;2}sm0XwZBg z4u2?sx=)~q;-{tO089nkQ@DBG;Mgz2(TWmYd$R+;0KcmafYeiJ7|-zP);r)BX%$Qp z4NVj}D8tlxYdL08uD{aoxunTf%fWieHJe>*n6N#}UJOD`qztL?D)}VP?m%XX0`-?N`CAx-&D(M93{N)#PC{M(A zsRcTCy^%RF^BZc|MQj5W!yAR~)j&NjH5DO+q^ECiyP(?QbTfzKAd6vboHNp?n)yol zN;e7SqiWeFyC@8R>Ook0+I^6FN8`@RR%xSB6QMGJfR?tCH0nd(QCX0!kotC~UK@{( zA(i8>^<&KTo#lJkcQzuO#-Z=-SIF!>9;lTZH_e*qg@$C}6`A?Und%}HTbRE;K*d83 z>k>x8xlsJXVSTNlKsAo6obp z!4A0FqdKlv3%)QZEKw4)D#Xc5+x@x%e<-#8QOzpUu!8WtoXA=%OXEDBN;+EpwZ^94QF{T}Jt`Idyo%`Jc z29#Y0gqP!cE(s?m9+)2LJiLh3a{N8Ok>=<6AloXSNzqP4$4)dDK(#*@X)4G(T5Xbs zHZ{&tDasqV+B#&tG!&DjZ=>{ppf#*RH7qzZeM;c4-|B4^rIAM1@P)jf6!j z1Y(D^P1>lJMgmPCky+RfWMdKuD{IlgJQ@hmbu!Ep=4BJdcmdGP;fxu;``4Am?w`*cSdtCLHP9AALS2T#w;Yn15kB4>R^IF`22%da1<9j`u~9oeJ}!=QN+O znxSU9h?G>yuK8;VTC58ulZ;-t5{pUJ@?*x*Ac3LPSAnW&w-z5k4`1Dr4$iB|Hs4G(GZ@=j7BqG!S(e8xseOQJL5*dn@zu zp`NzX6AIx8)Qc?!t2;@`>_M7@uGPCn(Cm+^orpCdH-z+r`QU!&=&dysZ$8$>)w%-2 zlKt8<);9_gPpe1+oIfPP&rQ}!#Fxr~!q(ns99yYa0JPX@sN0Kj#_1OGTA=pj>m1|s zI;u`jZXnlwtVsBzoTWxA9)!JL_-PT?;s->l+troRc z&8kr~i&C>S+LC{Kuj~4a`}Kc%-?vvD9656wM~;VazR%D5BfNSXp^4Byv(Zp=DXcYU zF10ePA)kKL5e4y2)%~8dL%&;Nu@?~9Ut4Ni)9HFV?3KnhpQhJE@10J>KE6J4cU>&H z%R{hccV?wvZ`EvnRd;!vdFR#dY>Fd_bsDoxFU+Rp@(pz*Sf#-i8m>)8wr_G6y}zsUkPc@i!RhIgEU+1-vK;?Z zDJjEV^QL^7b(+oCM!gV8D0#(U$*|O-WA#}cgCh66Pd8MNA-M4H?Vi&vaF)LrcWNe@Bk;Uzn zl&u z@FW?w&3Uz7g%(&dJox2%5ZBDqXVt#He^BjALMC#!=&SN0{blVQU4(BYJec4)$H57k z-LH4qqq9+LL`?lk#OGD~Oz&q#rFW_fiHf$8MK;#CqmKD-nfrGsABanAsg)c)i}a^p zKQIi~ClEfmTi$53y*@AwQ;0gIY&uq@HQx>Wc4>tV&j?qdnaQ8+$qoFJ{_063b*xpv zY@W%)L)9uv`qL#F6m^wtul(zQ0c6VgxO05q#sST&i&HFtohI&=S=6uNNDem<35v!? z?U=XTMkma~2ajTz#{ZsCA=W><1Hc`vlgrMFN6$mcRUTQ~{$0P^CB~TQkSCc5dvpW; zD4t)j5lP-hezCCaoiLDT$BMoI2fg}5UFL6wh|TdZmY)}`u2H`e9D(m0{z$ETD}-q* zu5m=)ZFAdDZx#6)7P0B33i&a~E8y`4x(J+KU+qBrzr^+TYny~1I@8lS2)~F zN~n0&AojVlj*2SGSB9Z|Y*j6pn%gk=e5)KRfcJB?(j)^lvN$v{xU8o(bn^JkpW^Lv zn|ei}u1eJ$%{<+Yi2cSjWAbZnweM!q zvfaA<$MxA~RPXFwyKJn?e|&uKn;4&nd^5N8)!}CZor0Jj9}XhnFa3Af^biALCVvvc z-C`yur@C9lV-$UoyJBrS@?N46ZRdAO|WP+?B+eMz614pN1802 zYfud?4;N7_giczs8ghggt<9yE7oY>r)IS~~%l&Mel3d;EDFSSa4b%fAxrk|?#?}Kz z5q{{C(QU7dBlY;f;1}=2$Npv+i0sCHH&B?x-48O9yFbcrgn6-ODku48LlmoC^2nq| z=JJW4v363Bh>9*no4AR7$cx-b-6mU!6n(YMAJdxe)39b{KVE=acr0$^n=zT>o3~k7 zH~q4JxzEBSEN}JAezc409G!DuO*gl45#oILxh^M!uG>{e@zmOjD1&~xT-I;=4yY1%YQ6n1hqB1iwB*~FbAwi?<@frE z494B?Hn*JJoXn@cotwY@VBCB@`AcrCbyh0;L&}P;{L+g;r4V2LxdQ5gw_iU!@VoVc zj>*5&iRbO1B-H@pt-co)uL5f16BPoxdA}A0jEudMJNZRK^l!1@(!Us77NItt!67*S z{$U_E6eNr$QMUnu_`quVVD~^$IxaGH2pPBZb;3)*fSiMy93?@H)u(`x;b9sD1B8Ns zo`QpsLR6DN0Y#x8Ln$V99rbdHr}Dph4dd(rsRKP}Xz2e*b>R(%j5NY#G;Vij1^8fG zyfBnBOjHwww_IqO!%VH=FmgByUpt5Q9P+@CG;pLOoRbAE#t#>lx{iI>nA1^^(NW-4 zhxGp!HYbOo^NghP^{3ZXV=(k#Fu%p%mc`)V!Kfh5X#1}gx?p?@9TO$j|1umh;p1H} zCN>r({7n|T;gAz?Z8+rfxu$YLQcS{vOk(`kX)iN}>$Df%bLgAKEGf(EX3Ojs$igMf zBCf%rsL7)1h);g8+T!(w3~X=)HYR#DX72yE4Oy~3ENzJg*n^wc^0(~xky z*zg~>p}4|7Aul_mp%2nL0O{!cKcHJA(l-hjp2*1{!O1DZi4x$H)Z#QTTo@xR9cwPU>d-HU+asL^#?C`W&LhBbo&5T@Sp6~W5}yM}SXR=jrq@Hppi zUUwf}k6_-wbiSZi0SaaTE;#`K)IU+L7y++n0pB>3wk^uo0d>PlNLXFSB;eX=sI32w z*f2)KF-asS3GLvI_Vh>l7mIqQiQ<)p|LMTHF2KX;%UJ}=IS0!H;Gb*x|LzaZ;5z;< z49u&G3Dd?v0Mx=$x$_&>#lwPTM+?j&y)9mjp7@>^4Y$eE3Q zEW@H+uhir34L-(J>0ZaX%pVy(cZ2JixlHjZcJTaYXxsWvysN4HRV~j@iA(*{8l|Yi z@0T~{rj~U44JMiN8=F?I<6Q-e99o*Ow~$)32qz*N+muwOsQGvGxC|KAs~GZ~gw4J> z(?)yNpvO03p}~>PD}A5Dds7QmgjyeiQjIh@n%NBBwg)7*lJcx_rajEritwk6r|CPZ-IK&ukR1KzUJ9q)Qh|I;G5*Wu2MpoIn2nA zj%ZO+9x#%x?B3!|Y>ItDJhc=0DVE{u?J@4KAwAd6&Z#2RDL_YjysPe^;d9vS3GRm* zA&3MzWILJo><=KT{djfG&4lUsc8;V3%m;EG+Vi|hEgqhF7n_=Z_zBQK%n>p|$!l;u zAEne@7-xI6ZE|1F-;tfal)wterB_?;W?qt&17ZhnCeG=HkQ;9?gk?A-Fy2k9fzd^L zlkH~>gFdV&M6v2(({wgezCFy+lrtvFGXcdJKM#vdq=$MY)$rW+svkj6p$UrV#LP6* zNE>OIV};Zxad~r3=7f4UC86~dk5TFcTszOYAY6K6Fq!C4A+TyZ>b9!-j%QV9SbxC- z?d}R&B;9LiyBDu8fI)Oo0-r|nhUyKKTP%)lCC{sP+GFdxYpga}IUY!2Zzhe_sye*J zeDD?jLJ1?T@yqk}PibsVX?ktuMnvtGQ{3Its}$c3H)^btnKjhAJXC#0_oo>~=9Xm% ze)Bqgr?(qLFP-DUUDPun4)=PK5+bR#sME~-3{m^!rwYH*6UZ259;LNBaXgh|UO>&- zhn^->8#{9T^~5D!wYKxU{XKnKdV5xKHLeZSG}7FTuAd9u8j0~j#S+JeSx410)tj@m zkS7BMCAi?&p;Tds3h2uTbT`U}H`0Q&S(BgR%fT>0w$HZYLcO`OXr_@I06RKYov63e zp-3$h&P|4WE!W^nPGlmJCLbvTi_MYK#q13JIJ_@8;LQ7meT4?OnVJDnb-}jtzR$w4 z-hB>wGL8V~H6<;qFn6o+mzi#gk~7^GJB%JOAosId%cP-rql zfwQTE5f+t8wPQX8^%jzu9r8oGn2{qy6=+}TSPsc^^35=WM!`=5I@X&QJ2PWdTuKII z)lOyiyDpZFA^$spXaE`4V@;9oT!gSHAo(%~474C|H*KtX=$3h;C`IVM|i0&4+eqXko)#!C)$Yor*-;qq88fUQA8-h@~zV39@!@o_jdZEC(4gx>NAWud}ZxGz6AY*ahibyvw9N&oEp)*vaA_GYcdja zq-ad$@oQdX_)5nnGp)+d^<~8=OA|eZcZ!biRBlK<-w+v2#NZw#@);muV2Zg)MyH#r zsHHUtw1Bp_g9PnY($9C@X%hNqZ(ijmH$98!`3@TsS50ig6D&x)&9buiu z#O+W6Yoc5+jZD2&nV2q4zZ8(A_A_!-*0$=(<{L^M^|GKCA}LEi>cFs^i5_9Xhta)g zX)==*A4M=d;;6{sSv{W}V*7E;_Kr+Q^7J^5WmVzfb}WpU5_VOt`1RYkHcD=>J10)$ zv*#|R8B5e;uUf3+CKODpmzn(Xc8m2kfyN4)qd@#+CwD@0CBlXIXE(ubB~D@=?_i28 zwy@)OtiIEBtHkT(t-bkYbENIep&Sg)NT5VV^f1TuA)Fpi;*=s#n2;qEuGO)2yZW&A z!8gd){EME#n{1!idU$32er5_5?#3Lhx}>KQGQ^FuR8~<9z0;1BS58#>Ay*RZTTYbx z_e{6e2`ei^)HQ2BLZBtmW>4}+e9!&~nNDVBut*nXx?==fKKjCT=8*_U;q-Q&3X*8U z8kS2I04iqRivXyoDgPONsaok&KYjD!8Cr;)vMly!Ao8bhwqo%*%}c9}gd#}3}f=MV!=2fw4iw}#L5b*2@G!(#F%T%L@}5FC&& zfZ{V*Jm|}NNC3#<%TZGj9)|cMU?m$6Rdx{xSH!gm^P}X!>)qj!OJ`-{GT@VMTiUO= zgg*UcyC_}zv}fnKP?K7O5o=gXB#GrSDN@TW_Cs#zsWu|vEKxaxH4ivcBZs_1 z0w6)h)PxQ}VdID;wEEBz9V*Z!C`kpiy;=q62Pj@6l!&X^jF`jB$eg8u!w2l7tGW@t zz!^c?1?I~St)K9QmB&-YLa7E5jJ6nD=QyX#ji0F4<*bU2A;P_6)RE0BT+z_ZESOKZ zep~{;+h2TZ)+{tkjfNoMgB!Fmh6#!LMOwo{ejjN@6q-zvM;wNh8g?_ysFRz6N`DLC zt6KvV@cD|?-3A$lerjVdSaas(rl_&fBA|_3k_N$`0fOAX+EB-qI?WuYf}f08as{yz zPYQ-Op!2ha8vel{0a@3B#cnZN;An5dD(Nj2MbK526L)8OpB-VyQYVICjPtS zmRJ!YT^U-hks<9ueR&#aUPmWg2%5)6adsiTk>Ih|LKLUGIDe2x!l5hQh)wK8PR z1K!z^LQsD|`ih)ja+X&xcpQLs@CveKsmcw$pL0>F3s?mQ*Q znJI_>fGPBP=>}gWJwGO3$F1hfd;+N<9L5|0os!0GYjXNsBuTVEa*Xkr2m*>(=buD` z6_~s91diyeyaTXi-p-5NzES=zAHiv&^xWG!uyiR*0$Xf>kHp*$hl+T z8i%>{&3si14@}IAZ(v<-CD7fhVIC=0h4eo-*iJc8f!Yz!ype{F_L%X-K9tTQ&+Z0l z4FDqYx%*Zm%sCY5{iEzP9-+8Qko*byZZe^~@CJlw7hzB@X`yT|tEB|=%^|r|JlxIE zYcfUG_Yjz<0Y~7_@mdol9l^k0$3oMi2XjuPFM|1Vb>OM+(tS@IwjDv0!BV~|9k|>?J^mb=B)s|{&i}T}cDdSyEKUlV-yEjSWiC4J z4DQ!p5YPZPI)0Kx3rbW3qLVA01DH%J=NLd;K|+uVnxqMWy_b9-XqDLS44+oJrB{JG z(N!S-NT0bJrBp5{vBr$XTrz)-OALji$dfIh(ASX4#DpUz?8UC zMLmEqxEsZ>SfWcykgqQO@fr=GtZ?3Z&-4Wi9e-9;4D@liY`z?!D7IvYp5v;$-b5lt zqJia*ggU)~XgaK66kFXOSG8?U+

0b;(1DnnuO+7Zk_IL{9|owqwYjH7YckC*=Vh+U}B( zJbF`0>(`9PR6c#fhj`o085k7}y?sXh-rHi>J7C&BTpy%fx0I^7zPgy$F@Z5ZA5rAbm*0m_MZEHt~HT7DV-^+7d4heo)j0OA^os zF7<%S2v0nE_0@D!=Rn~YQsK8G;a&b%Tj5gKclM7!kGp!U6m)F#h3&}wJsta;pWJn2 zL9wp)WfAsU7We5)_TMEoybSV+EAJOlh$VC$KoRqNlN#u3fk(3p-Vq&)!gcpVzAa9A z5}xu_PIhS^@$X<*;h?+Yd#~o93V(bQubNBvk*2{iAJkU3RReH0fy713 z8#c|mUw{e@D{EVT`VRL#W&haU^C?Uu}qxvbh1v&)xenySZzN;xnD>i`L2eIO4mns-KMNj~6r}Gi^Z=v)|KcK zqNdl1-0NTOvNnM!;mYVHU@7lGtH%)(=|B=nBx00^5QYf{8 z4(o?>Ny2k>B1*?{-$9`WGI*C7wmn z2G&J>H!|3@e?xF2>F`6_I)QSBePH*V2P9Uf=4Ha#hy8DTzI$ofj@}Ir+mRiPDM*9R zZXDqc0xj_|viF9n)|7}{+h)n7$dL~iqPP#p%HQ4mtJ{Z>`&k7hL@M8JA-W+x)Q4;b z$HHOW($KE>1G*Q$KUZHa-mk*Cn8mp?zC0i_(^AUqWyK}ol-eJBof0ZxWj3*v`=!ZrghR;_`#_^ z)i!DQ>B9l!+H)EXDm_1{6~%WjZiEz54}t0adARa&NJjji8|TzY1Zwy=GxNQ@Fv+bj z`_FeSvJKC(9M=7@guBU{?~gWZk4~MawqsY`rIq};J+A0SwSAs4=dSukQ{&v1YC9EJ zocem0{rjK04qH6Jrf-Kp`J%M<)orZ<>=#O>@rBgf4Z>QxFc&3Nklsrb#?mj>g@eh9VY(r*(-z7^&I~wKB2~2rVe{t) z=0j!N%oEO>i0y&`n@{#vxer5PGCw=CTzj;OU(!z{;hKiMNuqX0ZE(top;G^<~$Q;9U8rtiMzmGk*h!d_!pgyGoU`g zU;pI0fxmJ+r_AOSJMiVuH@9b3Mgh26MpsHDHs@tm7iBgb`B(O{OP?}vxw=A15f z+<6pEIsmtGz^gfSh2I3fb}@<;KRI{!dgr~5m)@l|X9vfh%51WL*3>@_)yr&lqHt7S z|KQ(d0fG2I$2fjuK0w7z9l6GfpJASfb2>Wg%)~_=A9nt;EadMYb@ui8|Ga=yep&w+ z|7$Jg{D2p~9KYlu19v@G8$90s=gJ!IoADq2JsD_CB?9gE@2#w{hle22|JvF5`ny(n zBc1E1l=<=d6#TwE3I05^g#XO>_3y#2lSAtNT>1A=uMaRt$o8-9E&#y_0SZkxNKizG z!5a+WR6rIe2+apZlam_VfKakPkP;9s?&}6Gyu{Emm`nppPC-GA;v+|^kSiLK`+88o zAQW&q3MOs}X2^AY7Z(MEqU<%_vaz7H^`Ul+r*`wAb`PWWkD#HUqk)rMQ!W;I8f7_} z@L*av7mQOHCWwNGi@`Jl}}oRj97Y;p3yB{bpkI&>5eItqF^O4R?8 zY_Z@=y#8?-3bN3-M_vmJ<@p(~>erDouM9@hTZ}gD*9JpZFGf#%gO@*}Zxmx7zQK$B zzx9PI|KVHz1-Gur);|(MF*znFiR;vvlEyXJ3P@wo)?>k9S!{2xGD@&=Nwccz{L|fK z$7<-vYUapBPRB;W%trU0`mX;%Ttbp;;(~1W?k+`qz|4&8h8LTI$G>fc9(8P9QTQG& zw(w|nI<9})48^6{73C2OWC(Hde{6=q2x4JI3i3!gQ zZywhu9(=~kE1m~0F1#-8qT%J{vS2bv>*n9QZ`3vtD~?cLMBc^CceS~KElFc!a7#M&WXaF zf%xt&;lN-K7EY1i6tq_cIv6Wz7b9 zTHpPak^M^RxHqA_Zojf6?Bx5G5osQ+O2GWz7Dy}tM4@&pQSzxSfK`Rh@MnpB$Melj z8h=3euV@1NE%RS4H}V_n9~<6#>!Ta7@qBl#`Q`x1IoYz6vONm=v+qr=r&bp=sRQ>L zyut9fn)QteuHdq*#-N=AgK+KX-nsx{t?|w`XOEGMd^n@Hc<#oN?YokCl`f=z&d94? zWL!Om)ryJQzTF-o-u_7S708DO4Me$rR;vUb+FzE%{S&6xqe9u`Ajci5t>2T9| zy4cShRt{u*znC(y)%wg)!&qx(Qo~~9G6Z$WT1{fN)pRUc^z^R>^|Q3H)PH-3T3s=9 zbeW+BsY4gGS-hUFwDdsiBv;&_WP5i=RFe)rr%6NWSGF8~Uk-e$$`Y=oxLG_Q%bo{- z-_&(6zSHM`^#jCavFigKBh?ewI3aW@?+7cCv-@!Zf-=y`aD?RZq9cqWogL83GIkzK zj4=5do|V@=n)5igpjIrNNc(elgN6FI*N^C|Q9=+~Xu)X~4O6133UK}SyBkz+n%A6Ee2wK1UT@S$^-5f6z}V1i`4Ix*@`|flJEX~woa9x z4r1J>seJi`%B{hJw0xQ1j>=a5krv~X8 zWIBJ(sTHH5mwr;+;w=?Bc*E;3(YxDX@dtX35`b}QN`4x*^@jIWggFWMVUWbQ*Tn1N zsLZ>j_gV!y(44W!hVOJG-lBU%-t66vmt6VaLu+`Tc40@?JFjk z_o2`obpW{4T99u`swqazXfQeUE3zo3zSLxY2=O+CGSt6!!6Y}4VYq?Ut-b#QN7tINeKEmLqc({jr_I{@Lmm&djQ2gzw<-s&U3LoTe_>sqyzJZnc-IVK-zD z^7973AE^#T=XH6+c`7O7v4#xyFoSa*wTS>)jUPVKgDq$hO+z`ls(TZ4y3VzHNCrZ( z+MBOT@6e!V71Yw8Ds?911nR_#!~91y2}7P3t+*Z*o?i6GGrUK+tfLq{{~{K%@wCvH zG#g@~-X|&LOs0Twv#fQ`7TUL7a{0JNHCU=1%v-~%27Oi2ehfX+20RyyKBo2wdJ zI98q^CczL*px|7hOW04S-i*_S!S~g#Bnst@NKv~9gjAz@2|iKl&;mV(d+-iabMJ&vv@_Y1SuEeF#F44g z!8|?~;q6;Vfkf;X?eNT$9-A;aq&4 z3w4}4kpw0P%2|W}Jmd4RuMSjeE65333`=O{lFy>Uo{+MpYc4NXfX83E5sr0j_^OM> zI2+V7b31i03u7qka31Bw)n4k}26rFu*>-8B0Qe__(M3r;FM$dES+@yNnJ@+MuL`nl zsavLnT3eA-}(ZO()h76j5qfJnH8m z;B-v%3e$xGXZ&a$c6QT=-x$;USzGgnLDL)O`gPf&n}BVap6$UKKIx)XyI?D*pX$2d z+I~KWg3gL-q9#^hr~i#)1F?~?Pbxj(ZCb9+W2}_^EftBMvpcE?AYc;gbelFKr}Y+j zf;wMzATjjAYtg`W)G?q#ABjy_@FY*PK66HQ@<<$kc%lkQOyEN1-6QY2U`Y`2EKnTW z#0rTIc`Cv@fK#?N00`a~l6Fa4yXkUk@8%DF2JzR{QnNN{;{uKZyLmLUFAq1es0z%^ zB-TD^iZy#dpMRr1$>uY);biae$7mOBQ;lX%u!{%nsGvuDUv9TP)&an5%pgIoMMUh1 zr*yhDezQ-Mo>-+5YJ{;qZ?V*qcsdvC4&aDylPVV@5&dE&xK=s-!GiW7T-?i?6AEzs z%=93g?gytebn8&-GG+zE_na*^G&-R~z83zfeX2J# zmgZ$Z90#t<{P3rc>rLSw5v5&fUrl_4;_s@gaq_JG*`^?dPTN}0N2&Ge$)22rTx=>U zpAU+@BFZD#`ygFzK%9H^N;29!N*-SJtaKT|l(v#;_UtujEn!ToL^AdB1Vq=*IAAE9 z@SZ<&8lqVkn)Uq%Xmrp{|MIq6`yW5vo~L&g&fk5E)@U=UFixP+Up=c6jin8(9*1yI zH#-k@q^?X%Dli`?-wcash!xQgCAwWos%9Nm{N5T{H%WMZd{|K@P2{bK-wRxd)GmZx z*1j>C2)x(xt2OB%`|dsk!$hpda~|Vv5vHkxVZ?cqT6AP5_qp*~YS%KlLFVn--(MH5 zJ)KB;gaae*@&0-(Irq%}#!iI~`OQS!txEaC3SiX39}(fUuO8!S<$qq)&7z@d?$Eb~ zn6oqFmmY)usi-!3eASF@-GJBdp+to{1l4;BQYU(7LU=obp3B+mkULBjO1PR}M_(jb zOiL1vb;&@3iD*226_^b)J9Arwa707e0+2C;M6%PYGveXlbXwxtaeaw#!~qaaI*}zO zqkN1msM~*yE^tcj(Wk?Vvz>4*A_}!-Mf)aX6n}p3JJT(Oh z^W2elWQpqs^{hB=*8pMViQYv{4mW`LpGp=`Cc%hW-^>hVOP;2ge;vJZSA&9^3d>6=cC z9$=t^S%!yJ$xrncC#zS0qq99e z)AMn&jGR!@4+RKew8rP?2QYxYVySe|861q6bXd|6plbs*V`zppDB1>vgK7(TrXQ^* zFQ`B{v&6-rbccZuk}!RF#!PRhE}3`~eYN}^7x-?NN)1h1dTyTX9ooeN<~J>F3~{kuAJgaG+duUUE*_Z`2wHqsP&?*M*J79J8=|3Zd4 zX5sazGhI1$6-k9*U?Tn^25aYisZ7W2n-!Dlw|9!lXlV$nLw~&>2XYfh*QW+#Tk9k~ zSZ4swLs^2Q!E&qj6J|it{*ay;B+I!LP}Sc~#NUDOldV9<5C<_P zF4R?jsw;vOR7VCtNZo5jG|BocvY!`Wq^TjJT?zs{1~CWwnsBF zirwt%sa>xN4Jo2^NhNkZ6qV*<(r?uYzmZJS!8Y3z}(Jl7`{?Lb1T6 zhYCTY$t~gLq`lzP6w>xo@awk5`5=n3`W&eVp6qB)dPM`vO2(j9xhvMvFxB@Kl4SD6 z6EVxo+3)_mT?n%Up2ey9l3|M#rl-!lo}<4izola9pEuYIJf)lyd-qU@u?vI>aED;n zd{^nn+@8S~2;f}M;RSMJDvdBP{@+(0X5D7vX=yZ+r_#D!u*Hr*@L6b55zU)utRrYs zf>%)GNm-W&Av1)f!iSwXAsB1eqeeZHs3!H9;V$mDUT9ZNc_D)FhMD=WxrU1LmtmGC z4_}ng*0riN_~*fS|A!`d_cJV^Qnd?%p~}w5p$l8O~{@4lENV<7T9#-O`GlAS3ELLvxXsI*s$!} zM;e${o`<9c(vGpa$~UphPGL#eFIcLgUshqrGYN>Z|H!@NAkGWzxIfZfwURM(){#XU zl%hs6jD77vM$_;|cAvv4IDouxhQ+!o45NM b14+Obm9)kYBUQPdz>cDkj#&_H2N9yD*I*n<|?=5DO`9s)( zASTu1+q-JNWWYWg5RYcwG5Po0E*+=$-(S4p9TyaolM1#c9BKkRa1@9pOhq8kGWw*8 zjQqX8Xpi?RBK9zqlh&T{7ZHvaZqpur8Qbom^2i!@fT-MubJ5-^N0Nmby)Oa-vce=u zJ)qf#?@f<;-FW(1#27vp^Y#Y%xl?En;Bn{*V_DiDLHMpYBf4Rpb#qk&2jMZ&kIVpseKbVJnv5_EEYivXKXG zX~Qv43-Q556eQpO{kMUUntQ{`9wWdOu&WR0M;}sq#-YJt??kH{lUkw$RIeR+Y}S^G zH30Pa-pC@VSMqf1%sqLz4wxrJV-;!S)H+kuz&?X`aG-rLb~pv;nDC4Hc%r1+B^oVn6`%WetK)C{i8^_uIY1c=cnhF zfT7DrBdkm16!R@ji*|}%Hmtw=#GQEnN`Q7Wp9aUi*i(CG=tVg?dav7kj(1&F@1Wf& zQ7S$31_cmVn~>d3C-O@ZK4hia7P77Xu>9k485gm9eCuOk+Shmr#;SWOUjhBlNum&H zM)-dIJBn3mN)ghzmGTcs9~|>>lR%r^h#VN zhNa)&u88d*D_cEF|J6@5n>MAeqacH24N}87Yv*xpvC;|m(kdg2D2eP#r^rnKwyhvG z!h@uP|EFDye+`wkB(6JL7yF~v~$yb zr+}@dl-|}Xc(f#P`=;+UzQIe_xb*vEzTMvs@YS9B=-MaCG~8Jtin+3X#CKaGcSR?O z8eOvdH+SpD*I!cZ3B=Tp^}Lckg0zA2&Hy+Qyw=3il3y71X{=M=Wd90FNU`1+~XY3X}4Y&i;{25rX=F znE3q>&-;Nu&Dy=5BTJm{4Vk= z+Yluk{Q9^op!V_OzLJ_S>SiId-I^NS|9I+>jj&?EG??-+YwW$Zi|4`NKa3$-sn4dw ziZ2x7hr5?$n~;AlDM<@Me`f*&xDR;NBkReU9o{{gQWpOE#lD!KeE*fvuh+_dHAG1c zBmXYu#xy?Ln?<8~a0n-jtG_>Ef3KCj9u{WEUfC>uLUPZjQA_!%i2b{3>Ydd$Y0ti1 zt&3bHwckhG-}T7+{lTH7y19`0&*O9dGa zkuOa4zmBsXjn4@ZMhw#&tzY)BE6EW;$PT41T87xey1LB!>A>%M3g3;fJCz!IDTn_v;@H1)?@sRmj|W0`V06$5PM8#%s??hD&WRXt72NS^mUQMEV(sOYyY1bUw2>I zk+f}ID*UuIbNJa;N^5$HUrfHRslt?zXHyo_0SwmvLK_y1j=) z*sW>&r$J>B!`VQLXsnXm&%XV~3+}j6_Qx82&{L|*OFuY@`d@&G_!>~j-~m+@p%q~g zF%pSaA%ZB$L2z1-kOWB145X<5MzN4;V{{^U6{$obuW)k>Ei->n3N-HqQp_r76n3UC-)C`!sY?*u_nYGlI4fL4^H`iPHUXY%C!(+d zo0v44j4YcPK9Xh5X5!3t)9adAUGpkDtRlaLRh+!+7;~IH?s0h z=f!g=r(iy(NIqvTKDS^#pJKk?3;`1}0k>!Y?{ER1ctNDBppcND4E{%*3JL~Bsac`S z?+6KK3R$=b>)Q!?MPJh?4h|8g01pS9sl|#Az6HwU>R)0%p zVNq0?->KlOk)zZ2R;<%nH~9~sy3wjN@R)0BFk4QN(uiL!UX^sH^<_Lyz3<9r;*f0?k`M;1$i{1Z>R^=xyb zNc@ADXt1M;Y7O*Tphmc;rzN0bC#Ry^tfKVc&5=@rH;D8)z#^AGM6=}+BfZ?P*OKXu zRp`M+puB7K%ag5%p@+unFAXYey9ycn z?D^O!bRrTF7`uS^y(3+g_%SVZIHv7ywQd~kCl5|5y4m>EX#OvSYql6wRr?h61!QU1 z%28sDzgFUTCE9hy@pHPFh35>aKt@bGYSc;%;jG4h1hG4NwItASS6lbowWz*R`=CQ~ z&Nh?P7gH$7_-QMd`-RocRvGnba5rVKIeH}cj$*JKjk<*FMpao?9}_*7m4CFA@;lY9 zG@BaXTME)or$0yFIS9LeYtKUj>qvU}Ev-aOD zHhbZr7{mv@>E_R1^|Y|cK@l?OWD+TSt!uUo@K{=nlowO}1^Eh4=fUifh#jFMqx+Ue z%XIzrR(Ep=Hz^J5)KSswl*&g|atz<`Z;1mM|s0@*06jX5F>Moclu{M*?^U zL=e_Lv5!0ka&phlJ7t2xd%s+Xq;kWNG)@D=__A%U)rrdb2r;#^8RrqBN{{1E-Rc>L zB|KM85Uj^C^*1wLZak4jsxwpKRuh#(e)@x>q7z6ZXBta4w4>GXlDkk-svs^z%AG%K zk(Jt#8|ja&mmL$T?)^lL8lwnuR@c-4Qt#+uU4p)LluOKj`5qMw11cQ*Y4Wo~EYD*y z^d{4VvTBeIgF#u7qIm)<1hUV)DoWkd;P7j2Wp|aV-dVk~ zdS~@6di3Z$qW7|TZ$U(KiQY>DK~@Wr5Q6A}Bw9p>h?2;@@;}dW<~?W5`S`v*+{4Z; zGiG+U@9Vy<9~A_vLrczar$l8`3|q0h!uW}1TzQ!*ExyVO-~Y;;iOy@m*B<*K?0%HZ z$QW2}abOHF2b`N{qx})Bg4FZ*kp4&kp6EJZiWyHGu1Ri3?*_p6|BAEM7sCe&U@^J(=eJ0l& z8#pH*q3u0r)21u=wahT1-o8Dc=X+<|-#n09n|{2-#B5;x2t)uNhe{HBAETqpFU?6$ z1S?86ZNtXhqr15bnachKrWzw)NQfx|boXIWz{I)&$Uqe}7elITgE1SX9A0Cf8Imsjy+WsT>_ z1luLMOEn2+uQ{vB?+CZm@wjbErqNz~-U-)uZbQkO3vsvLmM_vBYY^f}LRq>&jSBlX zasqdGi;KoWGkq=d)w^)0eEL)Y*_*VEN4x zb9ky6?U09Z(p3V54kc(SQa}ASY!1~QZ|xPYe!-^?g?~A>LWrt zQ201bv3B1Qntc2BAGlh~M=pQ{e)7hugXyGbg;!mke+`LWBv`6Mwd&{I&NZiE^uB%- z--PJMJr_{DmgjIVhxq}L6Jm^aMZ)5gJFAImKR5<+>JZKfow#A0oHQ*|8HsB^dt}j# zf%5XovEAp8J#uh9JMy_dTre1FAre|c7zY*)0tG3Wq0x^;;v3FowQ}wWNn>0wGDMO{ zw4rn7iEi+jEM;x9oV&aYq2hV0rCN8e;T@)aYbWNw*-MB%q-8hp`97_Dj=$0T<}F=NETJ9h`LB-KBX2`iwbgf`(Jsj8+V zBOyeuPMp#;SUGV711MCZeVWZEA%|!R!+DbDF}xtiOw*pAi&lM(n+@jzH=(6YoKfA3 z1D z6E^AY)n-h`LmgZVd56x;aLrlJOq)5E`Z1bYI!cxV;8i-!(yf$>K%vws%*ApnIa0IC zfk~6I!87=3N-8$sU=G9E=U#d^5wU&c>TQ5h0RuFYlNlM^%gXpZkirz5ug1%{Ce5hS zqbP`^%ohg^R#@DrCVFZwV!V&xK?2{i*=j#j>O;am1{;#js6snZo#0xM$DleG^WB+; zwV$cAN8JLn3q3HwcP)WBex_|wDlyuHh5+NBTFR;%U~-Xis@sXZrfhnm*q_(BYBL+{0E|W!mMz;KLCc-Bz`|IfOgf7D zGQt~0u7eM-w7ebvzsFhN)$5XBt2M~8BA2xn^&#(qN5)rDCWJ2Rd5D2-SN4|>x0TaPd zN9UA(v8cn>d-e|TzLZg-5D|?+*5&p+QPHUvwg3uyvMfovl8e;1Ue(_-x?QF75Hmyw za)j(ik@@!#Qy&mE8cMVx8ect(I0BLBu7DbKY6coKs6OlU&N2^MX-~as5H-{rr&qT% zWPZ~ZcPmze8_^sB%$So^$oY9BI0 z`i0nwu_YpU;8!_%dlTVwZm6!=PUIs z9POKuMBSnFbQmIJd+FXm8~^L}_cB3?bOf(|Aq8=S_Z&J*VmlsL*lprxJ4hW`v&iai z&a}n76od#6Qf~;5v5lleO5fRXl)U7H2z)oqJbwJ@7!_^Hc;3YfAyC3{Be&EZZnoV; zA|Ba4;|qj209u#nLuG$I%W;A_epL>u;~){Kbm}7ri3MblwcpcK%5RHuYlND}wY|@O z?)lU2mj?r?g1}R*O_ryp_5wt!>Q7SKBZQQc8t)NEh9vNkx3l#ITN^%1SKZdcerM%! zdfelB-Yeae<7wzOuG&ZXqNnaF2ERZ^^S&?AmpCw;rh?{$z<7s|$BXL5?j#kPelNum zHlkoG(r&ZQ7QztsvI^v(>Ty}skMfU#3>bNV>|;QiF@wZ0-HZ^$ZE0$oG4rN+M`9@;_CX5LS=JCy=!;5` z8+SGG^3qd#?W=ZalI4bl2ic5|=8cC7RJ9n>iS8K1rSe=x=t3B=#uhfDujS5|BN+8j6Jo{tm*H7HN381eEsCl>xKt1 zXwRr};)%ijhcj*dtT(B>{C40ug*|ncx8#(7 zFITeD)U>yhBKg!>2G?!i^ynX#nG&cQmT*FEe9uO+eI=*wSoqNUjVJQmkCJzvL*9KS z=DsSK?p%8JS8t4#amIA`SZtrhU7g(oWdP92-U!QH~aUCDzgHaghKZOMeys>Vo{+aQ!`S{d=kxsawI(H(mADT zZUu$;XybVeTh7D&dD+r=)8TpkZ}YcF7LEiK2HZfV_ZB2o7ATt+e(b8hdb?n!?`$^2 zW$|rRP~k&|gLJ4j((U?#X!8ejyu2&PfHhUnj;$nDZ`Q+7=%dnQvP6pfZyz$&mxmB5&aBH% zY>_XAU9(6^>X=q;V}eMQCF6|Xh5C!__w@adFV7a1?idQSHotliWzZE>RyxD=Tw!h0 zcFp#La&SQL%yBhwX1cmLPVDPi(wS}xaIGI-v#v9;zL>dQOSsX(v$0sZzQeREd9Y60 zv0=!mM<7nz_k`y67&%Gq?$P1fbV&1(SW&DySy_}9`cr5iK# zo3cI^7L z=E?Tobe+BH7vct#zkr{zcs}tDeo}Y%^zao5C-_;~UqmzOvt8w9-RaMUUp{A$e0fKr ztdk{Ux?$$iwvzLd3PXlDDE+d-7q_<0e!UZG?(_Mc;Eo@|q+v13Z?7JY=oRmco$OjW z7J=Qpkq>}C=@gUQT`+_kZX;?>Y&X4|f;ZU4+I>Wky0L@LOw^ zh=K2+0g{%l_wecTer+_xHC4?=(t@cCisv=t-;R#PnMLg=rA|-e3!d@DlWXk z7gYLT$&BOHv0j#~rt3f^N-%oqj3S2We)g1QFvl~iU-H>sRicg4c+O;>Q?S$XxV}5p zGZJs*U61>>^a zC$73W@8v6@A;Z{BfEeFz!7YWe`qdsK7EpWR_0sQ@?AYOte0rT4m z$j@$tpElXQH#b5k&x&0dWJ(P$zYPoTqg~4oNoxB6=g~rcIPX+Jb6|tOpO0hCZ(c@$ z$TXy2wx}`k7XRri{5zqoxM%a#)(PJ3?A)8<58>S9XOWAdhRZwmPYq?hi?9LFHAxZg zYAgAEtG?Wo4rX-bP#SK%^oA5r_-c1Kv)EVYX0QHMy}cdl!gc}XcfRO6$f z#^2oUH_v=rp3#GZTz;AqQ2W{ZPUGg8%70)*oA%}gKbw_)Qrst)93-i&+0d zRr9(U36El8B3uC~3r&Pcqk#f1VQMji*HW4+e!NP-xzz zq{dJ(5dEw1iHqMv_-^iJr6M7sqT>ALDgBG^-B2M(DghBHF-`LN#@uXS(femH7#sa-@7;v=>@1iB)tSWjnN)TDqbiv( z8Q3zJI54@|Fa>!313>?5CHntL@o@?;^GW;{`Vlf^7S~|5_hfcR_z(1n{s(L32E z$wx26c7w2lB-tE1|Et6IKe>;bIy*+5UBlv^q-1Q!Zez}&uFYX;&&e+HFS*Bgb2<1X zxp#wm!f$ZTzx^vlCT=!LZZR!x6JKsyFK+t~Zihr}&rELr2yXvm9zG!+F{yv($K8u3 zB$bzhiBJ5_fAV|(4S-nX1r!Ygw5;OoW|gKK6!L}_)SaX0@&HG`VBHPh4l`|ivWUHn*D9x^Th z?Xug!bmtf8px!z@b7kv@ZGUgBF$S^xh5R74fV)YZRF6`FVN+~X0pOtE3I2;&juhIyl(_lZ z$X7g{9K>y)i9CIQaSqHAjCpJK7!DFA1XY>O9cWh9Yd$~t<4~wYmd%(_p-0CSw2)!p zs!g5M?Bcta#ptJdRUen>+CxzNV2GS-O3>pi zhKN<#(AVnDZH^j2)-Kd>VrM@A15wD`l4C*E$?o(oD5t<-C*hx-xOMub?)Ozxna(eG zJ=4DdTAl;WSL2vmQewZWdTCu%v+h0?(cn8WXDnq|)!L>7BTL8}qi5HCHB?2wwh`P; z8Lv6>BV;^KvD;)%ec%li-T@x8y}1a;4jl$^pYx#{ zlCT@%G(2UIOuYVlP3QCo<=&0p`u6>P20Y=ZGU`R7+J``fhX<1CYg<7} zlb3ibCbC?I_AZ~Mum~SZic&X){RP;&&r+T4dxlvxhrd+U*iqr9KAPNc4lsHL6M3CnhO4h$@#l!xeh(4XQVX-LPIJJ&xov*F3O>`J>)0X39+$S zFt+|~<-weGTVouE`>~PI(F7OCeaiIKlF%Ht9-joNI%Ve0d^GBtkKBITD5`pULEMY4!NhgrLsMe>&X1d9tDj1Q}!rTY;C5k{-Gq4~`kk^;A5JAT~mEwc)z~^Co=d zRnC-8Q;CwEVgTxYb}a}*CPipfLwu}F2fB^56CZw&qK_!aOYl=Qw9HpX7;$6Yzf=DK zS`ouCRiiF0E5VX9lpn9PFJO5*vrQF<%IcbeW$Y*w33agzZEeTq;9`kkPl^=BQlX>A z>`U@-m}Y4l-|=GeQw^w%EGrD;m{;4+luf4IhBdqEZyd|kLU=`N$?I(2-JYe9)PaE^ z(6z)9rnqL(b_9do@#BDvSSpS^n4PK<#|N2Dh$yTrjNo^FleeQLYxpSfsAhbI2(^g7 zg$njPg804mNyo?EsuCRB3?GJY;0Jr0?j#gi$yTl4CBP@o+s5W9_~SD=$mFY=s7l82 z0T=CT9i`DNGLl1S5J(8{$x%6?3reg4YGob%lmL%?eMRkt#w7WZyPzz!$)7Z?^TWkO zj4PAkfH}QF(-~|EE`7}<5jw)|x;Vg`Uu>7qZ|ioe3cL5%+fHQ1v1(y7B<9f-FO5zU zv8u6#kaG=og<|H|I-}&@nX}J39XM5)-WES;$IxhDTu*v<0N!R)BdQND=1p(5)_ABX z^~OjH&L`e|xss&LE&1GG#aMYi(Vi4X)sSNO=)JZ|Y*Il=b9bmfX`ca*A(z}=$CeK6 zcr;B{dd8Di8Bed0^SsVqxBg!3^7sfFsf6{8=xvnmFgnH*Pf6OJ=;5&m@IVR?dPHaC zGWf>R5D!fqs(sH^-%pWu(|)cmtHm#s@mjyMf|5mUB$q_tW`czpvk(+7z-=FEw?^r6 zQZ4@Qz$-P|vZAVVv{nqMGV~m1e82BPr6}nHEzD^aFb3oCn>K0yG{@6Z`+#s2=MDl%A zmOzq@iI2*J3JX0p=srtAbJkXP$2^lMu(zr}QcM{UUck-12W<9yNyqb)D<_~DTPx*W zh&HJEK^L-}ANHK~$Tb)Eh>1#ia^)5me{Sq^e$f-^2$#9fNx?K-Z;pIM_p3z8FBQ|Z zQDOY=!~#Wr89l>N3m2bAL~4ZZ#+r@su?NJt7)Gp8Y*7f)Ql+fF$XspfIG;MLq|;b< z5^$15F|QH*rJ?KalD2A1BTw;z7HiJ!!-pY9^?`VnX#i0IO5A$orKM;03BYyYcC)RT zXGRTXgO^S%Mp`dshXxXRQ}#PfA!L2F>4B)A{yC<2rKt{LC80tAcf_4++u*kx?+D^( zk^yS)6pTKASlKYL0HX=^6QoOI#)yEq#5m~oCQ_k7dVe<19|cJ`cjJZ0 z>tVF1XJVOoIGF?Qa999uxx`C8ikEd)vra@njYNHG-5#AnA_$4NoK135dkcX z@&I*b!Y`c3EZg|aED|kp60Ix%Z)b?~d0>_VrV5gF?N$4OxabjwL4gw;QFPoB*+W~>$-Nu9*CN9ST8 zQMe~Rl6;TZo$mz%reTq!?rZvFNj~15W|0v4f)Zg$o0i`O4ZBF|%Cqq@4Vj(ssdA9a zKJf|)&1e>bb&RBUny^PCBk$HhHbmtoEHWSeuzXvW60v|dm5h7m4DNBtn3zy$d6>DP z1)L>7nHpw&gn_4xGh^+YcPwP+q|8_!xTGpe^UjDD#jVq$nv4YyF~-HW&-in@0p)z{jxU4E6COIea#w znF;OjBgcf%v)S<>gm!fxApX&VE-^<@)%$KIchL{&JnWNsDjYd#^CsOe;1hTxfZerS zq!N{Hyc`yql#iouSQ3Gc|HzNR#g^yN1<%51?bUi63%X1QyUASMp`-?)%;8I#gxMCnV-Rl$ys$uBh|@a1_l03&=1%@FaW ze%xlp!CO!XE*h`^-N7)x&E3BRir>G4*3c0TBMTOe@0MuG^&ATruPc( zVjpM1W$P9mcYbodgL2F}51rhhJQo8m_&>(dB@Xr`A3G4#VkCO2g}8Spryl{_eIFl> z!i$okr?h1hCE)}33P5#|$p@68Q7%zxQE3UTOr0+DV||<6OaHms0+Zv<<2fJLLgK$00`Y-d+IzafFE zDEFZZbknqQ>XDMdjA<8CMRHb`m9MJAkVw&^YC1J57~%nTAS@pylycBG13n3WCy9q= z38CzVDH)d+tM~vwh2yHynMY#2uJkfb1D(jk+Y*WrOen+s1+e94z6X5D)zha$?;LIX z4DZ``@(8Duta8<~)mbi3NZbqZw*)+8$7cI9#M_K;ydO4~ip?pTDf7Cb4SSs6xapg; z3y^XE#NiQ77A@*LXu%PfqKjRim;*5Ls>&KszXAh{h?s`85h-v|I3Q^})3^}h^>BJX z2}+6$RxZLyQ{7PC>g?2DRZX9#i=2SX9m_dW(ZSfOyu%we@(4Ibl?K#zb)^O}dNC1*bqk+S>2xV8}7K zt&SwQ7t5dt@%TTGxSA+(eeWe ztriRx7@OPf9b`=QqNU#6yK9e}_-k7+rb=eHU5Z`0W{~F3v&6@&fyvtgw`(F`C{pTHLTeq`86@O(#nv ziUE)X=RkLVQ(M_vZ=DVxCZ1io3?BTZ=5lR5N*8z|?Ip$k^7O^vqkxy+wr{WI*s6@Z zJhgraC=pN(R3p)0JDn%nYaHAy##x-w_nr4!oDh;{^vviCQ9WT_Q+`2LGRUzu#Jna{ zp7JD-Xo%zO5VyAoEue?3sgJY2P`E@Ob2CPdCp^{}D_$~q9X8@SuNJ4<1I=v=m>I_0 zI7k^Uf3VwHh0`k@_MUo;=$D8GJO^$aG@cWJ@^D=Ck%ORsu?uUWUGkQ9zZC7{379Eg zWoy5R*#-t2v*vyRny=A%5x>$Fc;X8fZy5&^eq zAG5wI8g-#K)BpCBap^)6bK$veW(v#_rGE%p{=DXKnc+y8K@QCvB)kFNvqTCq z{gt1kWb)!FnXONd|K2%6Lh|0i7PqH?wpz`9H zvf7aM>&2=W<=UG}{^=;nv2{w1)cz5DO6;BWQKof0zqK&Tx*6UX{ETGjm-TXf^ZKeF z(ZkL49{p8AuMMRlOk2Y0waLuUR6*(b+NteF_x6p$(vMeBM#oGauk}CTqx>m+hn7zo z&NC%XNfe<5D-)2(G>Xk13JtgHD6*7=UFlbDJSEwPEm6Pwp{XX)*64Rp+fDFo@ssd5 zcFs2y;*5ivq%GUxMzBpQw$D7DL=8TPJEZH^J&{@6`h2}5AKh%TC%KTezGV9u?Z#Ye zyJgt2sy9vUzxlcLdj0kFn#o`CVzkcfmQR%fUxdhrU;2kXAl`A$`r=4BcV7?L=%Mkj zR76E_mwIsLwSqr$%V(pOo#4N#Yaw4ET6P!KcfqkSUB_Q|@MU`!&0i9-#>HnEHu85K zkorWGS;!y}nG*XR8+-oIZAAvV6@$hlS>(%S`*F;Bmy3IHuv`Q3e#_{CIK_ken=n%v zBO_1F^s=vMg9QnLkRa=?wR>S%LM#3)`}sb*gNlwPG}u>z`6vDZab)66}J??VsARRQ$fP z^X(hN&GqQyP$ZJ=mf@=gLe3a7wUQsVW2=|8x&)LcH1MyX*h;}}`ct$6GhaVRQ_i|H z3x$&Z4(#GoAlB7(K~{~0!XdB{=MK=ux6V$h-~IiQLIlWxg!E%jB1jX{kK`1-ClT|u zKNim@DwFa|B8_BkPyv~!p|NFAzn2o(Tl)|{Gq#+WLBG2_r@7od>~YkE=d^Ddb_%Ak zx4Oy4)n$&R67h-@DB{iN^hK4K^p|>mC?ZDm)m+OvzM5JO(qdB2^W_?%SmVEL-^; zDu0=`D6Vvrs<#J9-Wk%i*H)*0ZTb$OpN;nt&v|T70GYlli7St!kBGLr=*qlKKmpW) ze8S{pR3cKaJFj0g;Gs0M(Ev1DHFzS-jt86i(HR3tt^+ih76*r=2-v|7Mt zzvQ|$`;LiU4g)<=pp8nPr>|9!GsXGZUyuVTY}J9dR)WXR;7m?@H~!91M;kG51?W3a z%S(9kvITsfE|AU7ZbT$55)Kv;0p1(@ zM4})^$__(%B$3_qCv)>A^9UvL{~x71;(r8+p6X@~it;9t_fJIPrc_X))cy~9`nUc> z@gE&Yib_C=N=S`LOoGb9ips|5{~E|s6rjeKQyZ&MyNA$_Qqxir(ca8JnfcJ#xYODO z)4F)l-p`V zLmAkm7)0(cSX(fP@iFSyG8!2%QFAiUi!;fpGs(*`Dc^u6dnOYnCZ8MXMEf7-h>n?o z>%YL$jcp{R&aABUpY(kl8bug_Qa~k`WIJKi@yzWaGi&AAzDFLfM3%9KHT6 zJ~>9AZU~f5ILapx6_|tyPh%zGU}d9ZgJIYx>Ho_)y5UV|j{nL)v zG1}}}X8(4d+%h@XWjW+!Ih4#fj7>P~k~r)wI5k!N5h&LLF8A;o0`(vE#KO%^@vn|2 zpujDm!fpNEqffr!+yTivg8V$~aD|#sbEU0yZ{+ zie`e^)`Is-gcwDX0;>}cl@9D0{blY?~qBD1(%k_FTqUeopiso=X{_1Cc|K%z9 zefM?L=S)gITkEc4wrf&-y^9ly+GxUTJidsrkcF$q-FP#$9!I&sSWa7@YVKUYy_L{i zv;*VkaGUF>Ln#9 zO;AQ4nI?$YI2AoM1*6}hRd3nD%pcZ9!``zgd&T9r#voHG$EfID<3sd4$Rs_#HiIlv zD({%j2Qh~7FrUXh0EZPpi7XVl?JTpQydzvMA4wnD6;!zsP;&q~7+Tgu5gfOuCzQv@ z2u$PNJ}mf9*Mi6=?Ru>Z`FsU2di$9Aqqg@#2xpt&5%dk6z}r5R=a6&{SEk14Uo4?5 zl8=m?Up#|yQMsJ3wujTj=D+8!qy%oOnv-g!@7@Z|b_QPnHu{l9B{c zP$%Ww_eVZta58bA?m}%70jwK*g+I%PFqarLR9A}N47#kx;$mOl^6wnf_-C%`r)*u@ z67o3#G5!O%#46%(U1ZL|e2=dr_0cF%wlR%bcxK5P-0#{XTR-`A-N%6KQGRNA}|Uu}o!2W7H@zCMr? zY20k3x;xACXN@BEo!~C3{Lsg9jtcTc;1r74o=ll72RN-gW5hjyfpi71Z31$_Txa67 zIF5(rm|BVA>Wq#bjd$OIIJyhYXC?wLgrm?#zo!>!H2C5CkxmIV()^sqWE%uTN;rE! zK7ZAdBsK`p21kf9WTtpNlFFz(>s@}D4d42}fhF-qm9THqu=b2J7!JkV*L{UQHf)e^ z%<`ADw-l$R5ujQ+;T1!vtSB~M;rZkvc%|Z66=ij5PRJv`aS1}+)n&q}@Dm01fKMN&(<-a4_-W#_BF$67BT=`-Hcx@)20#TnyrNDUujzCP=4 zD%l3tAt1%*fcC^Hr~r2OEvu*w(_Pe85F{l|y;PKv>TQOO$qNEOQ8DnX4WFlPbt;HJ zlbvm6NgBLuxDETq+C-*~@YJ>~<%lQ7w};a}+FQJ;x#5Y%sakcyr|ZJL_46hDRY*M^ z+lmXY4kB(0ZI<}@cYipxob-sEX%CZco)*_OtoCRW4MiCs3F_3HvK;D$>DI64Agmmq z%BG1I5Zs+)i_gV8z8azzk9amHgGH{Nu$(gfUP^kJff!0j3fbsRq!?}JNKcKEW8l`E z5p`}GMDnpkFGGp2jXpK{dQd%F7XWYkgnB%q8K;4qs$o;L(oIRE3G^x!t6-ChW`c<) zb<6O-`aq`KR>I*#m`wXa{JAOQDZ$|bZ*7GHDyGABo>r_L%h=yi9^k{ z;S*cbsTD4E($3m0V-~Nzd#Wg%s4{iK9Vv|L9n6@F5TMCIxSIk^)3411cDYW=KcDI1 z9ZV72IPsUPJwJ${9m2w=T6kAjY@9-C@jI^252ZU!o!@KrT@ecwNL|bX@r3>D*qS8O zPU|vE_a`jF&mt8m_XB|na|nd~iYRIC3weaodZ>bxinbT7hNMbJ-AL>u;G%0XnvXF7 zfF18G5#chm?GRxUsvuy65C~oB@JeGkyM!Kj+)SL?yd`HtWbIu_4=CvD)&M%DaVMnVgy1l+f<*wj@EdhwABlV&k=%?Ui z3HkvI!O%VG4c8I)!M*#;#HW$BCbmd65;snZ9&bLsN-!aNPn5dVy4;4*3Qd6d`7o_$ z_hyx8eLqhj;4z;`z_%!m`xQt^y~TWb=PvkH2z?Tt;V{krlFB&O<(^W{Rs>g%+jPBK z+~b(zGGP|k6EwMMVkdxv*--YRYBimWCz61vE@9qJvzKQr z447fXQYdh^&J+nvSUw@>vHqsv6nm4KQ~vg9M(V=}jl<9MkUW>Cap#I6%IAe;wu+-#CbXjyTd@OzJ$@P|CZ#)&e;MPee| zyGnnRm!UQ=QoNdFNg_4n8k_27biHUmdQuEah{!}fMn@C;K5w5*$u;vzPW|HirQ-Ev zxBFsnv?K;H?i*1}t}%U#`kO2_I|`>UHGS!DU#mJsKaj@a9GZ)?B}tLB(YP}Kl~Pr6 z%bn$ZtRVPO*f$nIq!kk%) zQ7KpWJ2d0R0ZB`WxoDUqCsuHbpm$sE>pavNonm`Igtqs|gDFA^JYr9wyj`hOj*eCs zzAOtdL5s8~ZUV3O@&+8p(PI}=Rsu3KSayP*ZziY<7U;C(++|PPH<4baHbhPypEj>pWwJGrlx5R?E3jk;9!{cJjII3EDbx2z(AM``M8 z>bYzZDQW$%+05p3{aH`;5KA`-VRX80f}B_nc*Jjhhb;{h}#tO zhm?@tS~P0!X~uH0EyI*j)xdMZA>ei=tpaMXR}%ER#3dNQo-I#0U}x zEmY)62%tj*=9z|REAY)zq`3wCn!eZ0H zKhh9a6r?CMkIRK{J{LqAY!t3iRK00gf2nMG4ASS0e3C%@gpOFJ7ut%$K9dQMYy))6 zI4`^^R>C~~lR`BT=Ep-OYjI)i%<2~3%ROUUNOMwR|D5oT69>faaSQ$@C7f3X>sMBc zCS08?Wq}hu!ys1KQMd{Xjxhs969V5MZVC_A!}>zg6Q}P9d~#f=XJO^LsQ{9Zo3}(T zw=#h!rI8m#@fl8~dP!mEoWoYVZBV`T)0h5kx&V~a=@WgY;oB4#ULzf#|* zB)WG-*@6tY2&)WTuDY85!6H(gFQyq@=f)JE@-X&OALxrBpj8 zhXdgac~2$VBzO;=wmOm<@l_Kl!=*zg#=(dHCxRQKM~kbrZ76CQif+E%Hd)fN}Zsq+ei z2a|!MmFaS=YATNJJ!~kBC-WeYGaBz*;)bV^cPn0zq(-4Tv&@|Wj8@3fBU*(d%5u|&{qjz9g+M|302traa_S6VJQL8^~vnigXOlnukS z>vN8&ex*IE*pwin3fxWOE=yy#k!-t_3flU~p#oRI_tk>Fwtak}@);}@o!|EJb=z%h zdz71v>IYyJfFj4L-O`Y#iKoNl4q5avgO)F(d$WlQ9}A)uYxO(u{&UcQ;jyYCx5?(# z6YztYS9Fl~Aryai=x>Idax-e88>JWsO}*OR^mNsYkloVcl#H+nHm|cl@;NtTSr926 zrwV~*;~}p!qygP#y3brz6|0c!%YEIXxz0YnyZwk1TQDlZb7aamI)>cmp(@=Gy7B{U zTwy?hepgGfU)_>(ZOOltCozPD+&#O{ULa9kUb<3%rlp-6RD-COX0`YHv{!jZ!wf@L zIZXJ8wYO$f@o~`OVKDs3i;nT(hIXRpSPUc$N7r54(ZZl0*9LpR|3bs;#dF-dRl=^49)NgX?1wnO*MA#^FoqgibpVxbm!W~V0jc;F9I=?AC zBtW@Y_N%<1-hFdU^QN=^b&AK^*>kJWrir(IIyY6`z!;~d4&U}Owtn!ITq>DD^i5T8 zAzgCbZV*pra7>?3y#C@nO(6=}YkJcZIr--8^v>2ancg&u^1Doxc%al2Q{}tg0?z48 z)0f0E&cpA(Oz#K=cwi*2?Ul!fu3t^L_>$clRo^nE(vLj;ZAE7rPD3)wlqut*Hp^=J z>XvOir{H^v()Xe4Ch*bsmYuUY#B(q4{j=h>a|D5N<9{d&E9ROl$ViwJ<&CBk@7ZIR zBzC$K)okZ0{K%9`aY{q;8c|^V?PoOY^Tte8pdrFeLXqR*1^s~q+f0q6!a4iqg+<%~ z6~TgQ)Q8l{yPksBoYPsIOc5W22erv1@==zN-`qn4txw4j;p>YIz_6HRg9yv~_P)i$ zsDWf#u2hAkOeX4VCVD=9(*)ba0uuT{+r=WLj^ZiW4?mV4Gp*#fphk5U8>W_w?yVTi z%C&8pH4UtEeOqZIfk4qji?bx7srT^k}<8&#mtM*-m<9z*lj zCI%GW2vS67Lt>E9;J(#9{lx`*vuZCd*5md1=j+*zQ7!IN(g5sj?>Fna*XG_d0^_rh zIUTd@ zT5V7Wk)gYcXbd*!n8~7!aZCnFKeiWHj*tOJ=i|U_ulAH*-bj~vQ2`+;(L`j(a;F%n zu7&=G-hxjGeV;gwUMt#_XQGx=Td1`{K5LbMBaods(bNw|2)!>qr&j8f=zejIm9_#* zSqM>aICj}?FgY>qNL0dz40gm@!jiB%MnEv**v@TMA2;IN=cR6oXviJiU0pUy&@A|} zaW~#^_eE+ER*}LAL>_~;+at?$mYZ~}!wsbUZSt#dcmKkY#IXOa4{91ul$)}DzZ&eR z&g6!JmHj0TIAf9;^R6!2FJAbVZ6DpZ(fa72-XnBw`!uQM{wcIv_D?qgY-?}U~6nFb^FZ@=GNksRVi7N7|Z zS&zY6W>NNR#&5nKS6LV>z+IY;e{|S7=d&j@AFD#jU-Fs!sXwmWNKWszS@k?2`fiB9 zFnvh;;a!=h|DG3!|Neul34-tJ5feThQ*;%-yZx6`O5ygmaqTFE>L3LcrT4w=$`UpT z*`_OGKm9(y_0T^J?;;P%;68WGVp0hw&|eH&VNIP)>IHBV2Hd&ufch@*R!T-@(xJyo z1nY*gz30RGF+?-SuHi(j-z}$&mYd4LUnzPEZWd#^dio(hm33(2%#Iu$OQ*1L`CZR5!|J1~Fmn3%4*%i*!`pjBHPr^{)=6k- zU}zygfDn2Qy(3+^q4z2sM2aE;VnVOdi!=dg0wP@y3%!GM>CHwH0TDq_4t)FDd+dGw zb1u(6MlO;uvR2l0<~yHxc%#Ej>e|qcy$zY7PBqgX!he`j9;f&g&9$wzxO$Vy%>EX{ z-S=OHPXns3Y-EJ!pP7VWsiG#22Lta1YWV1KkoGQU;l`~>*~s&m(=iV$ornwcIlUkT zJirTnMt=zUM*hJLVc7UbvEaDx-p?UZG-w)>LjBv30pd~y7Z3?eeD{sc8Aw&+DtP73 zhpRxPW}~xF*V%+aRX|L0sYlj+@-4u@cmKV%a#A8<*CV-fB;v$_EpYIWmtn$(&03P& zjHA5=nKXNUxb}sCzN7~}kb{SZ%6{Ldd0`>Zhi=znaOp$Hw_*~QhzQ?0)xA9}YIEec z#MwH;HQ8Y07B$Uv%^8iv6?-6W2PF50^7Pf4Wu4!80Kn7~s{qpF8s)@As^fIEfEvs5 zSQ1J}*v_7kn<~KGHqp!>9mD}X_~|ShodULraz%)c@}3uE*&s})O`&}s=LW-oC;}sq zL~fYtChuG4a}mP)0hi3fJ-w{q>10>lRmTh0)F2XUPjU& z4af`ZkmE!N2@`EiE8O`qMxYry5yS zD5fwr75f7oChr=Kz*UE>s;f|5TpM%sbJW=KWF4sG8a7-_v(LeI*J}IceVr9Dd?_JQ z#B_UUS@{5>kVEsg`}OuT%SSw!^m!vdE>rMDxYD9t1@7=6nB7(JO7hl{KE@&tokOD+ z!m{Hsy1>3-YqQU_!m{(}W+Mz^kABd& z!TK+jA_4rD4@CgRfS_nnG#x1yFB$S8;3RyBrL+{l*R8IzIm4W^_D z=iq{KQo*?;;QZeI2At@Sm-QxQ?#qCaAP<#<*hRpJ+Qy&S#qGj}qV^4;p<(zZ-Sm$V zg+(O6$P|2=Sy7YumOmQKiKgd5 z8ycZ)ELgCz|L9TXEb3YpZWJpG<3CE&e}hwknyliMtdbY$CR0{pCsx<6f8Z2>)hC>d z@*h4W$j2rm$tEt#X6<0;-b55IauCGI2`XK`j5djx3u&7QD=P>aCd;y=<&7g(xbZ;5z7 ziB7=iW;F#jdyQ9Kq?;~%D9gyO$zLib5R*lXmr$~GwF zIxu;B{v(wOAF5s2wTP7Ccl>N;oL~408^4XCqYHG__!V0j+#UUGXRh%vrBn&bJ?7n>dYk!a^wl_#&?{P|7uz|0}vC7eniIZ-T*QTbKrkSF-1bacQ@ zeKduDy|UIy-80v_HaKFvSYf`8(KSI28?Hc3lX#Q=TcnrA{^|j2-D3q%*DJR`KmvhyW zN6!$>kuVe;-XgJ{Uz}3C&z&i1QfpmKm)ejFnQIfSBlYKZYR_|_p}u1fwjuu8XH zxPZqweK`Qs^zw_R$UsmRS*)FH@osxb?La!y6qZ<=UCVS2EM8gZx7c9rOIk}8C8_-U zjo+t)L24R|V?UaK7y7NoUvAR&A+**_hz}7{nWHRAkk@il+;yCm{(oC(Z-h_o@6xuTaPilfm!hja-Zg zPm8d_{dGp99B^Dy(_M%f3vUFRX#@)Yu}DnX4Cm91?H`({Nj>(yZIK|Gp= zl{Hvlsl;JFH(ZMmL*>+1{~t8x;rYEWE};cA`Zg42IlgfA$qy-s*}}$ECeF%9W8}mbviW6^1Es|%KnNsqK5kl~gEVyF zxz2hk*31A3<^rk~WpQJ_sccW?YVq>C!;vm1p+NY2b`8MV#mR7^I-v#C z)slkp^Fw;EuDBCHz`D&iVU0NT2hVpFgP=))hsDA{tE(z{v_}%om_l; z!%j2pqg1ps(RPwk{ZRk`b)xlFLD`Y98P{!okq>&O5R!kIB+;ns`MY}>t;ZqjY;vW$c`BG6t>&S%ilO`Tb6FxGw(s09_qfFw( zAg+Q7qlt)^sfAS$s=CrqfnqW@H(K-#@Vkw9XIfRK=nq*>5E-dX-E67zy2e=jh{d24 zL{6_*-6qx3_OUGSWk7&&f>3c9t!g#q4ABHrM~N%VSbaRF_GY$GF7sAsqtLY>OE-D?)nTYEn#?1E zae>Z9jemo}i`VZ3IiwfXVb-v~_w%uk3`pVmFoGpVnerWNtW*~T$=+TxRU=`?wu*>$ zmhp!!uEpJ>5X+`)y~7xrE8;G5h}{B;OX)d8Bf?5nZ+dG>h6djvDt-`z!D&J*=?6}k zitP{U`>SGg35TsO9nv(K7$LEGcBdu`qkS)$TVV)0io22c3t^LGj}rXmW#YzCIE2)Y z;Qa;BWeY!k!MG2Kq;2QY0q;k4AGDgr?voPANJ{NxP`8;D8KerfvD*lI>$P^$j26x#(gkZ_ilH@>n zoDw47&S<7QKew;=4&dNP0KzvyI~nw89L;b2J9N%{*SiPUrTobbh9z;==$sr8XNut+ z{cP}?JEl8Pm3-t5;Y!+$x~RDmS^l_VjiCP z#>$72z3kw*HXnO1rz^-n|=gDch10{HcedJIz{7q+TNcUq=)#- zN8GOp6%Yuv++bt#Tzvk9t9wj7PT6)5#N73!7=}QLK8Lpc;T&K zaR2$uj9%}sBiL?pP%@Ilr}O@sFV?X?AKWtLN2Y+U8Z&(PLQ#r`giwccblj&JknxZt zv&RxYWcv>u@-pWTp(h}g&ERV)klHozqnLn_k}w=0yqw2S;6#cIOyR0bRL=ruqzFpJ z5@9kB&x{B;3p(T)eDN^C9>FhE^5E}A$ZUroRZQdn#kC*JOhG;T871V4{p4Qzd>zCn zUt@Q=4gkBG=0M5qMACw!Q(;UJIyb9f?dtQhxwyK>7arb&~hrlj1FS zKWoJ*WssZ$Wsbo<<6@LjSvMN?0b;Rk<`~$tOiJk*=)mH>s$cStAZsBR=k!P|9i$NH zy+qjUlO^*m2GPt4$QhXk*AaH*uD8(pR2(tl>B@@{E*f-|U6$fr&+A}6IjyJh6XWE=%$ z8rPHSJ$j&ePkdc9b0|F1EH14smZjR5B7K|zFYDlN@7iE0FJ~ja1RtpfBK_u|ra=dJ z{zN=)QP%wfiuizRi%7lzJc`Bx7j}wg;mXm>081jF=S_D>J$UC*U?WbxiKohGt^zV2 zVuk2I&vLR#WHEP;phu_5FE#D8Op!|L*-qn-Cvm(t@8te5hBK7eI?r(1{(SVnfztgn zZ{^T#TP<(?I|YM_j2?Zcv!hGLR`wO;d_hvs@Dc1y>&@XuND)9@352g5QgDMIu7M`P z<=l~2Fb*PZBlF!V(7p@gO`*6dPKlF7w$bt}#;I&Sx*c8=+?c95j6h=iKrxf~KN$&oqD&T*LbIUFsQhJDu3r#b+ z&1CtsstPe*RSSjPCSgUdJrZ8$EgULvkFDM{HsmY|QIN_L0@m3SC2CZM;I1hP!m}70^WnBk* zvjHQ_ieDv>d2z+?b(dH2mO!#=_Kk;@vXrUq#(|mN6H-j^(BpP!CPAT-xdk%+R-8mR zO56Aw?Co#eWU!z(aKClC62beFw~M)RtpfcalRb%_sXe;0v$`|k288zTMSiy@*1MS# zE-fT$OkxPtd(tJ4NG5b9C7fax0;n8PV=;52Qx5HpjMaInVP@8(wUD0npu1J|RnXgy z(8h3}d6S3y0Cmq~4=WbdS#LcxUC(&7lMGTAN{0 z`r&PI<|gmq=EULsa7_EiaMJGZkiSuMN|RenihE+%$SdQXL@cr-)5KH zq&yuv8X2ffe0Pcl{XR=1*?o8J{fUcANWkP*uoJXuR;>PH)-UP4H#L-<+ zs8BzX?Zm^73AWJ@_9Qm+pG5tRF~)n7Pi-dU*C%6mCwR~KrdVSpoIIuk-;cUfPT^Ij z5_hLEPKM3|rmMlzu$$A&lvArU)4clAa_iH&qtjYEGsm4%uHG{b&BkBM^F+}NXfnR2C^eiLgd)8wh`QST?q_#jxRBN7TCSl5U`F;1N zaYWKgr0rY~3=3#aJ)qZgw|%goG%cBzWNDFCniSJp8C{~z06|d%4-Y$)141nnQQg)vwEK_90HyZWPQm)ikN>-zpZM|10 zw&5Q#@@j@xC}y~d1Xf*$WIKy)h=++I#CZ2iGmQ#F z_Dl)oOkc!51V#ZhRGrvjK18pFUtjy6$A8U*|D#?#ncsS%W-Xma&1+rZN-1_H4M7A2 zj_JBVgB+1(MhM}BY%*7(W=@4QZ(gE^`$;&742T|HBUY{Mtu==P4%C*mbhd^L6 z@IC!6yq(ym;MY90UwD86|+rPhx zz4&`*58NxQ9gX|)hP5B|%4Mbl(97DtIAAj7+c;dS&kWuPBvB ztvp!yN=5|r9Hj3jjcf?p@!WBgciP#i)iO&V-?Pfydh?k92X|b4Ju9#$GfpP@aaXE+ z?Y(eNf7M>oxaqTgH_`C%!o8_@j%}9JA4-%Z zjhp%a%ZilmD(Bj>Uyf-T1`qSTzaTC9?EN!8#mGW--&qP!$sQ&j4y_yc)|34$e*S2+ z_i?iX;=|_J)|=~_rhC>t-^v-kGHn^?Jj5tp-S^Ot^gI-AU^(?5`?%f>r$QVL@6qSb zd^BrzjbD9NoCJPjN}_lDm*~obk=`tcJ;lZZYXL@NQedyq;CnhJ2^ME^@9i&#Zl@2> z#EmfLu?{CSt0P^D(|V|l#wwuhTy^rD(Kl*9F%(Bs&fS-@5mN6184vFBO>g@R{ob;3 zax8J={&1SIy3dRwnY~5R-B%x-ELQIVE%!X}3021303JVASYrDkn#>Q@p`2p<&Yd28 zUK=B6ANY>mAHnv*`7RWNS0(6sw|x5v);Y~RlO{acp;lEPYR`^#)~BX<(w-vDTAqTy}*ez7p{$;ovw#dDrQ3| zMwkOA{drMx1g}8Z&vhcNvCa28>`+@_i2t{n{89XgfjdpQoKS9t`e1s&K@VE@m3o$}|ER5VOp;z?B%%aPW>gyYvmV z*&P)K+wM-CyGzlh)l-8EF366I8bCZn=n?&Fc9CV!^L$N%L9qzq6P=ImUVF1S!W0I0LDR;Q} zxIWrD-sh}OIms_f9lOH-rkjoFN0mIxc%A<3b`jf8o2}a2boX}{?o0}C2h!)En_6)n ze>Ae%8VqXR+x(RHP4y#LS@~Jn*`^jBm>aLwu@)+^@0hVPNidjF#ecHVACR-$viZZE zu{0WEH~BjwgXBrd#e*6(zK^=f|6kl{=|6R&q5pNMuuQDNlB{A2V(-F*)iPg!X}sK%EucE=fu)ojQF9j zY>ZeL3#^>Rzqrc%Huj$#KMr9@4iOCwB~uPH9S(IOykTLaJuMC}m*|WnnQJVFT|= zmx=`~;zAU0NfHT&z*+m@oc(d$emHL;&O1reHd@^O_N7;)rzImJEhB@M3r>{x2vf!W zKd(6bcQkgvt=j$%I#qtjbPAr<&f_sC)_lf(M-!2v+GyuI)chYsCyfDKyro{?WL2{J(Mg(%3>jj<9=TSGQ=z}=zNKTOJD$u&%0}0c>o&??BglKSe8H{Uo}i{l z`D3djxcbT=S+=R`y7WjftTEX^+oev$=rjK{!lA+1-Ei?`nU#=lf6l>2yRlbo<_wOi zo!A6U`U9d@dRk>+Y*Df9(oEGk6@6dS_lu&Fd=2`O<}@woReh|QI@h=5tV5os0c@}Q zzP%)EWqZ&-XE7{T1^4gKDRJ&3VW7)d>x6tIqb}CicByo9qt+T{)h5!L7v1m9M6D4s za{|#s09GqDp0C8T1#4%~)Xu?#6N!=6f6J(+y zPEhZqBP_&`6}Ttv=dkd5bi=KfPxcF(%;d7PS)I*1x3s0GT^&Q>ebd9Ch(~?45)-I< zS{Ua_0?Ry- zlP?k-q7H8zEM*zQ0u3o3#{hS&rJ$aj)=Z@t_A4IfVg2S?N*_yT8Z&-?TtVYFX1gD` zx)In`2W54^LAtJz_M{0Tu;5$N6npeXsof7u_g~@E`A=E2YFhTv40%vCq(F85&OoR$ zUdBSR!MN3CUzH&$((_Y%v~!9oOjO2OJh;LlHhg$if5e`GKjTF;!-U`OjqtgzEpRog zGRj$7`r21U`U1Ma@12lr@2OfVM&o#1m!{S^)$>`t?q}Ru&jRf=^BROO>7kQ?coV;` zE9F-oRps%=q?{|0L#0|9j@Rz7`wK!4TM346IljAmtkwG--yE-&KDDM8FazoGMBY_O z7m&?FFhcoJs%E7gpI?w#jje%x;R~;1O-b?=#;bq!V0Q*%G?ygtru7u(DUBo({Xe%V zADELj_P|7}H~mILyJ+gH;t+h0=s&N%FTFpSW?m`VI#wCHvR*XEa6JF#+wnrAA*^Iz zQmW)*`?j&c&X;#ef9FiCDGoCL9oP5C1@j0Z55B^d2YDSxrwbmMkhVqduohk2`&1=n zu1pKaE{n)DMQ|ak=bvnkbCcO7--Xt6QOGmMgiUn1RdlZ;s1w5hg5FU%FSST(I>Z9Y zHY4lZd!){7_JN9PzP=AH{B@k0>>*_ZlEhv4jZR55hfbsql93RfaxK#M4_3-7gUQLp zwEd%H9QZ*(xc4NoFV@*JURE^R-HA7ex@E$LM4=O{<$^pf8&h5ajIpFoMtJ&R{1})% zMi+&5dL$JIxrv%px2_9mNJRl5?(=E}u7mJD>Twiax}9{KgMFn0X6r3ZLvOI~U5}E? zDupXxhw*+HS(3EU8Z#dEXdTHue{N(~-0&G7+I}J0FBP0`tmBx)J}s6#rL|m@xJ7Se zrV4`t`?P##SUtCU)y(D{&k7lPED{ei`1e6&uLd&}f{Jgyj3YxGBS~iGdB-WXaNK>A62g>aI;~7vV@TvlaTIi;D#?$)cQZ7J0i*fJ^35${ z;X56%z`5}!HuD+sS52c`j}Nkr;(8Hj9`qRx%YsFq_PFW!PUE>IzQ|LMs6ufxJ!(X# z#4xdQyeQ)HpCegCZ_P9-=QlKUAn0`=9RO2Gl*dGWr4|>z5sxH&s!Ou~OGbosIPII6 zn;o>Fts|CKdEgcfYqbuF+v0%YXc8M!fwMdTV~k;r7TO{Bse3hFOF$ee*o^CW02{2X zlk3gj^@bKY%Bsq`=zjm`QCw-}4dm{c67BBvcjcE#pL{r-4x!7x9e{Zs*#rOFSxbEv+{{`%)E$s1)>ukGEXI+`oLeso!HQ&rb^_QS&c9SpoKmn8x4ftnSY`7aUQ#%F1wOO5;8U zk1=y#9np64*#{Da=Ha_xQA`=KpKqk4w1#-gY3w!9QulxF_bZkxN{=%WN+HZGXc?=^ zyMOVAXciV22%BfD(|iyg7;zd0{L$Yu2%sUEZDzewn_Mk?5h2ejTYSwD_I2CydPs5l zPM|KtgRHeI^Y4Wx`07i6!PZXuG9bd*8bAnPa|KRNJ^0ZUYIrafz)v#)KNzd%U@B9V z`5bla!pljG8s~qt&T<5cyc>8_FOC+3Fc65(Sq~h-@9!d;!>4q=dfcTk`9h=)UVg5> zT_HA8j&^HId!>2OEz+x*^ju2AgutwWGesg7&gdf?@#7VD&)I@>|K!EhPKcvGq|UPllBG6YgB z8M!)0bp#;`0f(KCo?$6I6$f{^c~EPG;Ojsd7;Iw-v33ncCBxf|4DY7^3gTf^elm_Na%9RYQW`zx;17zr0w#OYA7z-XJV*!C#z?gs;yMrS`#Z!;QaF0^ z5^2SRjA-}_rSVJ+6oldkKi^pQ0Yb=ts<<)`aJ~=kR$=0=b4ze$h;@%KL&Pq%#M%bg z<6C2l!dr-BhfZRaVBW)X+ z$hiXIdSt?$zeuS6!1@SB3U;(Hr%z;dkI$Ji?vG7OZ08G2zx)1kkSuN13)0-+m0x4!!8_I;9Np@x&DzkbL0un&L)#o4g@_P z2WwJ(&55ZXvZUihPPNi>gJK@#q zz$9_=%-=Gp;&oZxZRy6;^u8Wh=0!YE=WMDESvTi1$BLD=of*QO#uBz3gl}avNMx8{ zvX`54*h;}hy%r(?5ZN_g=z+GsT4tQ~BQ|wlK@lgol3Z&1k&$wG8ec9wr!Rm5>sFLI zVUdx(l?%`YrjI+A(da+l7i2pWs+P@|Kt5{!xkGGK`uaG#44VeE|BhFN2$#TY9U*=Q06WubLPE?d0%?`S&ymnA~mB}NnJ zi|Z_OG(bMjLV=+Y`P@8}^}@|b9jyX~n`g8-D#@>#G~ z2-j!a%PqXmq|k;Hojs>zV>7IbjxV4YDu~;z_^m4B&4qZ57f7)x=Ma@1KYpCauK+pH zN{wa7ll2lJW=94UWlB{Ee1sa4r@w2hiut8jXZ6TE98v{@9k^D%u!?T8x+{;@spRl4 zcBEID4 zkyU3L#@ErCkde?vtIv7JPCuvd3UpR>0;zz))+T|Aa{QH3|C!=ABQ>9@uj;ry5u&7#gjX@`)hSLQ(T;VTFm*#)3kI$Fscah zcA&{5q%nN6sY?yK*aw3zNZ_mr0bhER~` z-o3?#xVxz95YpneD9Z~g?@fOZ++Gv0({f)|=8*%08x*TQlzD5X#XO|-a|~8FSNb8W z%|xJWiI&o1zXFqs| zM!DC=!YatWjwC10FNK>b8FKI*l65kd-3(#y#)#-mt(gQxI~^b;tUx zUC7(^G!fO@;xhlXxr88>~lclEBZ=lYTw`5oM4Yv&+Ymwhqr+SO&uI*o4VHFNM;B-#-ON!lY8NmSJ zHVaeB3#QPX3{=lm8ZyZKlR0X5OL&hFx=lwRwzaO+&7|A?cejdludeqawllE^Tt$%X zTh85Hdxcsz&WhdPUWbG}T{JM~7ytK|m!Yu!gd@P?xt2h9dr*FVzVcOa(O%=T{)iKx zB_=}qe6jnf*Fel}XQ+4gt=)mJ{sCIO!A!k@wuHe?C4<*S2E|@<7A@T}n+*6XKO`lN zDSy>l`O25CVW?(l=tId+*Kluxo^boV4LEf86}B({Kk(|6z{@(ex1mFwp?sh;^8QyN zBTFM=XCve2(Mg5TX`9j6(9sK#YT?!B($eV4*=VO$?^+G(hWyyQrKZn%V{O@EF=u$` z{;_wiwDPnGZz1mvcE^sq-~Cj0cUb+db>hk2L{^S^2#{qg-*|jflqQ`p&b+~$);IoQ zeH`%`ZMs25Tfj_ne}eio+12Wa79eZU#su~91okT<#+HQZ4`V3^PLe zSM2;XV;Qkba+x7~4Q`!26`E?8xjuDu8Pd!@9W~X)dvn^|RA}C4XtQQoTlBRy4WBw* z89z#omwCdn-(aq z{hDs|!0g^KeMl1d{ZaZV^qgKjTbb^hgbJz*f?@1<6`NEMz!|Ugd(L?~LoFyJW0VG= zTtKcm=nShwRT0esiM4+gl7f1VyEB^=sT+Qf zzpuk$I%Q=)?6C;!+b(&e0lwP`mLn(`d{>179-isr#J{gn zb;7SXw1I?;JRH_23K4;Xc$l!!;+-{?4f3KQCdZStx#7k)3F~$ct4b0$`fv0rD<_Jm zb%QmK(%^c1w1;^02B{xV?BfPGwMzo_!)s^IZ!b+(#6}eLz(q9lO4-04_{S1us89nK zt;CKfZFrOWu^ozWBg~(Vl9;OYFn6wJMkr?P%n84Fubl#P5&SUqT?C6k+=%-m$pFn2 zeJ>__wV}ws@$ae%z)b4z#(k47y|jx#51)bBzl8n$a)GNTLMGZXJlSDsvy4(QQXcxe|Hr&KT~3o_Ny-);Mb z?;047`hD}^6R!0{W46x&DLaLX@-$Dv^}c$DLD?F1)*?aihu55TAwSKNw*JsQ}j|pow$730-B4 z04<1rqXHQ5MSqv|AzCqiIZFy#Dv@UQU+cU7ikpJcVqAAbnDu0fUH$6818a1F0jV#y z9B7Z?Am_RDt=*rt7`{S@Hq-04pta4vJ&vm;wC_A4$5y^u2z4Pzp4IKJi|T*qMdsyd ziM<0&1<3iDUQdFp##xulY_QzG>{F+~7Hq{*KZxohCPN+^e0?o*afm|blMNBCCw86j zEnd_ac)9IF>`oT)TOQMW3!ZND(S)Kg;>Wi-f`1!8UCY#8yiZu2 zEcsJj0~LL+#{Ycs#?unoYqAT4Lxrurl;t}7e~Uc=uAR_aS=be2ue}R@Ueu>(R(p0( z)kFDrAOjRI((zms5|EF{#qVlrEvU?Z?6bjzd+E;`kllvh;qz_^MBdUN5bPK#^!$+D zyMFsNM=R^I+U=L=M;`-lGQRCq9$uobR|G{OE=PWAGV9FxSLRQzX4hQqKC4BtJ2mxu zH+wj}fu>VnTRN^>O=x@?*{WsviU*h3;0PS}$ZE4UydeALg&}pW^|E$F0Z-8YvkL7j#F}(gc zkFjRz#`>CLZSv>3sP^>Of==HUJvq@Wf1BuzJjd74!M zFYVJ?3-5JdAILFR1u&3Bt8y2sa(Tu%w?)kMMb6xKA30yc);`AEY^w&)3jV$PG zj4xFvI@tfA5rw5ia!4Yj)RC?>NS{OoN+g4^4@!Uubxi@~nu2ooLb=~Y`4bs!-7oV| z7wstb`;0#R7eW*h%|$Qj;>GpfgeVjfmhB(T#PRQJAHNBc(8Y2eACs8OC2*1#WWuX3 znL03qC0?3Q7u6^@7n(yFtssZiwq;S*X3;jeob9u=`bUep;7m-c%v}E&i{fYHm$-~Y z;V%3rK~_~0RujknT<&}DZ!C%f&1UVvb}`aN&xJuMUoQ7?&|w4wFcPvDyL*?w$;}gU z%O4X!U^nq)_f5Q%qtJ|4G&h!m8!IS-RWiXE*kYZ${x{Bq^&wzG;yL6sIZPZlIb=Am zDsXD(a%x)sv)O0K>7K-mrMonv#4WjPJh)x{2}k)5|5@&1=0S7u2nh2S-@4SIZUyl8 zhhI8Tl+3)iYrNuOyw10IUA%ZbgZZ5=I8!9QPlO-}EXbiOsHiJwXeVfABc!4rq-}Yb zj1n`sl%qU-FE{&q@x{~hm>QC5+|>&e-9 z%iWCp?*!=o_51$|Vba^=#cM>0i;bmlM8)@;A=zW;w4Z$Z-^?gkgbrOEYI*a_;Yr2y zJmn8diK>m26Hl}*&8X>5%*Dz6hwyE6%^8Goai7P(geka8J&UFbtDV7l8c_N*LH<_z zz*m~5KAitSn9RAU9t&Ebwo9eGm=lO#RV(l6=O6l0IEEDtHj+!4?n!LvAAiw^cqxhH z6>d{)*qW*|W)|#F`C9uv_^9fp{>>S7%#&wTmu8fm>2nVurZE*MZ>12a1NK&+W`Wq7 zC%TV)a8Y+4VUY#{l{Yk43=3VKoj0kkOj^3U4lH;d5g6xXR=qZCukCq}R1s!D%Bg-z%|bBx(N=;v@PY~gLA7$|yZZ8ZiH+-yNb8!8s( zGT>5z4e5PqQs@ewH5%fl;^tusiL=SFWQD%D3&EgPKzgz2$a{30X`%JxA#Ft!PF{rl zuHhi9+XPZo7E?nqRjcs{7oK8*Y#$6)N}OjGxM@6^J}?-LP1fw=t59Qt;08G6g=Rra zh^MDdB;GB#e|X$pv#v~T`^-Uu{i3zE{xE{-uC*&7i9H&5{VZ~s`SHlsR?JcxXz&Ur z9jGt^p+6L9RXrP+hbwM62M}%mb}iwkm=1CmuV*UGJ&{Fg6lvEVBXw=BQ7hx4dE>kZ zJ&D@N5(&aN_(eu|g)bd3kXKGTFqV~hk zo6XxdX!sp%trn}Ap%@5v9kg2`X$;)sJLt`_J=vJM+K|8&SL)c@q>sRmLoV=20QZd8 zUPu>+)#uqy!%p;h4u`d)HMazY3cbG{C=H0+UC_68>7`4iSO*{;DRie)$DfRYMcj73 z%IXwH6;8B}cKI@|&61COOVDzdf=g38s6~)Vclak&rCH@zO1hOff}o`jg%Oku4ED69 zEJ+)KX_YZ>sS(4zHC4t(R4$oC({8EH~~Vf!8UJC)$-hUBJVT<399yrZ~5h zyWva|XZT-PmC-&M4Y?z)uDn=E8GWKv13|&=NF3&1*pg$ zIGw+IB*clLly|#(JeVQx>P*#1$dvwm?;US>BAk>`S0Jl7Kk8%U#TL>NS}?U?nM^He zd&gDL78M~T+vv#hXGq+%9C637nggxBWtbBUbK<3YjJ;EQADqK>b)ZQA-7}~<`KhqI zZKEQL2nAaxmm{SzY|6d)Pg7oIb5thilQIH@oa))l=~AmKJ`S?-0JAI7U<#B7XL=Fv z?5i3FI71b)0Qj(GL88Ofz`a`Mc0+_8@unT>y4(xh&(-Na^dxd%z9b9EwXNjWF3&@xdXh4kL0(`wsUN{9--rxo<>0 zv+@ALp?D2o92pq@o5se9*2Cb%chy7zp{=kSD-od0VBaEdU(RQx>`weDquc zmB6P9ozT{wujhsK%lb|n?@B#;e84Ugf}bdc#uSkueN`aQaQlYYTjY{0^_5Dzk_}J8 z<0Dc$vT~Jyptt6I5%j9@t0~UgU;yB6qmj@YA0oj8c-`22M2Vu53vO?D-dB)f%GoZ+ zq9C-Up10ZYystb_Z6ur5t6bHgXWvO?6@*+;WG~pdGp%g1rmW*TofOTx9Qb!~C@NZr zp(pmU#+#$Y((Z@Z_T})`_4(c&lP1UY+m|*vd5XcfJ@WI|YO-|FiFGhQ^zVoXgYLTck z`h9y^wB9Ka*+u&XCO+;LlgM-wfP=@&Ayhd{a#~kzPXKLWHwb#?2^DX?-}muI$iFd4 zV0~I38$pJ8hoy3p9d154Od4eWtdVm2-U2=ScMomc#px;b$;I#Y<}E*mQuY3L`0#dt zvDIsRX*0AWcM1c$mSUl<>CeNNZ=UIwv1D@4Qo`Cd)1#b(;l-M!RCuV)`!1l2WzUY=U91+!5z-2ok>+?c2EQ_@H#W2t2TRNr+dDDKQ$B3? zt$elnuin_AsGIx6S1-^ZOAW*~;22`dw@%@wk#ok*5#o4y)n%#8MIB7IULvVL@cL`2# zcSwS}H15G&(zph9cZXoXA%x)e0wDwv5?1H^zkjVYwW?;erey)oE*SM{gkT#@?w|;zIF#%)Nkk;q8`ln5hEkWI1$a+X^lOK3$Sd@q z7#VjuF6t{(=O;mEZV4DcMQW519A+20krLxpDW~EZCdEUR)DZHd#g!Ekn^PGZOrjBT z#RR@a6H+|iyv>uo#%Dkh zY+6ugWWykqSW-pLrw!tahCJsC6!8a8SZIh85A@e!V#7NU-IzcQ^PFgnJ}<8@SB~*k zvlI0l-T_~E_}N3dQN{2_Lz^Z7Z_!nMYC}`+0hAEpOx?Jw`=o{lOjG-WZxg(a4zZY> zDrertsSFSS`((VBWHG^%d^xljs^reSBvf0OxKz;0aS9$0pqvX`WM6Apo(A2}oTXFa zb^8mhC%-_RoWx;}1Ha+RMosy?bOBMnSk!N67hrV0=la#3(n}|NVa;SkB z`lOZUP?fhaseJMYGPB5; zkC1m1)%kKxo|3MB(>*5ipQ+f~MJ5lW`8L=e!%9J+;8BYJskkzut^&@hMDuDKmU*bO zQF+ZRa7Rh^pwY*LrF8$K{5uBF!63)^OD>^h1$#_|SNbb#0AszMOagNy;UvN2lV3^P zR3ZVDS9xq%`$J{b1dcZ#|Io3@>(-)^0jg_*9c%>UpQ?&Te>ad)>N`{_<5caXi|T(x zt1AMMkCsfYcBngz?#eB2pqL zIs8TieEU;pu?l^eIq;W?rfVb%=!<9wUV}i6=z$yfeMJzu@yiq_(EjJ?wY1r`2-L{Q#*?f4N|4b)dkI0;QdRKY1B+65&Um** z@L?-ZVR4?e=JR0+$h6hyQdPyZrIw<`P#L)xzsy6Fx*2C*8n)Zq+GNDFGnKYGPqmMI z1G#HjDK@afe}y^cMKyVM)S-FB4PdPgb~N#_bjm=J;vG_d38z4TL#`M(0aAJ7*jqn4 z4|MRYELuy+!(8LKs=8(6x!CzOy9m+H8(F)Jhv{0KyG5I6J8QZn~2bv!6Gg ztMrVLtJzqiPq1<(67)D`V+?Qhyl+Y?CB|AdW)me1S~u?fXYuU~QrNdG%D741_ceeG zo?FK0-nXPxggw=J{>#xx7~$h@EQ;U1;8xS#*>^7*iL%j8eq0Gi=))2j06r3+=VwAp z*s`T*ks*=Cw*iHlHV2kLxy3SEmqF^q0kXislf^;uz<#PnYM9s%L*Nio{t!!kKV@z` zt6GefX39c9Hm6!FyVx+l3z_1{kT8r?g{*#Ino%5^)Ztsmkm!iqdB{tK5v4%$7ZxMZ zTO$oIteiY{#;l_y=%{Bb_3xuc1GtG6Dx=IEM_bacWPC=gVWfw)O^&r=gDQ2Hc{TBDmQ4#80v@!MkEmOCM%eUKuHH66(*XEKdajHoK5bh6jNc+ zg3vCwc3T2r6ry2YtAl@aS_uy`RR+oh=N}OxpbUquT`B1_%qSm(qb*>|(9d!eA^#Ka zUz@>i(Rr?YJ-*FG(7=uPwU&_83UZWB_*8;=mOy9}iB5Ml$Jxm4Gmpiq`jKOSz{)w{ zqWB}bCCKe(&^>T|Con#j4hsesge1zRQ(^h7d&TDPGEzAMks5^1ojS~CIm-Cuqed@h2BqZkH|P#OW2 z3onFr>XQ#)u3;xylw#hD?m?K_)Kl5>yEenb(EQNH%#8HqrAtn z7dQ=#9QsVk30luP-4lg~xNt&mg28hU<^?ZoDQa{R+5MWgL5#u( zJ5W6c-GbtjE-~4Zyj@D#{YhMe4T0l4+nQz(!TYSDj}juH;F;ibO`=&zw?Y$<03q6+ z(o~nEc14-gga)l}wnD$z8(!*D9}Qmz3Fm#|X^6MR!54MKI@UTj9L4E!1?IJ0ron}u zX+Y;K+@vi(B}ag6_BA4Ax_!Y%&*0WzJcxo6)|}S$Od>GvaclWCcXT*~JG)sy2eCNR za^ALp`5(PU?PJ@!bNOT(+X-w}vvpR}y7Xj_M$-s-bctx*-o zbie!ht%TEbiLHM$@F^~<6ke}y4%&;n)ayY{rr&2a|H0O@=_7w>%nrzknBM$d7Fuk` z_pr!pFTG|5eMgU_8TB~NhU%4!$$tYI@4qe8LLJoo4Y_7h1pIi5`)Rp@v3s~nQ$zl? zZimQ}QCst(QTmHk$<_zV`8|<08ieFGBAy1WaWT0Adx3MWxzL{B}_j30o^ z{>p9H6v1NwW(@T8&!Bwo?Vyoyw!&aKH2!whHyt}WQ6A81*g9W_K}!Dag-Fr%qv{!$ zp4J-b$SvhD!iAAA@KtRz4JNNfRcj!}c*y4J@Hu69UBz<+1XC+YMRRz@rc+S`|``SnznjZEpoa@EMAEwls zE;HCIOfSp7QNI=JFlg25Zt8_Q^LuQJzzDlgm}GUnBEOhqdb=nq-oJ~^qcY>@vEWV* z6ESYpn}*GCOKLUfPwh;fk6!4h!s@Ze-`qUl6!48D7W}}76v%a63tJLcKKhOG#2o`_l4cz9PU=sfq zb^-ym0c@H`?Bx3wJD~{ZqCUq*rKN%3Vnf(DFl;?B-*{uXJ7AI1V=?eyi3nrK8ez#P zV3T8F)8b)s@?mQkVQWj`;Ns%o!f*(&aEOpjzUMe}bU3_nxGXSau?g4A5YNOF&(;ag z-WSg;_^*@i?}jL1g zklC61b@DkOv6CFRrWQYM(zlMjiVLjF4Wh_PRg)4!l2c)`l_f=A(nM<^8^k~s-cnK=Gy z=KHVBQGrzU&Pez~{hW_l*X2L(iGq}dmXU@-kVZs_Mna56NrpyC`~PtAh0yp%)6xmk zN~zN-=_1X1bh;MwCR+5S5&!Oq3T8m^r+ri zsqcSdCu$~LcP1j??zP*h$emHfR)z zoz@J-q1I-t{=lT^Dvg>;j$XUnjVv~qK9qCD7CzUGVP=q<&>MJ)|>I(JdyP)i#2@9ov1MXOuF<# z)*E2Zh}&A7P`UW+%v>bo^gRm`I?V({{6uOz18ZwmoL|elRUyY|FJvQPu=a+6alesU z7L!TyOA%|zZp-Hwx}jwQR2n{-7&29o>l`$Sj(ao8xEOn467&THV|THQLu-bEvi)MT zI%XwI?x7f}`4{v8Cv++TCJQKFSW9*cE&JGgj*2W#C^T9M0oPRG(bbyBi4?L|Cgo@o zqD^@z=et4{#&@${;QQ_nPbs03n#36XraTh?mR~|-p;0i6pm=jj*>ZrDnH(c4n2>fo zC&V>I%IF(~eH!8K>B&UYpD@=H0{>`I;2I`NBRVnrNL1Lo`&ivx zNdoD|O{$&BxicZ&Gc$a$EkbpD1U|zBq#yen04W(fEm9~y4v6I^`NnNBEN0#WqK%9B z^wfu%Y2GML2AR;Sv1PIGIKJ-ZiiqPaNw!Qw1unaIsg{>JCbUA26AtFu!9TxalU(J< zO)@5Eaw~>lMpMhe_OEa89ZjePKlxU)>|v3+JO!bVhXib2uiDK+4T8`J)DL4Rez(Fc z!-aay1U(L4KgbY&z8&AmDmA(%VY1&U=3WQ9#^!9-c6*S2{tf@mIb{gB9?t;~W_oDz z!OUZUSZtv4s34r9$8K=R3}YbG)j8#oA1FPH)#!7#n?k+*hx!|z{l(DAFzAK;U zqyh9&q5U|)b7q{!Tgdl>bgT}k=Ux7Zcu(%>aq`J~*!H{V&%P7D!3d!5$L1oYd;NYM zaJ;f=g0d~N0ifM7t}wzqOt+IPe==f=?WjacxT@I`tiMK?{vErRByzw5kop=C5K`wcgS4f!Ij^29HGM!iU> zK`=)rkv?(_^o6X_mQ5(T_9-eIOvIXz{}`ncy@s>SMy0)D30pQa1+Q~vdZ9}P!cCZl z-8@4`eGJbqhUhQ@g-8_a2CyO9*EwCKF<_Z=0c*;%yYNbGn0>oJBQ%3K`ot2QS4($3T~m&2IGb9k zCI+Ha97BimU4@T53L?vAgAR6pzu+Om8?%rDgk6`bysCzzmP1mrw9R?r8Z`l3gdT*_ z(kR+-kj(0ITtRu9rQ&D>Fr2RP>81ki-?jMu5>BKJWF@_@BoernN!7sCgP6xjMqn!zQz%h@ z_hDU&8TjIQQkW~{UCU2a+ONe)p|Wk3sM?ku3Wfp2x}je(?;G@Jr9QD=OuX~1OgmYA(}8`tY>^dS_; z)8eEqHxY@#fSVB43f}{Y3PfJERofhBs^r&;H(Q$LnQ{#jn1qjf5pOc&^; z>lL00-QiB_hsE3+02X2)YoTvlqo^6GrG`4TUZ!K8bQWh%8V$6JG!RyB>g_wpJYZ#O zyPisoSaE3Uw|19uMJdHan>O6d*Q#!Roj)Zr6o*Gp5lfF)4Cdm(-+3oZdb-%iqCg{{ z8li=}+=NxH*M>QOnlg!hS7A5`R)hnldoQ|iM_422!9Rbv3PNuCfC08W2ETf zI{qt;iOZ7`I;|bKDI+k7BM(#XlN#mu1z9O*c6UCFjw9Ac2Zr_2j%n683eNO;ood!M z5g_%3HH9{XgZRbI)2(?W6F5t7G^*x|vKd)b{Lg1^rU+IF{@fx0exJQp>RijK`>umV zF=_vi{9W{+dmBh;KOphf19;#(Of4g?O=)(m;IhB&tiX@PcYyC5+?+jH>B_tR*S3AI z?;(cf_5G~;IO>a6ld6>M8H$hUc5riSJOoiN_L~h~-0$=KuItqXGUrjrk;^r~qJ^vN zXNvb|RtWhZH=d}A>8yaMe}aR{FGOoEg&z^`5%;c=e;!h=bVsnk7$@3uHjo#*&8m{| zZlX$0lv7xw-9D11pO2`4o^BBqGnD8DM}6Ox-tU(Z@c%L3TzWitl1Yd_X>HhJtzY(> z%My5erBFXlVpfV7u*@Z;>25(C^2-MFx-@6d{+XwCWXa5Y)h`Amf;2*k4G zbr&2lWuP2akV%~gg$V+J^azeh5I1_nMI(Ac!%LOWaC~0}{fU5{r3fCqNM&wIix@9! zUuAgN%sQ6{kuc1)UYc~OqiBC+lxG%<3GP^sR&{@bgY%M(1A`J2r zii5!<6H*zK?i&*?6lCEL-9aFi3TAzE^<1tf*4Z~UJ3AJB{K7jKv&u89#8tOQDbhtL zu9z_{HU3`^Hr;#TU2Jl^?$lokwvjlQ{OYO;d``f+Xl1;mx4OfET&2 z9l!~)G7D=7a}L6pnZi3UW{%P3p5>r5p#+SUM02#n&)KntYh2C^%qn60he{I16NzWO zNr~aCBw<+H4!-JIu>=eWygEs548k}UDHrGnzTL-z*A>O2Kt%YWMY~B1!1$T9WL!Vs z6eCn64U-j-jKv&9LK?;(m-x~Zi^?&@LMYXiP8&!Cmd6(+UjRLkq&iHb(mv^ev(R8~ zd7)WcT=c-?!gqhjx>@|1Zj=4fpVQDVvjudi!v>(VklIS|J^6#R-HV%Eg+ z#&~zA{4&Tgp1}~?aG~&{E)fE5t}p%m`#NTDvJ<1P#+0?o&sgMWD6P7&~Fb zzr8@t0|oV=Xk7kgb#S11NoE2RP4F~IEhqi!C^qk12`L6DyezXLIZt6D{IzS=(|VeE zbp()5oJY7U=oTgI01O6Vl0=rNjxbbca!5QlSxm{6oxn@n%88VCqE7$<1Lav@?6F-t z_YK7^SFBs#3U@Fy{Z(;buKdxpNvM&+2@uGkTPbEk{^F^+Qgx)V^J^vTGKRuDb`Mn* zrzcE4t_l^btUOiqZ5SSI5rpuU@L#4Xs}|i)#lb`Y_oP+(ehXK>!Zsx%RL7{%r-hvR zU^*_icBt?YZaAGZVjqPX7q6oJe0N64B zOyR*!L577a+|`t)eA80TTAr96E_q!I_+pR#mXe22{5l| zr50|pIdim+57Ay=bjpi&*=+M$NHorq@Z1da?ym4-B^Aof3OZ}I?0y$2N@Hix(d*U` z(@h@N-62C1@$Q$l6iH_SR%g01SzqwX74p?s2o9a9)Ww2J)I~puU3)Tr&{T;oE4fgZqf@ zG2lb+7)cl~7?TZYEE@D;s-bitBx+D8JVBEn8{)aPKp8Lo6E(z~Qf_P@&QU9P&sVD^ zJd96`|CE<+da5SmlEVuW?pQ<7luncE$u7|@l3XP9rbXNHAHfC2On+zBLz+=TTNb{d z>gQ*?xe8I~9)$u`ODvi#&Y`u*z60q^xl%s1Ga}Q(;@2BvPm80ga&5j18SY}^mWpj0 zx#QU$sKy&y?+(W?7C?h!gV#zEE>D>)pW`y(dhmQ3>eZlFn70!ULKtgvWTGpm&SDaU z8Fj)D;AjbyJDzN#838v!L>;DduQ7G>YA}x`LCYS|#hBm)be*r0Wf?A$P*H=j>Cb!U zHrO-WTUwt~XHdR`xJ}eIL9>z)xH7e&N>Y^*Y$)mTJod++2{AGO5$0%Dv@z}38J`am z&=2K3!+RK+3bu0*Y6@j#z)V)m4XepVd32-uHXX$DA{F#-3Qo>V=JGi4A=&K5XdGqd ztgF=YF!qe76k3x}W4p>s)K(F*vGOJx&@34i{K{$q`+fO3PLxOeKrLkSp?veP=W;6L zg%-F=3`i3RF@(u@Dt(lAazj3;aL{EI#U+SMxh_2?m+YERYf8pI6ER~nGU|G4Vw|-b zd1z4mkbZQ#j9LWNXdY4(ml!1L3x@(F)RutAa$Xg>KWcI9BcSwWPhW%o_1z4S1@_5f zPp^e1X7$AU3|eDJ1$q$L%2dju@6bqo;m}kHLF{;!T0RRobF=)~1smH|TcElHiUyO7 zGzCq_L)`%P%9O(-^#JB-J~4$9mSH4?GDU;OFQsl*2y)|C?uWAD{dcsHGsaM!XPZk* zS0f{}q(*C$*zop|p89kG^%Va_xdFZqx=&-&m=6!jeo$I3K!)mTurZD=_t|(**a8cT zdHyQ27KXwM_}KomFcJGW6Rh3*xG`L&w$#YAm5KE>^>|$PcVHZ%aH0~6>-E%7rCX24 z=hvM}s*6}hEM_!g@g>_aGg9FxG9!b%OPgPoZCTc9T?U-kuo8&oGF_ZQ3*r^LX@U^b z8JaK#IP%$IUGxG%1Z`gz+u(7_Uc3JdPXD4EF3*u zud(R2^~KZqD>8eOlDO@oqZ!Hk4bTTvXGq{zFFD-H@g2x4(*>M{d7M&cEFVvFU32py z^_XI;9(DIvn+hk)aIB3>0_VeOUyq_^`7V60sKepld=JpEV<~=tArenh8G9-_kT%7v zgGt5qX<_npt^b)~jnkGyqw845CF9KL2gqzvXV03wR0ax@&aBi3@0YXq#C#fKLmSo0 z$+m-+YQV$OtR>gRa;a6l!3{sSdAh|ZZ7^^WI+0?fcm5K^({%sj-K@>#S#kI1@c|~5 z_i7mzm=wNT*=M0BVTM0|aF8BO-4%j4s|kk%XKkv_WBuNN zpdTFgM|`1^*t^w-wOW=L1iuj7cCLuK+TJBo;R20XjcCF^Z~3Ge;fmQ;@9y=-&~1j= z)_~94!3}^UgoNeR)WBXl<{LdO_j5GQ;PW(5Wf@-n>Y$O1gI7hGZ=KYb#e3T$$cH|0 z1Gk_&gIfOnt{5hYnKkEwT0F~z0OjCVbYs_u@Vukv=cwtDbPFJ$^!WQs^GuKl>Dy%l zhBS52ZnY4{Pdt_W98L^nf?t-sm;wJpCdMX}X!K96N+ex<3FYjMc=4DiIS_SmVEGh; zC2hgtl=%CDKOdstU6?UW%7Wcq`O7b_4sfh^A70as(#!Lgbd|lY>5e z2lRZr61o);OqRdFSSHY$9LN0oHgj=lxN)?c9J)GofzBuOGYp z&8TN`i+C}o)a6Z!wRlqdtpS2d`$N(s$0z4sD`Sa2-*Ezk$C|43Fua(b@&~VV${-CG zzb`fPnfEY%!M@nyP2@EYKhH~k#ESQ9py8yv;?pJ`4n-$Ve#OJPJ^xvRt+;nZmso*# zb?c~614Bw5kEWFRG02UmJ)D=ya3MzE5%ruldM4YX1opCNKtkpM3wA z=}fEl;jk{C-AO1+2le~p+tkyLH(H>wa`IGDz<15}kINI#EKRMZxy6J2c{t5$EHt zbbD+mYeh23BZ8xkLU4o0`+#G~VU^ z1w+^XI8YZQ8kd+5pBUL1BEo+`Mrfq@zjh*#VE@N9M?ptSNlHvZN6dgce8fy_#4LQo zoczRGY{Wvs#KLmK%3A*_<&YHy*ngM{866oVAsHo%j1no9gZ;N&j_$u}KYU~yd}KU= zf8mR;9GQ$dnW`?Cx(S)KF`14HnXx08tuL9ACz*2)IWZkM2OGHnAB;y1CMpIKX0ifG$1Or5tVkm%MXBsmX8Z%EC zE942JvGe>7viVm^_jiYqfEWV<9fQeh2CF~@JLHLAaPs_bMib1aXU}Nu$zm76;sj@- zkqQnD3=4~hii)hQt!=C8=D*#+S%E< zkAMC={!i-h|9|rTH~}OW68=BIkV?K%WASJ_39nN^WmU;|Qm#N8Ou6YlV8{@!bUK;M zdMaPJxqLQ{n_S+XbaH_{Un(4vLZ#(+LOH?Pe_$fC@O=b$jQ>q)$IH;zyXPV7+eU~ao*PJfgnrOY)%wx4IrqdL- z{5*j1@lsr@&MmC>GvA_$W2Z6-_AaN?C*bi0zjB{;b3Bi-B5If%H1$*f#cn9r~=cM2ts{_ zFUXBYm0zM@-p5~}siK(nV(2m*_F|dJEBE5q+K%_)xyG2jCh)B|d`%QOto-^;3~9Ve zl7cYrC(98#?x!d*RPCp#37qVwX(})ur0eQC9%LBURUKrSc%K|(Swt}(X4_;s9_Bcd zR~_cMw4EI0xsD+>HF>T$9u@c=Rvi@v-klu1heKG75fQ{r$3-y=)yKsN0;k6%$qFnd zrRhlHU0JqW^+|cY_vuLm0=cQFvNY4_w5qba`n0;X?ew&!VeEFh(tVf9&E z&)w-+{Q!jZykUgc`Mhz0q2|14M&Rtcd0v6_qGeg%`J#2ruI8d`%lnr-1Ov|crept| z^PA4&!WwwjN!>3H1dU|i4d8Nav#xg+zZ&^Sc6s);AMnKL+KsXuUq5(>ulvu?mB5Va zP`JeT)d>D8m&P8Twc0fV<|B4BO3qu$IYBqvJ%COJqaMUy-rXIU*1V@0#o{zU7OO1L zWul3>Ca$B%c~uvNF*(mPftYxF15y)e=3-6b(!L0{C1tKg6mqx6P!9^@%`aZheItUR z*KD$0->qAYOQT}ha#@BgzVLxJKq4t;xTjy~a4W6~cs$MiScQit-t9&lSqiNis11T} z>E~Ic#=c4vaDZ8azJw9Q4u{IG1bJNg>>{3X{5%e$#f`*G9B1#G(ooZiJhbTH=sqg= z=k)~f`)ISDm!&^m3c(!sEW?IvGF<}4-jJHUVZHTZuaUr0$)>O zyZ6VgkDATWehB9fh9Af@X6O9r@$uKZ>U+_OGVs2>o=&$Wu(+Nm)x5k4xtfl8o#-jx28bWb($-xI% zovrfJIQB7?2g!GB&!lFfpxJ=w%z2(-9QDvP@;ub13&lwKHK@B%sWFLv&?!jDkJ!LS^EMVOlYr#3NT= z1D6uY2SGvpx@mBR$M8j+j}UM01*$KbMemwHBR%-pJI;iC82LohMcGVJ_I?QiQI2xb zI>Kv_faZ5;vQhxIyX90G9hrXBl=4&^n%KS+@h>G+hLxKDl@23p4yHDu7`P+fsSQy2 ze&U5pQ-q_#AWS1m#3BmS29543NtIxSOr-_zpIlprip_M0@_>WJ6*b+sW9W3Ermr@^ zA#dc#7=w~@?h?$JFxi3&;GHD5y){5SJoyw}biI_#Bg=qcIU(-t&zZs|1&hy5Rob?$;0M+_X z>>vh9!LjZ4jfQGNb>A5E+CTYsYjjTnMYXanVd|W$`lxG5mP)?t&l<@#i|K(a(jPw1 zXh<#Y3>HB$*eyaM)<-jOUUlTlGm1_Q%Sp6Yyp5O-pF0ibr zb<-m?H=L9cmRTjuQX+coM&6yCy(|D%Z}PKG4~tpW8ppYgOGb@wy8p<(&kw`0<+G`e+*Gl;wPPFHD_|4Q={Ch}CiW90w@FAgvdE^>d?R7zX$rTQH;0;YX$N@nsD1iQ{Yg>H)PUkRM)qnl zp`LOa?;ToW_Q>{02KWM-#&2>*PBuJI?CNgTs~bM&IpsKhn*H(~)pQ9oT{B;xD-Fd^ z1O~DjB^C#7maH0Udb*{>N8?_vBe>uh!MSgQaKG1n+Fa17*L(kCloNuM_(hyxaKSX< zuJ#M@1|D}}OB&8u{XdyJj<3`=Mg>+If1?7~vb{0GS{s3?18)rbJI6C9eR`$Db`~Xk zEMd6PpswvVbREKVl(x({(_-RLxPJW)hwVd#nMb(Oc~+l4dBuRRI6*(wXNTUDGk^0x zGb*N9|71eub#nrTacs?AKast_7>co{?S?cz`rl2G2HU=4#~X`S5_)ayA(p}K|0RVS z-}M!R2yO8913KQJneHHsqO3Du$9606>m}v%i|)@%8tut_t2%yR38$~kethIq)~hUV zHy0YG8ix*WH2iw?*%hrTseO)v0o~A5AJMkHUC5o2w7q{_j*N?4TnCgl8pWO&Zaq(G z3jNWh^y!cUM)y*nK=D@KS+~g7^&ro|=bFipg5;sUMt$~Q@0nm42W+}#B{`u6%M+I;@F z;}#Jm;iZb%!9z0ebFkg<=|;RiNS_x{+|(c3Hx|Ls|5DPW=ZMZ=xb6>txc>K#Jg1{x ztLfWlax1GQ?m``-G8^u1pT zdIr*0dgyh8wWdd+H=|hH2AeHKI2u^U#Tc%&g|qNS8;(Tn>!6#p!zDVDKfa2lIE06m zgh*RjK}fi-hR`COUir0o;#&xL)hxN+=;3>2nEce{a(pGA4UNrKGN>Di`ML;6k4975 zHGm1>7YhldrfD0>`VGs*(g8i%DkDqRIO#Mcxu{;17{sUDdv(SD(=$;jD$R4z69$i+ z!`xp-BSZz}6&O-tkN6XgQS{)N3f*5VpYbMs5aO)&l?`7)$=y%J<5;&JOs{!->$^m?rVIGE}*WIP-MWv;Ab7Rri#X& z5+}e+X@HXS6eCKem`1xEmK+xR>_PZ#gA%)=U`DEjpof41Lu}S@N;v~?`c6n}(wx&T z{!GU9pR5RJDfX{T@dUa~>ZEKsvTqBILq`_HwG_phJEDeZwA05OmAo@gZXm)Z{&j1a zBpr^}7;N}oQQjH|&?wvcDsw|MUCU_0(P*k)WFLj46@kzSO0zHU)18%%$L;^z+&YrA-kjW=xr+X_j~2vy7WV zF$OY(pHA{#3b8}r8KKQ#CX;!^uK?C0>{=jDFEf`(4uB~(PvV4)qC_-3WL@aenqvtv`tD~XBVde2#;H%`)yBwPNr=d*D8kY~5V83Ak`&)5 z`}K_?OeeDg9#~(5C+=XNYGhm1D;JPEB~|O?Ml!oG$;b1F@TZ}P5VnT|cKZ8IW{T$) zM?D}Esta;+QbX6R6i>N2iG{Rwr9XB8y~jmU9n-@dHE=W$l~wt#5RPWnp8XT0&zd31 zxoBcsIa7{N2m;rs2jDPsf|b9k4{2GopZGp=lI#?p2ozz}k>Zf+=iiy!D_DVrC}w*i zDU3TUPM%1J%q=I0OG=yKsxB`(sH_zJ862p~RxnaoT2(RaC-6a;`_)g*_Vu9m)s5WDDbRUG&sHbAT^DVsrGR%`d+y*qzk^?oO@xY=Yh$Y z85`H)S9PHc%!sS5Q_)&yL994&C=Q_7%SnyJaS!C?m$Jai%A#U(>vp~-aYG6(etz(% zD)~pL9)-XVj`881rA!4w_#n<=dxHx&{lSj5=2yoDQrGuz`V=dJ1{JP`UntcS42>%L zbyy`em?8zgjSOMA4Vb^m1jx9?So8;+GzhUg9C&L;;!B^Dno!SxUU9w)Jk0}7hRv(t zbwbVpY~9V96OHp$%?BsVHlT(jnigDEcBQji_DxRJfMRvlB3i5_ip>~#l}N2Kg;&nb z)ZMK+r>t!;V6(ILJwq??YN|?%S`AnlnWvSpS<_?<8tl2=PfZp3^M9zS^m00@{e{`$ z%^Ks$Y&hfHJl!Raff@3{r~~!3k;2IX^H&RLb(^(lDg|p0XH9z?R)LgAvc;K}?^%xC zrb+ZfXRkKT^PjcZzuKS6)`FJX&^_wJ^EyGph4Ap~S%n(nU;YasWjLx`wr9!CPUSUB z-G}b>F{*WAUFD|92_t75na17r8$Dm}E77_=ej6p#`q$i(#ZyBv8(Dj8o~l#*;_CUS zRF+5Ts@2eWK?=`{5uJL8CS*ix=#00Pjkstq_w11 zCzH2-j{ESHrQ!s0z_JALS+KHdv-6atgCi%GHhF-ks^V>)fLl&(GTFf7YS9=zPm@FZ z=tGbEv|L?0kXWjnw6~>s2(fjF}pbc(l0$Pk=k;AZsCf4XOmPr482PGyrbh`h$Bg#C9C*|qz zvTVo4A?~S~42THA7LjP{k(6dvC>vP7hsDm6JR~T@UQW{Igx>i0WH?wB(C(!&h$@=b zPTnsaey>>0n-WIr)cU1KN7^|emD58?-kFf@=sFgxbesiM3WR$* zS$rECQMBsV(2u>x`P570xBCqP+L%cpvz|l#x--lts0#)*2P|!X-&1|rBh1~AH08~U z&YybO7Mx$NN${s?W0B7DKYB_d^H4u1 zg2q;=`J7fQFg@HSHx9d1HKuCno21zuYq`7o6Ij~M)>aU+#oSII2SfhWo+!F!^TpjQ zldM)K>J7-7T92YrCzz{WG7@8SYMW&e&tx*MYI<9rw&T8}oNQ6{Kw4@A7RI;71s3$CL=i4$jujGc=Dz&+gF8EtiADCmp%|`a9=@5ag5;nanP(2xzH(Q=P5=j8ryTdtT$q% z_}Wv$y*T`4WXP2bi;8#%Ri6tJK?|!gZ6Ac^xzCT|%h}fAJx(I8xaK%kH3{!2Wy%dO8KausFSJcbC~FG`}vnz2a5j zh{0_3E)JmleBDM1e8W{gK4aCAntM6q6IRFOI88yXoKnwgkcp4hsdTG^V~IiK6upWC>d+k2d!TAp9to!>fN zT%1A1!HX-)i+i^#|K`FgJNqk#w`*%1Yg_Xh$e4I#3z-yeZ0zqK^J3)3o&DXl+r6Fr z{lnwKyW8XA`_t3&%k%ro%k!JdTV#%Wb9;V!etvhgb$4@*%#{Cc!c&MP^3Jak3`epy z+kMhyEN-3}#NeS{KU3+(%EE8Aa`jq`BP~&>d80N`8=p94j5gNT#Nx4ORy>v%^30n6 zmw=s>k3}G!pCKra2os2ko{ zqTKuLy_=4``;h0>x9i@2;6AwPKCJ6Ftm`(c>oIKNKC10DYUuG@*L~{HV`krD=Fnqy z$8urYNNqz)U3E`gTWw2iOG{JjzjLqcYU)AG8kwp0^^Nom4GeVj4D}5R4fPBmM?W?* zHZwD^yfrm7Gc`9eGc_=?d_On0Jh!ntf48-`ytOj7{O`nPkYW7F%GS!p^4jvi#`5yU z^6uY>Z!K@^?Cz{A?`$B?IWnq8j(%rvYjg??#uP3?!e`i91)=9bpBW}V9N_MYCp{(-@v z;gQkOuFkQk>6zKNkMj#dI?4>i(-o}FK8YU?n_QOK=a z{y_hG z5mF~m`aP)(Who`Gf5ZCE`7K+T^2vmm;WBi?|F$@KcO$Pl7mH*wc~evhR9c-FJWw$F zEJWt3SL-c?aaCwyWQ%dFma0vi32F@GOwZS+3RHg}(wd^SFuMkyE57T4KV%N8bToV! zjy_{Cn^{XU9#NFb#(K=UNyJm2Vh+u>@i-bo$i}aTU0O#&E5tn;GDqB#r-G(a?q>X2 zko#%sg}&$fz&QULstlV{@9A(;EJ&KSYuai)TMY}TL;#8g!vLsY?D@F@Q6S`5oSg8> zJ~6lc0n6e0FS3yl=xBs&T*(0GpkF_(n-RrJRZrW8s7w|HCqztg7_^>nX;kc&$E1JZjZBFYZ>f8PC^_l*6VbM`oA zjKjD;B!e&am|1hK-?i4Y<{~O*5tR#0luL-}sq^YN`|3qRt(+6BswthUZJnZR(~@=n z@{z!z{rIZ(lByc?CZ@cqy|SpLsy45xp|Ps5rmDH6YGS{(rtz%y^^ag0Yg*ct+nU>Z zI@|mEr}}4b_=%~ZDeTDN$k+(!A&gD7ld^1Va(-+EJ2pc~H|!*KVzM7cs&O+t*qM=$ z8PW$*jhn)f(rs>rusAuj*+2E)N*GYL<-sNe87nQeoj2Q7;vL>WMH1iWo~JiI%Pk2d zY#S>GQbU+b*6rznZp7p4AcbGIJYOLV<0AFtu3Z-wl;FRN6cHd{*GD zjX=f4Da6LcCnX0bynPp)l9`3Pag&LjmWG^+ilVd(U0(6NvZ@p!e@h}wP+F7?Oa}r` zl1fx(7q;V^4D8zNw<6-AS2-`Svs_^1Al0auZ_~2`hKoE<=85ymU#?%~7Ut#Szw+^b zOHAWk=^PXGX@hG!}l4( zPgsJ9Ea4|?;p=SiCv1sC!KiiVi2eJi^VS8#;Hu@Ker#2FV@(aZw&aW%8p_elwKdHR zHO)OEZ4Hf`^F%Cmq`#-Ve{KRlMf?W|#-@hmNYm8(pV?`CY;JzCpENtQOpcKodFVg;68cq33)6L=yL)LAOeH;fx#!h@O@zT39UboHt>Wtc%L@- zgf@Ji6iIOOHYE6jC3KrDfvA_f@87&$Ql3}R+=#BpD@PZVld=ijewI_Uq?~Fe)tiRe z#^#3hmX`K*>`3R(NaxrHp7b|0@ef212ore1!~|h-W@?heS%m$?N&NQuKl$<}SxyfB zY`Xu4@eh32lI#u_V|$IwlYaI@E)!qmrS(F>LGqDz?}pra;|f0=A1y8fBIvy<(}a7S zf?nqMH(J>Vc#0~eFTGbVBs3_TE({svb?wG=X;eHf&n0e-f2LT@%#`yNxLDZ>ir6Fs zM6QTlu6Qq2Ra0Fn{-GXI*LazqPvpIjaQo-KF{K5NM&228>i;XIfhXjoPzIhwjV-@1IdMH90i( zFUtHgo=BYYPaXb?n`hWFH%XW~E6DTnlO(z%1#$fhb^hTTQqeg%Bvqe7l7->_#>hjp z3}L+(*uD{MbT6-wNqqEyuD)bN3QGBVOK@`|!Din8+3a&qztN-E1q`_EN1ot^ESJ=mU}b`odyW3i<04oysK zZWA~ED@xnT`-jW>C&a_;Kh^m!3jTk|fxvq$aqb|Is3?_LhFM}nJRhVJmc{*slPZfb zo-GU+e12_^pYqKUkN3Znzr=e0=^(KA6xS}MFghuOiMwB@5#VW%svVf#!xj->;Kj$r z!lob3p7`!>q<8=d05Jf79{`}7A`ep(0V|7ul%>TCZ!ib@dqqVh#76}rCMKlDho+_` zn@LR8?70f<_l*m6xNdNY9yUIvb#v=1Nj3H#T4!TiVa4y$yR7&`w-W z8wn#ONYTVkj12Wp{PoQI9kNrT5;;#eLj)3kFD}o|Pc1IapUEK7v$?*FZ}~GiPtGF# zXHXKC2_*PF{(bWM|75KJp29NzNpX?}`kUfqrWF%tpWY4sPlQT8oqr8S%gJp_fL_Jd ztv`kE=P4oxd`8jX^8bON^YRM{i;Djb6kUg@Z}|8>DVj7zb^nW^NyBk;Y<%J$iYCm? zeV<=gT>4AVn_JsEyLGV2dTn`0}pKO>=h|I_j^g?&%5yl|`h zo8_guD!(^L@?Vx08PCI-QvJ_iXsgdroZ7Xd zGXjnzjP9*1`&#GzokY=f<$n%CPxsbUeEWo;pySdxqv!}GQOh&W%h_S*44wL_ggJ==1PEMK<2>l?c zOIFWTONHy96tvN8PNkaHvY!1vvAnEp)Dgl(H!<^xPd4k93rbHn8`f*rHa~86if%RT zk3HFHA}*G0HJ===ZG8ezi*2`1UU1%S1qq?I+rT&1w?9KQ#CF=5jh%NoSRK$iogBXF zJ6+sJv0W^GlJjo2a3OlPN33prw^y=DY!7#B+S( z3zh8;>D=7dAJ*3pKNz`d>~b(_;!t)lX70OjFm8nuKm6-?aV#u5oOG_+IQ;6~C4MyJ zHSTgW?YC5RG!t;Nar6yAEkPuNUT`JOMhKM?=b~?J62GG~B!0{%7`y&hNOmayv6$w& z`C};yNwU1;CAl826cv^qucGTVkJl=@Bz~^fjJuxx+`ufA|J-am+WfiILVe|AyZwUO z$qrVi;$#B;`M+vzXjQpM@-lcOz?>k6C&poX`Qvuz_lI$7iwuq{Bj?I37$7NropmDY4S zm=%`=yoqgv_-}`BgR?;z@HWQO?NDKzY+7S%8%x7>m}GP|*a7~TZE`zY2A2)-#eU{G z-bTW}IZ!0LotJGV0C~NQN1a@@act*}hMgGq=vF+ogEC^BMup;?j~Yz`4Ya}y_UzjNiE<4Nu(yunr$x`t5YDI)Qz*3+e^Vm7hEgU>~k{R zOP#lDh3clY}=?4@r<7b+}i4){;*We{rwH7{@Z9fa7TcmuU2OloCpAC&EQWeq~j56KNVeKnYzu7Yw>%X7NOD(Q-Om%&E!Hyb8A@!}&)<}cDb{h&8cvOibxTdhd&X)T z4$9nPO3jzF#v3LN%KiFEEsuJ}n~x7F5cFs(YVC4eiOH)We!0-7+WR-pR3s!w;1)WzG)TUneIIYcYLg zuD-orXO0i+TIkE&k=j#pY)2TZZn?+R8^NKx++@^mNwYKza1IB{;+2E}fKbXmT80|H z1Q4?&tp|`~5+L*srSF&Y5KH>^{{S`#9vd;0q*)nr=29IaEkd5HKrZetpDif`76M^jw_h*^=y7D{@PP;!rba-V&2 zf8yB-ogprfgt)-K6OccVE%r=MorwXG#;zhgBpFpx(@@hsInh5d(LXtb#}fYG{;{d4 zb;9=k^6uiv?)o+f1paFolRHJCtU&))q)5@Iti=8K^)RH+oYDW-Nke&Kb5#p=VtZ%; zKQe?LIeU+@wa&>N!el=Q`lqH2iG&%#+~)e?2!3~w#Psw3BKzh4TDv^{J%2L4{_pSi z|KexhotD?`AYL|EY~Ek`iWO>zj4eN-uTfe6p^`|acUPHr)$f+Q`L&dlI7i`$E#h%H z!bBKIjR+13Wez`wjErJsWQv7C7~HNb1z_upP&r6rf1Vsko`|EQxK2r7Lrn#u zM(oovoTI0YfiQw0jLhdk+My6I6zT_Mkb^SZgGx9;B@&_1Z=q^Q&W8EqewdPew*CBO}Rb&&((XW#(XJfr42WnOX9C*chGJa{AZ`aBPKRY$Z6hrX}|L zc8-cKTm^kx<@4MyI4_i+7gogou3zxJj!@yCghaHY#63xyY{`%|DHH!|5>hw7k~eOt z-K3#ZK!wqWwVkrgKAu#F6@dPltItJUC-&=9dUPkas~YxDE+%S z`u^Dlnl1+K1`H)G8o9kRdfk2RMY!qb6-x#Nt57j(4MpqJKKlo14!6!bJalrjW_Enl z{x~H2ap{=z$gV3B)XnS3)6_bT)U+3#seutuL2mbhYQ6@mvIR$khcPgO1tY^k1Hxh} z!;MYD!;#@p$ndlZBr*xvzZLm9Dl(-#Dk35ZT@zh99$VOhYTt}gKNp9zdvgWyW?(B} z_D7<-cCsQkFAm0s!qaob#+IG^iHheqP1|_S^a_Ffr0+P#ht;O zp}~WnLrLmG-C4sa=A-%cqg|cjgS8~|{!$V?U12kWc{@XZeJgVKR_#sL`Z3p2^!?}0 z`Gv;$CH%s|;^O4+;_CX+>i+WD_vP&alJHpn=)cjGxG|XdSAmdL|2KdA+*(}U+Bn!* z`nJ3AM=tN4>>eKN{yy0|8rb{2x<858-&;KxNjsA$zkmK%pFdv29IxX3ZWJ8<-Y3bG zlY{Nw2l(H|KY#xm`~7R>_wWC-oAbX)OOiSM+kZ62!x0GDr|kbhDcJe&1EdQF{+m!p zC>GSb^X_cD{lA358s50xBV||Xe_tp#$Ujb0)%O&Fr_XrLMc4lo3gtgQs20^ot`6Y- z^592}p!@#_1@gFjcD<=7c~3$V#b2Qi@ap_S4bJ+5S^OV!{Lc})*>Jwo+kw*!M}N%m zFAe?u<|_F~_^xVR(c9TJXQ-ctgRAiAS;njepGXtVYp7i8lR6xj*K3t#&?SG1U0X z94|W`Ck#oBmDW2m$MYy(%tD%+nd6C%Q|A1v&dl++$Znb>$1`($a!15`G_38+9B)m` zjMiE_Gsn+)s55iC zrK(d*@tHXu`1JIc;O^Z?VflN1HBMF7m1$UBA;27`ZA_;{DOwW5)vBHJs zEQO71B_yF>L*+pd3SxJ|V|(OA=iCso*kXi z?@b3%|K6UNrGYTWQSi7Dn-QXzDBizH!AJt^wxUB)4|~#Oo2ku{!Vz?NnO4Uu`MKr( zt9eJQ@1!ngaY2^$8T&V1`J%c02!-dg^lNk6X3ONWQf zK|9lbH;J5Vx59jqDgD5{j_XV_%n-vEVhN;PE|+!=sg<4zpq>@;kx@`%S|GfV zvQs$|U(M&6nXL5r`NXhtg1Z@x6L=Y5N`?xK2ka~y5<-)$ckZ;B;d7MVa`?HY+)z(A zifs}fT6sK4Yi8SeLA{+d{?#SO`CSaL_4O+stKdCMRz$BrId=ytP0W7zI(#4IeJkSg zFIz_%2?WerXF22|L%e#o6p9T6wb`1J(FhZcs$6AF#IZ>QOQ_ zzY0+vBak^X=ydOX6T)#Lw1R=t!F43 z#y(eRL*qfyY}8+cqL#H)j^fd=wwI1CjL&)PG@8Q_CCSG^>ZX9YtfG`rPDibYl+=BI z^VkLOG&Sb#H$Le1ku&7B<1SpyLFmm1*u?FM74SlHPL*cFYYX z>BlpUi*r{IH17q^*~{GWjUG;}JK>a}kJq!XWX|2>54)b(g}vi3@?4nn(xscE?T3Q9 zY$amCc_+SEEE3GT>GSD=ccKQl*!Z(B0eRd#P%0yjJx(yvwjD!GJpTVDP}3$1ckj z&n|>rZ}`j^S#7s<_yAQp6PHL%wl0SdQ8Y|@&&lWQ{3x@F+U3NXyC+Lz>re)2$2fmp zX_{{?Bm2SK&bwtuIpJ4TnzSaEGoj$({P}??#cANRx6~=6df!b4JT~{MKk=bWR6vUD z8B*nAU@rHUz9T`1!$fx7GzX@y_q4Ye^ZL|WoZb|+RhD7%FVefIpRRmBMrF~BJfpTT zk~FwiTiN8S5Me*qFr_YH9R6JGl8&(x?q_*?Jzc$sLsREaONkz)N!;G+L#gm+pmEk_ zbmjTXS8|3~e1#vMxSD^7Gz&99WxQG7eDV0zIJf1(|Par+Nq} zIhFb|0tPoa*dKk1Gv;0sw>17#(&JM(oW~U_5V1z5*uDFvQ*(wh>P-oGxIPjgA(jR! zc=d>J#GA*&$0Me04PB7!n0k}k?e(~h{?p)^Q(wBoN7moojN2;S?K~abx@bq773U3o zZ`8ct76KZ8vQ%XrQ#h^)PNKXWeegEGgb+>JK53KVq2zwA0tWEd^&>(V^MkNwJ85&% zamR%*3f@X$td28wH<6m>tEG!`zX(($zwf-|lJ~X!{_ndxU7@ZKk93cmL`A5fRNAI%xM)bh`vR1)slU%wsRzt$$1xi>r(`8@sh3sA7HbCCw=V>D~g{( zZtHR4mAJiLzH0jZKCc$U+VnZT@cP$F8?C|%kdXSX>6<=Ft%&^Jf;8o3K^@LAs=Mru z_}@(VzQ|{EV{d@u$R|~ZUuuZ|*|(Y-Vl^kBCqH~Hki#cuq9@>#X;f|hNqj=$(({)A zTVm$>+c8b+81?5;qk*m+=WS*uHaV%M2bJMSMI-3=>ru5Knt)HaHA^+~a*AvRibxD5 z&f&dO@9(W8-`80B2U|&ZTw9I`uJ3-j&2ow}OZ;Af^yV{Z=9&$<@GXe-+3|fJg)udK zpCyfp0aV5>h-of!TCR}Zk4blnlgz%|2byo+o23@Yy}%S==QJ|j-;J*$#%~4Jx$Rw(cTUhfr|S1|e* zmldPA>kH*5dij$&(DlAvxQ12G1(h|FuBVqNv!L5$tk`O2F!wcm*+K?gR(T2^V*pBf zIp6E!XP=khei|At9FCq|yGia;=S(MM2y1_#UE@uGv0L8{zJuX!O}dnil<~*<1z?b` z#ve3?yx>eG4*lNr&xgG^dIaqy7j-g?kqg0(gojf^kD12jxv@$GF~8VaQ^K&xJ(8J6%5YnD93a z;e~HrHWR%H+u?6ao~CuFuepa2OkkHlF?zhZ(&M~41+m|l6wHtanm9V{dr?1$3JL(a zIUDouelKm4g47*e2`5uzkVy z5p`@aWl&wH$#NyC2p*?g2MGrNmQEd?UFh_jrFtXl6*;8#%H%wfBT^s>%SH7#W-cGJ z%x%&f`pg64Zsn*LwQN=b3g%YRzB&>rbXn!Su>;lMt9%yu4koTd)Klbv9m|(nS+!9G z+zCP`KeZHBJ0LgIFpzH!$=u<$@*#=&L(+UJDZ!yqRFKzvphQG+BEe`h&LlE2xt3K= z)0i8ARnNK3Jc=yUx{KfR% zxinU$*NdI+##TfEg~E)7ou^MPrw@VTm}{Jk|aIm5YOk{oT z#1NvT^2(~fF|{Ddw7~r|is8y+3XlODT~cH%S%45>$dxSiViWB|<*5%9vt>gNh{AKN zkX$Ef89zbRNsjr-0=KB5N+)U$wnDqf*c*>Z9&>|=dzh;ynIo=3?3^s3TGg9O89L+` zQfNzivDu!(2GH^^?U0vmeFzM{}Buu6I|bbSNz+CC^$l6vaFd!f=w=4{9ZvMRcu z(uUM>@5f1;rwzQHv7V(#U&_Vi3T;Kpd_};W_`EyEx#UU^@_3IT1ba{xjX}?yPAF}$yKEFweIZn3 zXSSGJ3KOJ{*%7Fo!qY@Q$@h6no77vM!7f^iV6ReYpyGk#e62U|r+f3x_%yYF>~X^@ zWBONL>*K93pdd`kPsj%B^H%<8y<02F&{cB_79&Iii*r~VH=N>Kk3FtoC z!yRFo=F_iD;MTnKpP<;UZr|9Oqh+B*Pnr!(>x-ee^K>8-A%6$kaM0_QLicghtkwfS zo%R+oz}^(#R4)zxC?V3&E86rfq1d|8H-rupR@xB#^P@lfV{QZRtz`W&pu!H?7%dlh zQrbKcgel4@aC4_i{g{f01A)yOin(hG^*^?Ws&tm-BO8Fbv-xH|bmzgv6hW9m!u5Cn z2*C!<&Z@VpZW!%ps;jPWfz_=1%$s|Xuqr1xGQ!LIvu;bWEK;sO)eLPJUEqfDUqhi^ ze}p*67b=+-_@Yc+6H4q%JIS-ldPU4_qKl?dWoi&bzNQ6eYD@)N>E=7LK-c{tT$p+o(Io8}>yxi;~a5)_)`m3Y_G~|UJ@qz)#V~Q$gdyA$9-Lq(3 zZ+8hlFSlMB{?KzL+!>^zTQEU4#wIw^U~p*7a!`PtMEe8F*kL+TzFrk zGqZ9Yca8&B#$kM#UhCPY;nDM0NulK2CgfDN+Zxe#UQuP3wzvW}oenPFZv<)!7oKax zl?d08SrYC=gaAcL3dAa|-kqB+na$Rn^*tu+=ze4Fn35*ecFp46MnY&aOfEXBQ)nAl zvtwUG_lh6YGE;SrnUAPS43+=vLAi5qeFW|YL8RqXH1+U6%W{ZBJ~Vc$DP5Tim4U8bpc=C@D_!( zMQ=3CN9A@RU_hZ?*bh^r^T;%mq{pb%`iX}7>3vbiW zZC0!I;P@}zO`(CnoY=Js5YW-*HJ9kZ&YfB2jt|?Qm3oU}(E!M~Cl)`NR^Qn`%KKLu z={u&_9-`8qJsDq@nq<=hh8TV?`zt~p^nWv6UEYEbM1Mo>h(bsDH<;5c0%xXnqRZuG zzL5Ih)dpZ90%XrUArKU+*UQ&`-kNQl`EVm1|K)whXZkhDrs}5E@xm-Wy21Htzwyo- zTTaiZyY<1mS9Y}}27(&!vIPT%7%Re*V3?n%DhxV8UfmSckP zO3j9DFN&L!DyS1Lx!c2Ch}zzX6X`uksF8^(kTC5=0on^klg)f8n8jDMEe^n5D=X(Y zOz(i6IV~L-Ex7qRUJWd|p$8SdT_E+az#wY>Qu$u8VvUEy&Pn_FqW&J=on1E(Fw3`$ z0EzO4r&FP_4&9Pvp4TcZxh6edf_W?UpH~2hienT~cs5s}r9_`ke$SI@wAu7k6zRq* z&;uL#j<@|qmIJ$^Rdu14rVKcC6r#tO2hbx*y)VJ}w2w-xw>zzS%8*X^O_PHe;KC&l z;D*H)%tnE*gi2T{M6t1mhXcYQZ}lCr)%6nVbV`Hw^*?NQSWsLJH8$%*HdJ?hD*N#S z;_Y+NW zBq}7c2&Kt)iuUK8%)g=G^u)%^E1De6N!*ghf97i@hQ@1)?JpN;m%YBr=+Js<#Q>G; zLYu0H=b(;J^_#U?=OD}~Io{S8y{wQzPdEAp?XBTo zEvm^5imrArM#aiS$EgcEeiAjn`P9SURb?|F^gFYid5_dcQUI?EtI9{Y$Ft!f={QV| z+&U%?SHtFpu}RTcA-Nv%FHG>B9z*ngE1T8wd%<3m&G^6JOp?8}rlXZbbI;2t`2|&X zk3cMP?MG9BvARB5?2+E`Be~(^)6J|~gTL-4`vfEoXK_4}J5KL|2{IcaL=VS|YQOrJ z8I4=MD;v_1dhye>agQZt-qU8x?@26wkgaCSK4TAxZ~Ss11R56|30?!Nsk-A@cG=To z`Bj$kvbyM^Va{F3)N-DB4WwRr@zDXimf(wx3y{l-x0>H@|E`^UJ{+gYXm~G5Gy1ij zazfYiyZqb%x4y7-&UcxCOM;!(W^eI$U_!S9oQki&(dP=Ud=UQ-j(nUI^CYx-^5X4> zpWR}y55fGik>ZxtZGHC*orJ0@(qiSA-$iuEIG7?OJ}odC>^N*rv;f7-~LX#4}Lss%|uCFhpHVJk%0ax|Z$WeftT; z<^8!2M1%K2uH-xvrD3#Ur*lrs6F+nqkVJ?Lx+4%+&mZRatTCP$7o}wDAb;`vP0fw% z8!PUw%uA?byf|NV z<@W-f6#=mHVcA37)6Zp_;Q#L4u1{kZJtE>RW6FF{-O!?MkRFAKdb?by-@-7Gb-5`_ z`SskJJ~WT$dXJ_yEirvu ziYKYxxYpuE^1;!@eUKD@x8{^~Re!Ic;62Q(uI5Cnb7B&A&ecG(z<1h)kLo)nf-;HouD)s%#a_4=*ChWK-@dhJ*%Hw^{8OM<6R#w@h7S^c_#S)wd1W5m zo!BF?0?*T{dGA#X;1_rtC^Vvp#1ILVWqj#=Q#xIWc4yEW2(2uD#9o(g-HDCA`x-Y>m zrs#Tlc*|G3(sA6$DRaAsYf;|F&*4#u70GnvwCacwWwJJkcD@%3H#KmWY;pYjEAgsc z%z0(~4QQcYuYTHl(c5mn!VN*HqbpgxTDL7Ea80DfhPMuk*5!=fPaXT=oxbU1#F*mV z>PJ`ave(tAf|RV@HcV5ZV;bx)l#(vE?24`~8q{U?RO@wT%=9b1=Vzb!b9R{NAIET2Mk-R76 ziD&mTjpfcRo+Cy2S?`Wu=fycqYmjpGvMMe5k?du2={pficRj$RV;qtwQ_JH5vKh`1l@t+-!1=nP2Sx#v^ z&r3=wF}GFRd0qIdWGe7S9t7@enW$H=Y9gu%21u~Zsu^9OTK_cgB^QK-(KW&dh)=iJ6~XJUqtDDPPZiE_C^3pD zF>$nfdli!~+&mz!bRn%d?YYv$G$l54>uu2%`YA>BDJ8CTrAsGD-0Lv3*)$b7w2Hj*JF)qz5{)W~>ngWTRA35GH%C6h#8g!jR8>#f6l_~n zomDjgRN-hPXshQ){EZRFXajmze)U3ejj~d(WquU=TsN3qOE22Bh?y5Tks5>%$ zwiau1M5{k(>=dw7ztgVnx~}dP&}tdb=EkAnA=U*->wI`k!`ocLCr{DES;H?{^edW^pUJj@&(-mW|Wx+2cs9-an|x{D1( z!%w4e@PH|en05GT^Dg&1W}6duyjZtmBm9ky=35>0SaZ#!fNpbD&Ez!ARMn0|v}PJk zQwOa1l@*?TqM4Mu1nKyNNcV}Yd7MwZ`)`$t!sa3 zFZ_6--O8cEKBwKLpwmtXCoo~-bac7`bTnvmuxYr1ueUBt-Tts9f!k;P9NJ#0MKxha z^A)7qquS|>3A+Q6@mLPM|CIVG>xFajF+Q+9CmLQG4Asy`f&oP+OfnSgl<*a&dpcru z0oFnbZDa2aQ1#g+r*}lO>xYry0gA%9cIJ9iAacsfl(bMpJP}Bx571==fQT0cVN@J` z!K|T?9Ks0cN}+p22ul51YAfM9LIeed^0t0B|B0Ry1%fxnK1WlE+;y78J@#A45A$uE`y;JRh>JgW-W9Ci6NF z(eSHzodzTNKpDynuYOl63XV!LAxD(YHU%#z>URRw?UrCthg+Iu!Bb0aa+Pfgc9IGC z%aDWx`34)c*hH{K#PCf_m}q4X8-m4~J5<62zse&Gj#0K31}vfVX$j%}MN)EL$apFt13Q$WgkW|aasd#vWmd3^ZoX?J zxlVc{eF$Uw(BoR1|~Y#Zt+<9j@c1V6P;T zx8o8mBEO3#2u)Wd%T7hHpxS*encsIfg2`pvDf9U9m=YKLlC0Aj7B0MO(;&WI?A}wg7rF>gQA;zg3xTSCT7a z8L@Md!rZmyAN<@$P(z{lF;kEU1GX1tAlP`<^q106fcFd2a~J>*QLm(FU@IVqoO`P5 z7Qp0f@@*`FQZ3@)w&{bSDT;dlMH91NfeCdB(^EF60aa0upoxWfiz%%id6&0YaMn(Xs%nX|gKnWYx3?HOJg}LH`XtPW?goE9!kUqDj&s9>anHw=!03OJEr6Z*J zEClClNWD*Q!+1}t>mzQm22)8=aS~0v?@=Gvk+V&c(W@9!-v@MF=dXQhwy!#2$4gCC z8~PMa7F{+dl6CK=!Zefapb*yl*TTcrUx1}4E1JrFUcJHNUx)`AR^GpWWP(-{_Q;@n zRy6Q1E6glMr^$d4C1rX9ot{Cq%Q%hSw^N!KD>}We;y|DdYS_!7Z|sZjKLihwM<861=W}Ahj-xrqo?5?^q&TN<=<|b|6K<#_ z9?6tpDWo<|mlZtp0T13(w&^EZnxX(^nRRd?RDBk>vt;B@rjRl!-w)iiFJ@MMomVz` zC{biV<2PC9O?@C9((x7~bol+g9>_ey(xiN0+|Qvl-yu@}p=E#R!?9^P#R#SwORlC1 zcLZ(Dx%WRy#DlPul-$$&!uo6|{ZsCZb1@CR^@1C8zBLoDK&r*sd8f~C_5+|V zXw2^~fe9hHhXA^XU=de`kig&-?|#T3fR{V?3X$B?Vo?M=35MHxiQ~Br^~ySymc4?H zr|juX41QRB^&wEja{(UZPb0Y|q+t&HJWD=43q0k6`H4#hYRHZlJ1P^W+6=wYF})%Q ze6i&nZoz>`3$kV|`2*eg9lU;+IwCNCscdt#VkX#1-=G5Xm6J$LRb<26VM7bDR)kn_ z9}Gs#Fp6?Bl71&*AK+978w7>LYoI2{BFIsPvB$OmUiaWDlK0GOH{=&>3VW+NYM5md z77Qp?b?$w;h}EM?4#K(Iv2=7X!LDRHal&R$(Zlt92$Ma5$VaZW(Ygk^3m~b=P*n=S z_pxobdx%SZNVSeTU9m1n2p4X!-=US6ZhU)p zS&?=lkea@1DazHk-Dh^3;6PazOc}%`_it z-xfj7)-Ujr?bDJnviMDk!dQEX>!yOYBMKHBPU$Hv6cIf>tAR}fj^6;V6-B`<3(1)+ zVXxKO_FQDm55KTHJeeX_4qscWVYt0Wan&k_4ip+>u`QTn@fKrNcOTG3nygT!;z^dW zNYnUD+dWt37d}pkFn8)oPYRbE-NK;Eq5kq1OHY{jr>21n(j^0!y`$QGHdH7NDkk2H(1|+E(WD}ME<0oym!&F??afQ;GQJBbv3lb8 zaER}M2zE*_*|IEbJ@5+ttRj-!a&hAoy&gp zzS6U*4wq0huNJu`dAc#e`QvB$Lr?q^+iy|-`kARrbsGj~+o*S_43C(V8-x#X#h%cK z(>qzEWU_^Iz6_|Y{s^U-YNie_jIDQfyfs?cf0(c(bg#kiqRD#biNFgQM?`qb6}!tW zI;Wqve$n1Vz6`%da5uk07FclpcK~nT(n>;g?W6%$%n_xTmOjpJSMA%Uz;n(>4S49p ze2lC9O})p|ntqhC9Q0o4Ui3-QWu)3C$)DM{bK!Q*P+|XG5pI;iU?nF zYDO`~ZSJ;E+6!FQG~78=yud<+VkS5aj8~T2i`8X@+^Q&Ejd-!gyZk)~BF0tDE4u=? zWNC*X^y59j{xmt?-Sw3{A$&^jP}tSFNG6TfX)vJ6>i*@CBEv$%GN%KPF|=u&$41Gv zNvFH!+d%8p1F^{(r|~M6wL|eKjK>leN9t2P!+iUd-Ho-QD}+3|Rd2GCpQMvPjQj3^p2Z_&peq3F~=V-i}f%g zU3jFOR1a*Q|D8)ud!DzLqU^#mgB!N_H>EXg4X+uqEG$0j&EwVNehrV0O4BcwM#-gP z<6~hC5^`}eg^r#>sR+|{%jef?9SfgjnI`n!E0rmJ>|4)~+AGyHPaer%4;z870pWZo zAqq+!XxTZds+KbF^}W{IJbDS1QAgu6u6yYAB4pe4?Owdhjs{ef1)fnAX?kSDe>Ub)KW7QUQDYH$mG$ z{W5X^3@y2zMcR7L&3aX`4-p`zQVAo!zC74c7r5L4V5n+jiezNm2|lH`ypU?3 zE+?4FvG=|^BXz!MVU%t`=^I$G1`w4z4`EB-7>Q}v6xrYV)H6-=N?3=tQp$Z21H6Lx zWnJwZt5&dz#e;-*uuulatLs$Z#B8$e^(=!H7XQ02X;E^89yrxCAvBx^+_(dxYoVRr zehn z?PK+RM8r+nDxPv;%N~`PJ4^7GI<{ z4<%>bcb0B^OPDXN4baZoMsAZNsYp3s7LwHpYo0AL1!(hbN~%B|J3^mIazk4tL+CKx z07~dAWL}OVi`n5;r?-To&GRl9AdE&`2f*6Oir@|Hq_P`P2DBwpt)UK^dy7NpqX3u2 zqz6CG4dR%bN*@8zufoDYRT%TNO*p;qQuJ)r6r69e$b};$>8$m6*%GKGvK$(qCA{QC zh!#m!t0*2}W!`B(D3lpimG+2I#de1|%6|;qN#z2N0nML7+t(aQ%|7k3>0*G-M)Gey zip+x{Wz-oWME9*Y(Jfi{PAF*qQ7rd(ueBTW;Jn;}zEcVaCa*KO3kHJQ1Vf*OQ$4$k zG9~Czym4k7OEUm)hC=B%CfMZDh#l7$rKM&cfe%=Wh1A*RpB7-L#4t$|`Arl|w<>Mx zrHi9(_%H@mEq4NHvm%v4p^*#hnS!JnWyRV&WR3k(Khb8BfoWB4 zM|_2{0V1P6XmfVvatlf$T7A})a_X_FWFtkFFZM@<1J)NQLT6)#Qp)Y7w=<-Bw__hJ zZ(L}c%H*E<0_Llt2wlXd-M|TeLS2F$mahwWmh<#Bhg+henc6G^iUQ1%))4wa&<5{y`Oy%S+mys32r`G|SK zIYK86rnWX6Ow{AZ^nSB1%{(68e~`yaL-+96521e3Tm)*!c_n8D6-?BwYEwc=DYuHC z=6TPjTz55sH;BDqyuc>#BYbjdXEG6%i@{St(f8Ktv>cv%lF|^`k#zMm6g$ogXla0)m2O@B(O5J=$hrOU|1VV zvwN6S+9P_m;iP*5@mdJH&l)nkJgs^Z?D=LHJwx;DRDe3L7-aQO~Z_uXdc#A9(^?j~4uBLnwTavwy(i@R?HDgcVyUbesKww5i`uNW!C8qzu z(0Rv0;l^?N2JUdq*;{9yefCUuXU~r8)!8FuOC_B>LUza|o5&35oIOL4Q8_cKLMr+x zKYu^3*YnTw$Mbx?&-?TFaCb+@D3-JEX?MzOk0nPcR@Ud=gygHt<@PD2z*BckgSl~0 z|NN`9rG06A?!T|nYQJxkx@XmTU!&xXQiI!VeyfS@g^mtJbJ0}Ra^by&zJKlh-V6sW z*YxqR^6$knkJ258Uj3lEkzxL6v=Juu;cre)Z*tU|ReKYUcfBZVpYCuJ_af4y&A%8o!z)KR(!Z>o!JJ<2CZ?4C-L-w6bG32WH?(VG%_W&^zMv($|>MrpYiMhLKEf|2Qr#(oRhwo_E&Jc1Dz1$iM;DnY3ZE@_LzqYRTJ zZxV>s5`lV0tqFoJV$9nI1PR!YQ6U87g2apg33qI0uv?ufr%TupR!GwUh z76EVy#>}t~a!O)pF1&UejmQR0OaUbdCp1c<5sI7mwRARU6axY%$q$#n_iHfsm*Y3} ztg%z+!Z>Cswe)^o1F$TjpZ&C-p`l!YT%p(&a|HoJ<_J%RfO&d1CUWQn5LgLEAkC;F zL^#Ui`KFPKky$r`_Hq;+_X z+OrXyZodfEosQGMSMNV8V_fx0s<1N-$?n z)JHEI5lBa{?aJ8}Ty&=9Mg~m2@7=#C9{Z%++~OFFE(scK1!Wi%wZ{#7G?N3x=wfST z+&{#2$6)&1A1-^b-}%U%3zg(0Q3FuiXv{?F<9VgGvHae}Mt~Q*F=!~mj|P-bJb!GT zb{ZX)nU{Y*eLyIpzwf#EQ_)E_k9ihhlW(k|@Kem197f7}5{M?T+u|O^4M+oU6CT6| zaEmli;3z9#zpLcQp3#^bQm9~pn46}4zk*Je1opuU<B3(!W_kh=;x?RQP;#dGhl`? za_r|Z6R)bt9@!v76avt2jpj*Ld`xw&W6x+kYn!o}4+ep#?-1P<7Ox*qJbx)>S({d>06ew zbs$CW@$LP-y7aR3bWU6Hs?}t#eZ5K4-sj2c597CAnQW*M`q_zI2nvOOD}T`KLld&v zIvcgJTQ_dz^LIUs=>Bz;I9m;8$y$+j(d!CKfeNZZ|imvyJx~Oj#&A?1yu)JR1 zVju6U?=^3xsdo&Z0Jy70jk!l2jPb@aqwhuIeV^cNXZgaeAPd2R5-$9WOGY~tcLZsg zqpWA^rC&#J`H3aMEnU=!mgU=QjoMvkKoviUk+q5$K<<;C>F2u6V1QerZqi1|zO?|H z%N>lnR*Wlt1D*m9cw(obHthn2J)82~sGq7%yDA!ZR^Y$)S4tt;Sa@4v8Ys*_RXd_r zKC7BKy1m!EK(svWKN;s03X)VE|0ZSeRe;t$lX4x5N=<;1V3-34$`P#9-&-{gK$Acs zF#3}1B|#JKxyj6z`+Y79499c6%9sf&3%PGe>Ud8Y&5I|>Go|)tyjb2{x-$|4=KYM0 zzfPVsTz=5yKEI)7d2aUQpZ5#<*EJY)AQ;9reSd~Z`v^!Ou}b2szp~AYzwP4^;*$i( z%E@uv&9YC*=9f*;(22IEZD}Hj$A&dS6u7=d!UeDFsljZ7w9ABA-+TZ4s2x7z6P4?^ zJB??JRdLi#xf)x5j#W)(4+xw+%{0--b79c~uSc-^|6N!-W0!g{p=Kf=^@O~_ndZAD z-_a5z_)gs1k}$Hg$N{%uv)-63l@}?Y0*tJvIKLE|4%+psJEdtYdA=X3YU+bMHV9zf z3Rz>MafO$&%ikCizfPs9QQ?~k5=IHB%eJbhT*Uh5%D*tc37U*ciUq5?Ddb4Myas7I z@NLC#C@x=Cgor6}GPmJW6kFulwDnIK1=@6MPOu6ECw6UmH?HXVx9MLCS&D0(k5n{F z;L&-iXryniU#)2TV%e}$(d1&u=rSz%!=T*nMdJ@AdLL|*-9o}Y)|x>=3mA;bc*o_W zo~<+JB)u?3JNX1v*QuJ{r(9pR=WCsc}MLd+OsuuVYgD&N5le2L6Sz zXmU5yL>4^8G`XC^`;abH=9E{KHA=`NkbayoVSW5i5j!*=4IA}N3{-O9IY~WilPrpM zLIuf)>N9!qXKEpFu(db4vTSIoD|JA7`KbTGQ-6H~x}}E&VE& z0!Kx0VHA>-?mj~02LNN_Z_uW^8L(*8{jDg} zQ!1#9X5d`DxiM;VYok@b03?i2eN}kT`Tadsrmcx<$8;d#OZniwuIj$(Fa}bjzxsR>CU1^qmv{0LW8bvh+hvjG}MhoiT!1yS*EeU?k zNN6f|TJUGs+0a;2D{d|0Iye(w_CQW;qKG-#zup)BJ`k*|>Or_5S1E11+6cZ3S7xThOrKe`Udq}?%h@D~&n8NQwJ@1;QvPysJ%f?9+4FVWT zi$@8dq$}YV2CC@quKu*lKrREy*!cB{md(|9z;f))6%$P!=IEg-OdwS(60pN4-aE+` zJsMMlJ_pjo(bI5}f4r=dU?nYuJ7YJ;2lRU<-<<;wd4;R?*v~)x-oq?jzDevZv6gi~6X$P146ZFLNi;I#Ore=$Lu z0yA5~Fg6R6VY`&jS*>2?3Stis>4B<`4j*VEB2@@AYXXFA(f2gw#HWnLta%fUyh^BS zr<@(Kmti>CXBP`8ou^PZw#j~~Gx`d)t;au0j3dN&L?>&Gbn44UW>Ye`*!G3DgpbAb zanzU!3`TxvW@n&}`6}WL)ajR^+W)8H%|{Df-8B={{Dc5lA7XXj?a!Lm`Mzhr0_gag-H5;H@FbgwR--FRR9DUw~u}ZxX^vGKz z@L-QW%zfS-x&KKc)FN7nHT$qg0@^Q6kxTgYsezh&d`>#OgHI1Zu)wo_nnv*@(x}bZ z>dUW{AVErqGTf$791_Lo7!H=KGPo-+v9+6#{t2OlI?H?T;SM89rpanqaCOFpNt{u& zFGc&tMIu|Fy4O``r_%IE6;=$!Jl*Kw{X{4u4dcaQ>}E)FEmxxMnKB#4xbsSrhDSXq7>hA#=s4VxwmBK z#%)a`huiE?X`WiAd*X`s7a91n4~$3AcE>jinrfltyCAt80wVKeL-ON+mtATZqFQM8 z*$Z77HegF*Cp6mcv9dE&Y<8eT!4PpuiYl7~DQ;PGOernrQ53z;A4~=G7vS8&6a#8R_A(>v?||- zdjoxmlj!Snx6|k2(`ih$A=;&texXn)lc5}Xn&k+KBk3an(Qa9Q9W!V?8+ zqLAyXA%TDu9I`nMc!!NShEw@eC!w6_YcI!Y#LrJpS0n#6w&rcmEm3u=$XaY)tj4mL z8DxDAXDEf=xFc6VlxHs&c&e{C6BcC@@JbM1k!duRrw2!Nrh`bA0*`U@??7YSaTkEu z@8NB+t(?D{6pyD`b5A^7EIML1v*>TAaae{Re6|auH`{B=?q!g{jVI&z9#5U({&f0x zhj{G}1i47eT(e7ZLamWwr8GB?S(t*jY}Kv8=8=C)f}SXpppT4)UE*cw+#;$M#@Vd1 zo$sfHp|wSBfDVnKU%6IXmL~}xT0hC9aVgN&cD+d5aHeWR`BWZ?a&SiDYgUGh}=l+Ekqb7;%{q=jZ zL}Xaq(?jtrC46b(%}%kMUAGmcD|GR(#$W#1YSmw{sq8ChW_NmPCMV?N{{lc%!i@fb zBgI2MewVsbZa{fL+yK-a`t%iGeOi>dOGHK>V~6;27~H?4hLPJyF9M}>s0c2 z=&V?p17IfV0d>=bwzdNwyw|ylU+IZyZIQ1>#i+E-l&EMiH)wSYa68XE4rNX(_~iIS zQMN4pMyWg7oaP=Ae3_1gt}QJTRgq*)H4-#<$|alGqOe1ZXXevRovTa}b~`U)*tONy z_{{VqM8c^bW)0`wW=by}i<3kAs>N0f+g=k&u!s!98HiID+AcV8qm!Hl#?H)H`R_MH zbzAkd=4jFiCxujl%y|q8kF$$NroQ2`SlyRVtP&AP>g+CHY6LK_{QZ{9y(QzD$E13t}>g%FVt=;zgjZ&k7OxaJ9k945^ zj+%@8jc1=(t9icGs0AogZ;bW+?!9G{2ZV93@jwqVn#MS{7RDSSBg*Ks{Ru;zy05`;w*bnpLAM)zk?%@ zcCteJp`^pgY?4DIsJk|OIPgvj-B->5)c_P=2iI-wVomuM-DRSDAhmsg%5-ZcO!WzB*+QvI(h)#PxN83fs7j$toBY0LhMWF4wY z2{UFJ$$H6_KGk*PvSD2u(FWD-1-BfPrw?E332%)Wod24P=w;EEv@MSAa?Q&!75XMQV zu_Q6oYCC`58FsR6rVcQ5#bwoKPe=vq6e&>{{Gf+NL0`NJLz{U_Q86-qG?On!8Hj_@ zXt-1}*bZ}_FSF_-arr2b*N;H&Idkm5I>UMqif~1%QdmU)MDz$6xXoT6kV;q9;%IvZ zCH$I;#E3+IW0M=N4myrYnDE$sDH1WRGy^ z4l7@tj5kn;zFK?-j|FSxf0NB7COaPqE(QZnsj1BQ^)$HGpy^S9;cFSzz9~Syh>=Y? zJlN3td`jSn&zs}Ple`bINtVyZtoD{jWK_;pQR(!?wBh=KWn&m!amcd@{P-6-ue*H>>iY8xs zP2(^(6^XFcY+h0veNP8#3CTcTM1wRCI`RcjE)h*v<6O!Zqys7RF$##_TZA@)n`xfC z9{8RKJtxwa#y-E|E|B_x)A=8S8nZ(|A_NkyOiDu;l#mG4VA^jOZ(Zk)9??)b9kZ}V zUm9wtf?+`3`7lzB;P<5SKi<_%*_7i&!4fR@8KQ1w+LO~C&oo~EZY*1b0>IyIG zkBmZQ4{G6YOugIV>y6Sgn3h3 z6*9}^|4Hc^;EaT0pn@p-8c}oiSg{CK;x9L=w(H_GWZu$f3qrKS@)~;^6%Y=V5Jd_> z#rW`1FdA*^6EY{@35XeawYyx;z(fd99!;F~H9M3nz0GHfyB1ACB3vKi$)dx8tUm61 z%Vgs`GAnHcGM)@L>PGSPpIy=J)LuN7dM$wD{JQsF@wn&1`kbLIc6deh` z)=}wQjF!=XFZC=;db*4^9JojaxbuF7aif&QDj?V>15{H<7v-8EPZF8imYM_N8b-7d z*Et^x!Y*bc&CH|zq=@s6(SD{dSr2l+!3>qrVjURfnkT%?7`dh@pm*7a<(unR1Ol)ud=RRMET9HNJciJQd0t^@x}yhjQ|Q)qy* z0{?OmmhLSQgdncRnWpLAvwrQ@6*CDIzV%fVxl#4po(T5TY2oQWeij5iRA#o?bPYV+ z45LAk7UNj)TMo$Qz}#uAhCB4>I4k?-j01QX@8=G=!*ah!Qb9V}dYecl!5e*)fQy$~ zHdN+@DG(veGGGAKcKNoCj0LoR4iBTsXT2?F9!vYn-8y$$QsEHHT@FbS5zN5JAh+xb zbeR$@3?e-cGCTLaQ6yS3k<$laY$d&3Osom zoQ6uHDFaGjGnJ`Cgh{Lc{V?Tq!x`5M8LuB8sURvZp=m~8sNg>Y0G5LFASdP@PKass1GbkY4V*I+O=gpC!6_Q&(8Xd5L~d4z~~Y>RRXZ!aB}hNZZ88T4~i z>O(bXIMQWu{~^7j-4N_;SdMZa)f)SyAzEG+x7KPMACFBq^jbXRy*TltF!MvgFyaQ+mAB6Xo!N3+FbIX?Sja+Z^pmyHH84IDf*)>#)l*h zg9fV@vV|Q6C_|wOcxRCMk}Ic6IBL9EDV{%SOX1$+`oYl^aC zI2f8n{^20Ncg6guLJR)7k2 zdt$@r=ub}%dUwe&kJW|bk3hDd=(Va2@6=qCte5o{zt{u7Hce^P0rVdNh9vA5Z2~zs zYMGw~Uf~GxPYw`z8YKCliuXg1f=#fjZ;;A|;A?bOPQKml78XI*W}3&PFwfN0?3KqVzG7+hFyNx3$UgC_WIcW zD)PBP_T)W{0nT#z2mS(ge@6EL$~+TOcrn0x+CmXeCY7eEScW;&npB4NP+>6~k#SFT z>IFUc6UAUyV0^>%5RBASu*k_%h0$+s{?&8p#_%l?X1YC06aase8AJm{7_JS-GgB1c zs!@h+fpo-x^Z|L-;WRUqNbS=ibQFj(e7*F^^$Yd{Ey}Pp|0OqF=5`&Sa{Jf4OaOf> z@_r$J9&=|ho)Yz^9`=)fzB8*3+Z326#R&lV?JJ4%Cn_Ej{3liXt5laGPQ@${Ra?chs zSEHfL9X!p%kL&{JSJpFF@^}%aM;G^(v_AH;+)#M~HdpO`mG%h*!nE#wsREV8h58+Z*SeVsY0n7RTAeYODfya*`a*NP@~lX>gfF zd%Jh$4SJ@;;jUtvZBc8%GyWuclWm6hQnwId6&I0_f0y>pV@6bTLw{B5-;IFDZiTu6 z^KJh?8BF6dL1tv8wjr?TqGXq+!;WV$%5~g+2il`Bu*UP5!B3<64X?*-WkC(eHU;q? z0Rdk00Ts=kfGhz-$6i}@i*3+9(dcnZ3N^095Vu1a)?~i#&KoEA$NXBID!Vw5{$#sR z$s6d3r8}?z7IxX?b<5LH(8E!%4vgGxHz0Q_ty)qk-SVuByL)9!UIqz)M!SB)+5Ee! z@Nd1LRvA{4K!U2un-d-=AfiPN=_Bv_;|$BKn!0D z{sK#YqVAK?(JdwZGAO`}od@omNLs3M+2Sb)3sI9SRor2P>vA$T(H0s@xjToG)oIWR zv48!-WM|y(_JtsUbFdo;2lR?7P!Xc~s4p!h6&0^*nmb46AA;D!$&lq0aHZE~fm-22&p#F?QXmxRG2mvO)xiLdg~+e%k%xY=-40Mu1gnc4`R7K z2QIBgOm~v0299a7-F3U{MG{DV&D42cYKlWaI!usSxu1_J*E0&rdB`oD;>-$z>-5cY z1riJXPxnXNK0VXZ18bqjoO#AKWqGxRiwR~1|V!k0Tq_cZ#oX)I`nG_U#C0ZwH7DuBwc4n+>J z)(Y$Ti|zX)SGp)v__{{{levpdJCwO6MgDM^hv1?qQatiWjr+6BGsci8D8FC}eJT9D zM(!XGp(vEZ(^MFjRPFw0qtkw8IZK}DyoL?)h^`R*N0NhDeNp>wZ|GLWc?f#0_kac* zl$h|?=x4>+wk$95r+Q)IgnCR7QcU@@Q{lzt&t5hXpyTYNkrEB!)pft_Yrf4f3nUpX?6AjA^#SOy`InK0^_2AvTo)- zvb&F5JJj5xXb92#r(k$opSC*yUd|`K%FB)d<5qb8MLRO%$fnPt0w^PA!t3!?at%wB z#@EvRSTgS_-lIxX&>QxpQM+fhWu652{)%7Ry_yD9@zZPh1L}(7w{WG;9EWe-JZ0|) zEAqKf*Q>VKk-3>;?;^yt9eM*%bn96yH$pkJIP^B35Z6bPv&Jt1K=4yf6xAn@ig-9* z|J}Fc(h+%g>{R3EKNv>nXCP%U5JeQX!7Puw4;KU7187jG!CfSaeTXfS3ppEgacem{ zPsXwO`ZLv|O`oQZ^3QZ0b6-tXtetyq@=X09ol@QVTFZL-*U3ut3yqFF_y5uYUt^-1++-421%Ay@DIq4G83+Sz@t@TKV=>kCrL;=8c#pI(QY9&JuMyY{4b*LCEY zK=mWWYklV@6<=1~Jh}Gf-`}0b(*ED_9-K265Ta=K6A96DGNY8sn79vlL$V$DlFk~q)xrljDW1}I;)uNvyxTG%D2X-};NZwhqR+92lkv-N8$VrW=xmzb`6NYc-i01<60HT)tfv-8}Cx5q(p zVLqgcZYEt1E+wr>qi4oWzo!5%5wV6;clZ;SxM>5FIC28Bg=$P&7Y);&E(6AM9h1UZ zW2N?MwEN2j=W}Xq*VQEPRGQ6;dDK=(?B2wisf(@E(nV((2}S|r_Z#ASLDQH$7?X|~ zg~*b^ia4(=PH19-d_mYt45h&%OnfSDf1i|Zs8Rm<$1ib-%jSmkyx{!Gg$nH84Bqkj z@6uZC11tA$NNlg+*9xl3u%MUzpLf4$tWq_5Y1Gb)KJVFsv%c`DXNY)FPbb^E8H2#7 zuns_-y;J1b^}(i!!zY!JFYZs3dkQ=5_zvr*zF*U);rO_=&Rk@G?T6>~4m@UFi`bB# zRGLgNL)%;eslv)ECsPP&TSBY4xI*(##qMbt7_5_S(FWmVEt^7J+aQc+cQ2akPH>N& zI%HVZ>WD_lRKf+U)=Q!4s<+B7yBCD|V))~(pU_{_^mjF?ZWxuW`(d*H zTCZqwg6|BoJ8YEIe}NFwrd4(FTxkdu(3XB`Q=abWE8pW4=n!-!ug&_AN5?U06;J=+ zr=CQR0GyqZSAS~s6RzT=GmPI(d`Yeu7?wC_UVA{T3RpGk+YfhreIh;R=PgNGPQKf_ z`3V-t5gwyF=tA>P2}dgy7!PwVYX=6H+8Ezj)`*nT@M^yekUT6MG)pA^s7zL4{9#yc z(RIa82PQI}t}{}MNxx&zfBnIZ)vKVx25bZXoOzlra$E@%F~C70lR21k4ig1V#jkUq zW4YkXYEBOYAUa*z8Z#uKN@WVo8cK)r%#%n+$3k?P!56Zc6e?}bKmoJfIrh`spb6|7)@WWD|QD@{7F7Jj9`DC7XZ8{G&Q zy~XIxD#-LDF^Lg%LrhjoB{nU8o5-uuw?K!>8-2{8tXH#0|DHV&lJ`booXYhqbnZ4E1H^C+z~G zQmiB*rt2%%0qM?CzXiAG8*u7v#!<_V43OV^GlO_Z`jvN0s89k3_0tW2#@q;~hBnEB zMO5sC0XQt&1+=zkC9BW^utyPcc<_T90~e~pv3pI-+BL4@_laoE@sO(QKwDzD_B&4Y zq4=%nr5xWefN_^L;p)7FfFLquUF~tM6=$OCw75}~dV4?|{swOHu(7*Y+ir)ltv}=P zn9Q&aVjEnxZdZIp*4zulLy?=B;vysMiyeP}>k zn2F7fUxDYYLpp4wMC~#GXajUl?VA_v3o|SB&YyQSXIh}STOnlD;uO=8A9;zEr&^lr zwAVYAF_^+NFZ=O7u01qBC;U=` zdh<)T@jOn@v~y)=A?WC_l_m;saE+)pF<-%iF{kvCaT^0Sch{YEMRjtns-gOwB&s@z|sy z-0rB`uhuvX?zg5uRTHe}B8GN;N`0hPyabE~l z0W0F2jzMb@KD^_;Y}Q;HC?)qV=|5G4T5{*h(gKtA1eYGDeZTwu#%-s6TdLeY0~$I* z-s*C`9bxzydhs9@3&m~ScPCpCsvizQ{Js-uVd=nRq?0IMLV@QBN)db*AsWu(GxI+^Aqf}>xUtS2{1p!cqX8TN)b~^nv28$DDTF#*kKXR)>rFQZftmqnff&7b7%7nb zZr!LRJex>EE`1p$^sax8sv`kS4OTJ`ZWR2$_|Dbe&Tukc_VV4!&gvxRUM!Vo{Aq3ZiDRcAo(zdRjE-GYxSRxGmlI zlk-sB5UATM#=gV^V1u`(>xS$C;Ry9VHP7D0KjC8M>QUo+7Qmn~OKT{=+#tX|9md&D z(d~OL_9Y$7DOdPnO>yi@vWzSu?ZQxz!2&De7D%#_c2+fePe_6C|Sn@2W=qrL@CW-r)>*7XlAiLBNyQJJD z-p^z?2cg+3{Q@ZYT?@ksa6ppTN7mVab$laa?lW!Xm%3Y#DGhx07p<_SkOKxg?LHo0y&-1y-i{@@X5@K25GQ?XP*0 zUt6?STS8Y?W+Z^Ve`8LduG*e0*SFS!x%Rg?b7OMd-IuT-{6z(yE3CbnuJaNTPppP=lzOptkmv(wiMsGL!%czeP5hn8D0gvsCrrZ-`c!`AP6K%iXDsk%1k^R=o zEs#YNx0(a%MzTPkytavC`wjYL4P!;%jCCLD{RBn8ldTJQ9)(H`2`C8ARY1a4o56P! zG{6WzG+xGdsY7vtszC?4U#blTP+QLUNY%%F1)Et?41oa6?+98GpGU}Bt(Ns&kLh1n zKXXqJ%uLjUJ#Qy6lL%5A_OFxy(Fl8HB&-8z)O|=be#nrhL@&l;A0a{gc!L%@;ZcA? z$F|#+tcboL+UD0wUuMpnjds1>?{;6?>5ak{*zIUq5CK|1u#1tukiIVh80&a#VC+FV314xL(JN(mgaOwe zX^UoruGE*PwX}TWc_Sc2Mt8L?n@5VRSqb?Bc> zZ9qW8eq+z)%+9D(DPseBfIb#phU9!p#_-l84f1u^kc=(a%KByWKHO+5+f&2x0m{hX zoWTj!S}tT1t^~jkZQF??Or zpz-{co+);Cq5XLMi-=ZZg5103h)IbUBFU zMRWgX)Tj=3iAs=|TOFT4V9O07iOw<(5ANBsk29~0MQo!*WO`ou%!=R5e4jcens&@u zVv&Txii_C^ruu-N-s>8jg$n(+(6!U!%9HOpQWKR}VRd*7ziIiJ$Eniu@4Iu}_nh>S znHb67hka5(+V3N{^0rtL5y>G+Qk%${y(r0WT%NgHLeVRR$Z%0gdANu)`#;>gRc>yr zy{GE&9NKAK;={u42$$>6#*-fiC@0HtZ7?)bSX3%`@Y=vq1q9ci(l-jk9>H0G2a}o+ zpGvFm79G5+kU^ zqEJB6q7vv{CVV1E!$QQtSJq(v-eYdjFi%uyz(ZEJ2p^vcQWuSV9{d4MB|x%+A!)(} z8c6y)q?nQdo#LzL9pr_4H<{+GARG@?F;7}_b6SnYu%Ecmy4+B|`&f}hj?RWJbD2+3 z*^T}hk#2lW?O6NeUk3Wl81|n<&rTaxYg;tAg`rUcF&+37rs-7<%Ie5hz@7iDLeWZ* zC@^#1Qtroob?j~A#};`@_P6+OumjBepOKd$)uWI|;pfm7^RnKQdHXP66vkEiCx>|~ zfPpB_PYl9s0^$!XUY%?S>)8VVK{j)ewK^8W*$_oLNSsEbr8_iu$LJovUaTecUmYN4 zfKK8s8qQE*QxxrL8)7m5aPuek_W%PW%r+?o%8J+3+f)MqgcN_7#W({VgH0fd91i%L zM<>Rlt?>Ex7r@7+u@9(pO%!3b-s`Oe7?_dpiCbT6HpNBMa?JATdkv+cuXL>&I%UodA3<<*EgVS5)IhiLmkf?6s?>>wjPW=nsm zPAg%v|E>6pWAr83$|`p*aCOdqlvSM_Vnow*^LsjNp-lnNrPI2bpp@ZUJLcTW_J|$g zw3>^*8FybNPWt0}CCT4flq#u9BUysIN7@I=Df`um5T@vXqGrb2JBJwT@q;RI?!3>86pCmgRVofs-7f*hZQV=g1B5AERpBiqV9A=u=+0rEc&eUO2Etm@A?>go`^}z0~241KT&#$ zF(v2m*Q76ocKw@`B^Itp63+Mmz?CP-P|cL!>%Wf+H}_@Q@A|`6!ioV$-}t)2JZ)9) z{kW)!l8S!P5Uz^f{`4ZwJFk=l6@ZVC^V%7`S8*GU2>#wDm;O9svjhn?^`x{0PUx#e zX-XsFGm4%fr!);%Rq1i6WjYCP-dA@J3{gADo)I=DyBfLsX7c9)mJ}6+h|&d%0AN}r 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 z%0AWX9(Jj-+Hy&(Ivx7j^Q6Ijj>J>EL!fCGq|2*)?$LrLLih|i+aQ=CEn}%_>TVRP zePmR7idGb)ITX<)3fCVe>}f1G*ZGv1FC>MpP%tjhc6=dP@*?3HeRP6mzl!QbjoMo` z@1L}a-LZ;|y|#!olbJe$=bBHDzmO(WT`k+%R#Ep!p(L?+xHY_ElA`aC#|kj2RX{Vn zTt1fowGZ6}ec5FQ-Fp;?16QHYr7o=G(IJ47ZSCtTn-}lr@HOjyqHAp&tPQ#?Q=qQU zl(vL;INFL%L@Rnk%`fZ>t=ELn6SUw^k;Vr%fr6Brcn4qm zQZ>i^a033lk)a;Ip*vmyqFtbW#c0;GVE-_nA(dlF-*Y#14hwc*9czix7B#%N2x?ih z316KY%fP5;kJ=KMA?HVl?$HonMk8v^k~3_V$fZ+Pu5hRSILT)P<^l=>JgQK_59noYE8h4ALms^kzaJw1nM4T}k){yM)r zoK^eiCwARcmCiZ)Ad>NWo0<6IsD1xrv8}D3Gx5YE!X=RPYe&1bRo=2RSmN;P_4U4G zrDyt04O#tbxkm6@fRFgC`$C3Nuf~>gb#xU$od+<{ZA9D8m_C?LC^E@Uu(;72J!id3 ztJ;MP8YRUWO(!X>cV%iQpTMQg@q!TVvw%%Aeueq$v0`rgQ#5H_V{fC8ryR(`BptZ$ zW^42hb2+3Z6DmNaB1`|BJ-v|tdutCeQ#>ttL7}A5RMH97+47GAt~rL)-oCPG9oL#g z5L)$iZ{)`eI3?NvpmlKC{|foI5ib&E!#-c)1%3mH(n6 zc`g8XOaJnVeQ@5ZFJmy|5C?3h2?Ew<1+%3PWUR%Z8MD~bY(_u%d;+5CqG8=IotNzk5>044nOl}j$Z|-n$u68 zFO)s=?ju7>MkKR8mIP+=p}-VIoH5$~tb?$T1|_SJtBGR~K^+7`va! zvsF#n^6C*oz?o~#` z!0+Un$sTW!#8ZRWt00S;AjKOP&}8S=I_t>cOY=RC=UtP^gn@Y9J%DM>M%u_lTZq2JF4rk44794LayypVkEF1Th-&r=D zO}kmWIoZ6mYDeU(eMb^ZcxT;>=QM8BL*{gMf=LqSZrjhw`Ffl9@zR{_u<#{0?>BKG z5Bu>kjE3WJRdtV_v6E9N4znMrMD6Fy>L{$|t!6x&>YoxNI<5Ma2|KNY^55@GREc`J zY}PTfx@>3HUAycQ)h!$Dmd)G?BiB8C=62LY1k*e2Jvye>Gf?sRrSTbWmvCDPX^ZfZ zL?PYd=N@MSfdV?(r-lTkF8m6K!8=pivOy+aFtf^P+F*X}sVL<68l)Qm#aa@BQUbs? z2hW03fzeuxX5a*#_)&?x>A?JK?fdpRfO~RP>{Cz&T%Qj>kj25X)PP_Hp{=2sJ;y+7 zE>w~zmP4Z_uHL|+`zYfc{j5+j9HG85cnOLp*GvUaDp&LUh zn^K=#0zYaF{TYxej+Im|d|mk~nNK|}|JM;Ny%&1&wZ?JCd3%HqW?H;4e97motdTe; zU+Ik{z`Wb9$@Nk;=sC7gO3Je^5hcJ>g&kPWuGT?l$Nr=mCjp4WYXKD3FNvjX0FSO{ zh|FYj-#k znC9?nrX3<~Vq~m|)et#@DC#jqda16=Z#u5g5j#3tvKll)ob`rG%cIW;J8XdB$K0f= z)^rH1VCDC&h>sV~H#wUV`+De4l;?ezV-~k@tpEl9N9S$?%nTW>%~*i{_6}Az&Im8~ zNqRWg0Duh%%xl!gH&B)+Z`H@pFz`u4wC-ZSR#syo)x)`N_U60N1iS?pKt+4JgIZ&P z5%C}48(bCeEAPl_En5>5AR)7eZv%N4-r_`px|A{Oqmn}qL(nvkc*tye;2nXme9rA2 zN)!m-jp7r8j@>@K?sknbpUg^BFd{Rd8JZ5Cj{ruesZNWQI$H=LA*yT_gYmIyPEuzD z_t9We*wk|q#pU%tU~Koe%4X?p^vB$asAnmILcW{l9qu{a~=>r+}lt@ zu16_|3D1oxfXix!kLr?BbAXu|YCV*I7#WJgm*$cHMHk1`qFHl>ea%;onzIN|xoBKz zvzFz5oF_E_j|sw)lo6b3i&y$g)Ej0W>JS9(> zLbqAmR+d?nsIbEC4eUKtxr(MsqjFzIxCgy`njuLoh-so$gwxp@lG(iu6F4DoVu~QY z&!nxrI%4qw>KYmoKIxS8bqIF{a)G)@yH^jR-DMKZ$O{KWGf+Jz{jGVgBy(nz+j(d3j9K0oJbbSXIF?M1&2Q*;dwTNGI%S@B(WT5ETeTdd0>7PSJ?6!4$3tX`cymWo zfv8uAJOM&~+NaSI!zDp;qim%JxNZMA#7x`{eCct!h@0Pc*-En%Dl^LUz3|?Jidu3= z=#>;exf?%j#~4iuMPqdZ*wE-wty?w0SaG8BoxdJuBLn<2P1VMY3bGay7wAiNSaKx` z!7w95O_D^4JfuUic=rtb4vILs&3Aar!gK@ah{Ha00z`p9!;&x7h;wfSZ zk-}wNbfeYajGt+f`qr)U@NHb7!;lme*`0Ujsj`2bxM97e3-73G!DjWGV9%e*WQL4Z34=#1G0HM8_y%dS#(OjEDmM+N-`Os!a9$k{HE)&zS(XUE+kz z$VA=#jFXa{XTXssTvBJ^GF)KgWB<3#)ix7sxQ1N&LgKJoxhK9h&k5v;O|t3JPg_G* zX-y$CYE3lyt6jVq^lHH7w&dCyT%h(W8+s^v7+LUKB{c~+s6v%Zj1Azo8^q(6o5l@j zs(d6i*(^6+g^}|j-^Z5&iSySU(3A^ca}yww!ydGaOuG9V{o}KjU`&PnjFknHcfw#K zjl!sy5_k};f*azMD;molGmxCus*e#vszThJgCoEl*hzl7$$v@A5AKRNN`bbLP9}LuxT-j>x0*npS;%3 z9uEz3r$evP0wr&^xUuy)Z=}Vyw|q86p((`l(}{<(z-65$+Aj8GYbW3n3<2L5k0uHDAK(X3P6cdDs;JXo%g}_Nj-qw zAldB^x^QHycKVlPk{&F@1;soF#>sp=WVSL4^ZN$ z0asl4#VC(s0dT?%{Cw!A8rzlRX8{T&bGL8RsOU8lbw?a5WcqXlvw9%d}^b<0m&Z zqvJmh?ZL`=H4ju#A4X0Ef_W_f!$rzS6BbBQyOFX0CGlsv6D>5tg406-Q$c{?z7mXy zUx<@KDD&r&H~??h+A(r}H~zmS!@Cg2_0j5LH(QQ%NSQ?3H zpY?QDS~>{OxC+6k9N8R__0K?j(>LQ?uM>EM_;Pk>1fJNQ3uz1cfNC;>?4o2is~HOo z(3aJ$Qq$muzFGb>W?dhiI;$jHpt41-kunq#1$u7`LENT(tDd2^XbzSio1G8WhB!oo z5iD$C&1vh-BT{;EeFK^_ETkN)nj*ii_s|4VE=kuTmm#B8w&H7; z1i`SBZXG})q6WhWQ_`dUnnNMR6u!%|00!b9<8VMOG?XDtO$9oO=NOD;v978IW(i+3 zKJa1w>;toLK-LuiDtwx*lRzm{n5Q9^w|3`&z&&XaVBKwcD_eKi9q!TFn) zKX5YNqCgOF4r6R=z{C8sjEwf(;6gblL5-6}l`|3j z?JAnbuc%bx+1-N}4k*#PYl zb`XcbS;K($a$$7CLCyp|NPRr$#+NAyfgInwTNS~O zk*QO3`bsCai|&lSY`*H08%%J4{ROO$Sa)%PIGIam*^k%(|bNRlnbBQ!%UcG;6Xkt54gjOO$KNF>4N> zXc#tYB}{HPG;4QEORpU)z%=hFO=%M|?{Q4(esA7;XsYIE{!J|9Ynu5$T3TPL`B21O zM?}}q{eI)H`6%Tz0<=lyO@Tmb-CZc1kVx3BT+OTOL{x`x-_j z?pmJY5exm?KM_0fo3lKBfAmbn>cZ0sc(cMsGVlE4Rj6u|8q4^477$erzK#W{tyX z1DQK;d}>1=lXZl$OW5X_cq#k#4KAc@ot#(QLK zPnO7QWyeHf%O7bsEPIR}ZzsHh`LxXral}rP$eKd^SnTn6*Q%Xluay+1{f(IY3oome zAI^VT+RKPr$wu0rq}j`FSt_*I?+@F*%C}THvfs`-<3atY1hao5e#niwt;+fH*#`$@ zeh2kS3ysL1i)jv8Wft0P4zu@XLNh<5MjSqTu+V#aF>$DH#&97<y>7d(;zKR6E<(POa~q9DB{2ye=Ce zoLs!jT+1$N#GKrZPTf|VDi58!P|d)Pol7a5edl@4>6z;w+ddX>d_Gc4kov!a;$!S(-O?>(TR+O~DwBIlf=1c@Rd z8AJs{2`Z={B1wWGAR;`0ZIMRZgSr!i;r(I`?Y>9U3)Q_#QDkl#Zu^t@yDDKRX^vOUQC_iJo^0Q=gjhpFJC!ksJuS2 zc+E9(%wP5zSNB@@w3=M>WpQIIW@CSe$$7Bq@RNlX>KsSc7ca!9*9H^ECYAU5`!BWx z*1lansy_7GPC}ud9re0-W6nLH-`L)JW3%_hyQ|mxr`GEJXT%{RPvwbmuc4i2+y4mZ5pW{(b;*#Gj2^GAm+N2}mvkB<&zT=p*Q9J+X8f5?|- zk2j767Jt8f`S5V#k01VzAN3vl#W#n){tEWr{nvkVbbL+!__M!U!9QP9ikIS_f9@&N z=DN2v_WE|eR(-tv>soiQ7oGKBpMY2Zmxxxxa+9k)fRstxW@(eVGlW*)PPyebp6&=% z83)wTH{PBY9@RJztF6<03Bvbk)0uDROWBB54Irc)$D`8aUA9om-vx%Um4j)|TB8Mr z^EHyhpRS;V5XEI#h5&FMh0huwi`hVCUPHcU4+PhXBvBJ^y9n z&1Ihh63iDL$j&u7KmQsAc7FA6- z2$3j|p3JAc5^}~hFW5zDrZ!yjqSzcsqMq8@jw4F5I4eVnN>9h$q>BykP;MUg<$=?e z*=ZJ1sVi;`B>37k1=13i+%Jp^6>heSiWCpadwOB?wC2rzSfD@tEk%Y$=U&j?={e(X zjr1$NyiNVp&Uj)AKlgHpwS}hVPIV7&;5yPz)(t9bLQxfRB~sCo)?J4pOPq&NB+IMF zng)7lUnGA>ncUm#tj^QqNis9aLL!&Sv&mlF&8`^` zG7zWzD7KLKj*nzh*uRuE^2T^&(`+_d$Ll$p_)wmNu*t&qq!?T>p{b?Y{(^llYC%mI$)G^ZhwD`2!g}?b^v? z*rQ@?hr3oPc8?xh%kXorYSQ~QyNNcEHxHAU6$OQd*( ze8kMd)S@E95@cQ<3=dowXhFPJz5Mz+xp-(!kdRd*E}`MMoUdND3FQ}rjrsHHd8VB- z3(1>Jcr=Gz-*I#qdTFOE*kpI)*D7Q6wZ!9S*nKn1C^=d-Wb@jRyDt%oV(vZlNt~V* ze16|hb8jxPdvq8?Q?``Zt(sMBRuLSMg%WGR9!wy~#oM7zH_6yCT?wSrOz5;EarG>R zNj6Ex0`T~$se~H)FHu%@kHMi|@{yAo^P$u$&xWm~pqq8D6koqj4T%CC;%S?8g3Ex`K z6dHGhXbR%|i&480qHVXdPj3=V;RaGX6EnL-iwMPkE!lcDLzyjswX1})r|9~0uS-?O z%<7g{vBoXoTQ6t{vTa-guBYCl`*_P#U*Tw$$ktQY{Pj>5o?~3c^V^~Enf2G!A%v>M zFV08k3(e7%!0OLiwCSE1n;z08R7xPnu@cNja+2Qd_nRw`0>dNN{e>!U7c@#yu-^WqYgmZCN!iostF9<$QcX{oZ z{R>R@q2xU>6$dN(QxqbcxE|-{yKKGNucsyzf57W?XmgdNR^6N)?U|oh$$Jo%ajPRX zl%Zav?xx8j4Wf~zn>MEQt&`>|_FQyEP!U4tNWOp?7o{z6i5z^g+~h%9nA+u)^mZg)ws0vy(37N&l5{j8-BIhpnd5* z0u`?IT_;-2E%&eCU#AvFThxtLrGsCoRS&vuu-#h{b zM;yX@NG3|8kWlCf@=mXY$Q^{Lq?>s?AtOe#EO+ZYT7&xBwjepOVT6H5GlMtqARF! z(@{A5~ zVg+uqL7jpWi}tO7^A2U{27!Z2d`9VBr_O)Y4p5SQY2v5yj*if@|4CEL#Eeu>^Sr%p z^~h;ME?Q)xeEQ-vMeCY<)HC)e5f?eFRx-`?!usF0|p^cg>*D)j+Zw| zJmf7$Q`a)+Dui)TuNDh`>MoU%yfbDnU+$FMaH0E0NAOzDc=jh^x0XT?>Vnr z{5EkX1~neYO%=IZ6u7t$#itro^6GK7j_QT=)xf4NX#%z{`6kk0gJy`UC!U=VOTUR@ zi%YjKwXFR4JlUka%l%%=j)XzZkmlym2F=oSD=y~XrQpU9*%3W<_q13KBSWRRclDSL zX;$c$E()Za9GK7d$dGTW`ck8(OIuc@7JR<`d>6mLm9m=unoSm_XzLvSrB(Pk80uu5nubSY+;{t~7C#`74kyS=J-mCBs<@4_*jP(44fj$s z6QR12t7-W~ZhA(7?>Nkh3u#R+zTi)Pn#;)Y%7O31-rjx9#VP()YCKB|c{hb5ILm%O z_cp6r#Y?|76L!|l<=aFAitJ?6O3d|&yVTrSN>enEbOt31Zl6E12AKuQ&KSuBGTccg zP|NlxVfV@R6|%z>v{SBF?qq`VG<*x-h-kmx0Oy(UwO3$sq9^0`!EIa!Af?9@@iKMj zfe6BN$OC+Ze3b3C6?shBMVx~vL~sRc@bP4n3il2c|!rAzYgJv|2_z&)xi>0#~UK3MIbUO4( zO?TPVYI(H#d-+kmtUBiB6MHGB^KRuUm5nQ&QuGsoC$J)Uo`Qy}5AJE^0*Q4+3LEoN zmgYK?Z|_iqpE1L&O@T}A^t<$v3Mk^Tp-u}v)R7uaI3rph0=;G#LmUL0OL75 z#HU1EaC=mpLJU`s9#@M|^}!*Zjsw?qjUaD69&h#B=bzcvn#K*T&Jjl3r7|?43*jO& zn`jE<7=1c0$$_(HmG3ThiuvVHFHUVAMHCI|=MRkQaNeCxb51VLtNCdhvEQH5Xh`!E zGP7z#`3xGty;&@-Qx=6|GH--T-J#Z?NjK|qyG}*j#|R(MQRJ;1fmE>Lh_~l*E9MzM z+vI`Ezn(IWjUPuns|)UeOYI{~1kVG}cK!qs$##TJZhyI(;L0IY`To?hVphkc#52 zkGW6T`hYyfa1VBs{u#N&0i?9Zg3v+Qy-Q*Z`$M*B#( z6$iN>yOU1g2b}cq;fKtTM|2U*iy5=o&+Sj!8!wxVGTbns(ysPBcT4@02+m=}oGC%y zS)W<$F}UF^PX1AOV;xfQJ&||SMrDAh))+tu>vPj15v1w_F=(Ac`_-pb~))_a;N!{N_Ejo zg7kq(g2bizJmxw(iaDGscg>cQX@wHg*}0VSJtE@~pDkGyxRotf@XHOTY~B+Z8dLlE z97>&5CoQ97XJ3^vd+vH#8B>~x^MnST$+CS)SLlfqW0fW0 z`4GI*YDLMo=}wFIf;vYX=krZ<0(@`V=J|W!oUU(Uvax1XGjD_Xj;Wa!bt|%;E~bL< zG;$YTxh9gKgCoUXOd2CB(88-bClutMd}^pSU2KV$*oG}ZiPHx+qxG@;z9MHmZjm1@ z=a{1NwRw@|xj^~1>4>mXdi(>H3TgYjh+(Y*geL2Mfcb*c`Qof#udp0tIc7S*7avb znXhugRf;K9U$=reYMd4gyqba@CX^ESkg&L|AH_l0*>!EUVjpSTau;2}&i!R71sex^ zYdUgk2Q*wisMnR}h*Xl&&tsh~BNK(ZX1-#5uY*&ypcKcxx=o(&DS3adv@&Wp>d8VYuG4h~Kq1LCJ38(JEk%`q;oCsE%7u(So?t zwBT9!j4gXzZdl(ZF2+|pZ>zq_9<8X&+1|HTo6o*Sf5hn z&Sl8XduitwK}Y)Rrk&_n^zd2ocVba9YqxEbL_++9rp`Fk`{cYJI&Fz}#^&6qly?4V z95$|bzD}Hh(jz6o9vjx;joYI<9V^c`d!FeSpSPD>=Owpb;mYHFIL{fdE-y@l++xjj z=j-j8>yxGzS!v5?w$IZ0s#lA{zIocWwBYPvu8?8-x}S)HNi|jZJhOkhhj4YK8j413 zg;DU4wC!WVM0<3%oip*A+Mt+6XIgIWSw0tWin=FHV)SoUw_T_Ai!N4@Si*fX_tquO zTGrvKUh_g5rzlnC>RshaDQ3S~OOe==^gXP8U3n#tbrJ(?EaCtew__2YCc5Ev7Ytt}OJ zmOch$pg|r9@)HG;&nOy{AQg@rFF6KN$f%@5MJt_>R2Fc`X2zS7zefqL^(iBmL<6_QMBIGdwAa)rLpU zppU(sbudR#pM9mRlAu;D>83~1RxZ*{8h5PUNI!n-Y+|!)IVo8-wPSYA*>(eJ^Ge!g z7y68-(XO$9zOR$M+mD)mcT|zxQAWm*&X+_4hxUey`_0DZ+PlxqU7Vk}xRgL#?(I7J zH#$4YxCOhoJ&>6v@pUI^qb_fBX_WDNDi&wiZ>SVlDUA#6Ly?14Nj$AQDFPrNNCRx987+(oj|I0A{Gp>HuWdpQa1GHTOAHxFc&ITD^0$pIiPhcU@t|8vC zAz8Aad9Gn)uAx=1&{wh%Z(JklFcI+>TEzzY_xPua%_#e{+kVQ%s5ZK?wYf1h#h#Lj zP_qr+KlWgSWy%1I3c$vL~drdDN$R$2@3)b?bw`ofBZc4h+lpNfY;J=rgC6}7k zlv*X1CL{aseSnZ_8zUDEW&gwIEY_P2ktE4*k1{x|o^K4%eioU0HdS*DlYA~+bMC4A zTmkvK%guSJ&DrsC1?H|v_vDkzn+xCX7C5@6dF&THb}x>04+@tr$!adib1y2}FZFgW ztJ^O#a4$)6D=%uUc-36~NxpJbzI?;I>id2g>Fs*n~j5=6%+>f z-}5nj!XtRXzw*dK(ZCmsH3TbudF1IUSQ3$D#9Q429(kA+&ahsz6q}dF303+E*D3CB z-qW0+|4fzsmmq=v(j)H#B!Hz#pLpc`9|Z~gUyreuA2`KC=&10)X2td+nG>1Aa6Ev%J*j;__hOFav$m4Nf|LXt@k z)=J<%^~hT+`I_muv;1H37A;Db3)7E1@`8j{PCW983xOFb)+4X1y8FKgB=Bav83kPh zRs!8;Hh`7Dla1Gy#j=gogB@Tc03i|qRsu{mo4`t-e6#)7Bad2DQ9YIX zpmr*wepprFHTvVN3um`KTo&;08PR)C(J*@7Wo;Xm(2m0SlUeXjsqx22PoWd{?^VEY z>?Eigr<^`r-2Lo2nXx#ouC;+I4oS3u7$_mPhi^yM60G6K0mlObA+}6w0wtUmU#?Ap?d7Uh=WL}43 zIIpv(yR)miyC-0)1O){ECT~Psa#U0V!1C7C!j4JE0Dsfj428G116pq9#Lx^d@d0j1 zSey+2KhGhNOGsc-vW}d=x>D^NY_4NAfu|BM&Dp{1{07e(47gW==(!w-|L_kLLGpHma58u%sGYCL zdmD{)S&>@}ie$Ycg5v6}EqIqCX0Czw#@#_kDKBPH9y5y<^HTi8KJ>P+LIAR*tz(3M zW5o8M!Y`K<;guTRBCcX>f)f1FhGWQzc>f1UUY&?%N4~c#OQDsY0gG0{eD!%uK=Ji$ zQqCK&YEvCqI6tY!31r2a;gw!65(`;rwZ0!R346x!?AT@{B*$FLh=L(#@FV#2LFSq! zz7{!?$ke*}F=QpJ#=?5(;pRMmtY|%VaCIEYNV;A`V4{d0__6NEm%)p7AUJfEPFTo_ zGcE6pbTNRU^%xh{tvC7B`hOuSos3UT{6lN|rLq2@*UqdR`-e7+Sz!G`omba@%gUK` zEQ)r$X{ivnto*Nq#-l&S#{c8~p*xdySQf3*r>7t`eysqp@z_6i_iXnTPW(e%*7v?<2aE16apUmE=G${e2k1}Fj(%dkR)L1(?grrekY_`P)ZnwIwBii zK&_2bf76e-Kbugdr;XBm)1Qkxhgemuoi=qdK=4Km>AjwI#^%jHv4|Y<$7&s{6PrP@ z{W+8_Jsq6;o570Yxzzuuf2gqjH{c(d%h>oo9P>5&)u+Dls~usCfLg@TN%e!UDSUU3->$9~!KPEO{eOJusl%)N7`R>v9K&G@*%7Y5)pSIsdOV+nT zWH?rYzwUQ55JGE>&GTo)m1g%H~4ivU6j@?9azGGfA&7gN?1b0~=mHetdxtG2uF`p=>-1CO=onN@$#j40xKUTToB ztXH)^(x_=)`Q-De3Dv9NM?(ojk`P=g0xm4L`tUt3=epo}079UdJ*U@K_E zu{$Y%R3fHE5i`MMYxU3%nR;i;i2sCh-MU0NkObh`<0xL>P zOw24!AU6+y|0VEAMPZ?cDD=+U(jRWAJ39wE2Y`}@217Xi<@)@s7ZAq4V}NiGbmRA8 z7SpqQ)8Xa18641NePO!FRpBf!_qT9<$NB0LJM01wF5)+K7Ckn89NjWDWrg4b28V=( zg$G4MMMi_g#K*(AlMs`dl9ryCk$&wO1vwxfQWpOrAePkB5)l)UHWD?F5s(lvF`k(F z!$Ecq2#ABUL-f=i=!Ox$7a0%~sB!=0A|HUgT3&yQ4n6Us1xtOrSHU*LE-YBjp|KMu z-Knu5U{<;~wYj*CUPq(1P+)~m2%un*(L0+{STkC%Z+Eb3`?uEZZ@ri>Ofh0;i^NTV zL!-d4#YE)~f&yddGT5=zm{-_EwzBBAm62P9c@930FLP=3dY^=g?|nj000f_~@Q48C z$QYd1__&04E>Hm_lVoIOWs~RRKYna*fCX<<`$giO;abf z0-~g*csDTk?qqq1umQmiEbqg=>|wBh0lStl;uodWudp8*2TtIu&=xqX1>QZ@H#pWe zd~B6GHiWhN{S_8YIIPF))v=+IqVzZ*V7-39?)_WK^><%PXs`HQRaS&GJm(KU#l)0e z)tJb05D@alt9P!S04m5V{{U2Alx870Cb(|c<#i<_rle(NB#9)80tIGt{7HdHLB-0% zNSDQMLh;NkDa%vOuPmr8Ew8JmVfnpDt+41@atIuU9s=Y76jm|7l7Z2H%!==YAq>Ef zdi}u!#x5;s7>YG)hBFbZnTa$hMmq;Y071YViuCgG^h)sYsz#oO10g4g<5@MG+)U#tbWobXb8IL0bQGD zv@d%}vFnsNnB$K}wRW!&xU&9YvQ|BR^y=(j0|CwKSlt_#c>NFFA|sZwoaS8@ngh<6 zdo*NbSm&L-tEXs}4e|MjM?#8x`{vCXufxNi0$e`$gqDiF#H__Let4WqCVu4Ch-dxj zbOm!D6lTSy5H^P~KpU|T%njyEwB!yHFixHe6NL8UhMj9);_=^+gW!;^svugHPbc=xShbBi2H> zzogU&f!s52E&&Ru&XQ6xfYS@GENvHBrBr~+mr+8eg;^_r59exC6Jc3db@rYHiuST# ztUpb^beTx);H5P1L4A!UPaDSWcvL`#SjkY07s<&gVe_0%Y%3PxfLt)$zG6XMybpQI zb({_2L#{wXL_juJjDrseA`QWi`=BYq4j2PKFu}0KpgF_9_W@@Vh9?5UAF#f?x4h?qq4-O3tj!q4Zp|SbP(9G~~|8Yn`4o}PsPoRK#_b=!7 zVGu_8j}Km;Th2^(4^3lz(m?Jg)?_0=wD!sSjEhGiet@BWJ&emxj+gwx*%$rfNP{2 zm#ypJzU@~dScLB+%YM5f@IL*52O+`!$D*O!E0MGp`LX>J1>5rr` ztd3S0z6v8)-CiB5wtQF0=kfBXe&Z90_pN;UlB$DDl20(izlC$zf9%je<-!BC!X>q0 zj7BO(Blkcv^Wau8=2qe6olJ~w;elT2rd}>aFMmnD6y;ut@G3?JB_d)fJL76QOKa;( zp|J86RCR5A^>9BFz!7R&fTumIvcA2wv$Lh8y9eFZIo8+RIXF0lKujSP5u=01(P_k3 z&)CFZ{{*1H1AfCaV!E$qdax5KoKGN*Hz0a$6p5viPxsGF&&(|%7JE7uC;rn7NcaIh zI`EyCn2;bqxz|uS<9)G{yN`a!ClP4#i1Qm0TRrw2*8U}QQ@I7mC!h+KP7!f&-hZb; zXT(EEq52R&;K@L`MiL$w5)p+hFrr_^Bqbj2jI8XOG_z1jS_WQs0YM=NE_OzGwwn4n zmWD=X^DEfv))wYB?eLDSrtY53w|%_>?*@lHyaz`RfGmuE8krd3;F1!pIKzEfTI`%K z-}2nrI%@OV3GixTZy$5;UW? zK5%b6@M^|*wPO6B2Y$^MzjjPWEherSod89rw$5bcBMO@lrPYY?`g&+3_-=t=!3D5p zD6C}~2Cpse>+A0uMD+KJ^-s(UPN0T{urEZs9^kQaiXs)vppbzGzk=U#PF}5@}_CNEe6AmffzyAFeGhLAXU$JD;y=(4d zlbbFg$624en~jsP&~W%mdogN1h)Fe|IQw|}`3Cq01%`NehDHR3MMcKO#K*l%NJ@+b zbznw%W_EIJPIy*cVIn!@GYJQg^H&&|sOe~+jr1_ursmhJfZhJ8y``%Y+g9j!H_#34 z((rr4$C1&oPZJ-R*(AjHc%~gh&&&ycwgNwZw_~5*t?%3D-5t!{kNuwqhex=8-APbWWMb!1Y9}VO8nL3P49X`k$ z#uT<=3cFE--RQ#ZgVNH@(r$F=Af~(zU0GUOIe36g++px~5Z(vT*yjieo+EfS=q&a0 z^bGYJr-%K6gFS=8W5a`E!$UoYi5|q%7~nAcks%&u_5kPcJ29M_ni>LRj~-A^on(dB zM+rbH7Ln_qxZ1*OuAnzJQUBr20d^eI8EFyLyCUzOzWp;h?xa@7vg5*^e44ZfQfU6N zF*tnVxG(PYe&feS4rM!kmB4Fkj^4*X7Q|RXxhH1=l2jeyPI^BX@|=FjK}Bk(ROlGV zNyrEZKy_Ky0EN|q<`1|@jVPLOCBf7db z^eVshTd{d_Qlz36p+)1$-RaHS)}4jw_}9*}XjA`^m1O?3x6ep9 zd<(306kR)ks-40>!L#1n0&S^=wzfbAG0;&IbQBGpK*Od`&BwSJ5R;n+QO$D)ElZfz zA$02~x^n{E-QM5V-QV8{@9#$dMB(ss=V(v=C@2;Y$LbN{L_qqzpQaHL(=*e_NI(las`5*SvpZ^!kTrg^=u`?QQPCoq$m+&8ZOY3Q7-UQ5o z?xJMfF_#e2;`RQ)u>2YRr~dvN_Aju~1vtQ?wY>x4pRh~Cob(mLEzj}!+9n7+Az>oM zp(duJA*`ydt*NhUsB3I0e+8|0{RY<3+}7R&@9ya7ZS8wE__p)I&_MtDkzuOQiI0<7rT?+8z-opsdLg-yxeUl7jH3;Ci`>|(G>sq{XKwh z=tB!hEZbeJU~RuqC+8ST+iP=21pJ7@m$d zK1)h{dd9`}Gt7BpvFqJvgpO$i6vr-`oK>7zc+DgQG~0FAmONhDL{mcBTNd z5}P$nqlTw3qtgdtW0;eIb9xksz4sF+Fp~p<3UcD#-S0o&`@j2Z!ahaSb|ov~=xg{6 zDG%k-G?pA$3-rr|QP0B{+#8H~UDUu~VSZko!@~dbW}|{85z|YYE&|$KOR*QeK3)NS z-a-B$VSy3hQK6Bs!Ep)E@rmG2Pf5;5O;5|o&dklv%PK4=DlI81uB?hDBcvn3gW^G& zUNyJ8ZiQoIt~a<{Z@YWm^?_Z2JuN;0HpwW6L!YK5zD&O-qGIP_W8hpqbv&SRe57w| z?_%}<|L4cyPb|X{6qT33kxp4(&5a-YyCx9&(^+1Q)dN~Uv~PuWw)Vi=yZd|khx&G= z2D^I(`}zmLVLXT!Mq$7yjlgVT1%Q=<(RIw&6nbn4Fu9IT74^`X8+wg@h@Lb_)1ZyOL0jhiaO{oXSvNz%#?Ej zr5%P$l=uB2K#X3Ck0$5{mSp9*6Bp_Ae)h*-5TmSo5m8((qT^!{;*t`RQ_@nwS^hFu zh=k0MiJ_Po54RkrqOuxDx_=oFI8hr=w)@X@wNy&){7nMR}vU9}KbEPg^yi`(fO*N}1 zxhzBZnrNX)aZSpxaQY_lx&R(71c$V(-OoP|Hkev9R5uLDf=?r3AIB#Ulb>e*fDSqT zrS|Lc`&rcLf?DtOcL512kvnUc{f))F!~7q8IH=vK>^2|b@lbb_p3W8v{5|z_*-ex7 za9k?u{xNIbu7Gv1Af(`(NzyoFVksvK+j96vnToG->b z83wr}M$N9@S6-JnJu`aa?Mp~_;3)Q>!;gYaGhI($t|Nx&$4mCT^N-3Cfj4CTefzK7 zSyvuA8_J<6XeoL0m}_*YiO4BPnbj22c7pMU>5;8Q*wK+zH@wD+CK$Wfrg%2hN<*0A z6lwCgm`VlLZ^+@Sd(mE>!AIfYbuL6-(&TZ!zxm*C@6BiT{cp3g@sCfvx%hKyv*FVh ziq9@Mgv>VCzE5z&hH#$X7-whWlZz&|;Zw;A&IZs+>*WM8SrpF(F*_{H2GjU~sXFSo ze@xZ6a{K;)Sq7=H77S^^Ky=E@>!W#xDd3p_L+ z?_EE@J~wC#$W{Ob?w8~V9wX3C*jn0I+S~zI%x~dyAK;pQKS2MidV*9r@vkGKIvV0M zSI*mvq^_Ac)+drL-dyXO{5Zs08``j3a-7aQQHE64wM@JI!YrGH{7#ksGA5cOCdibx_m+3Le(ZxIN|NYVhd(JLzMzPSk0~wz z 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%0Ar91yX^amf%6`AHgL`+%6FVF9>P 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%0D-Xc_2> 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

h39uO@v=}*)$bp89 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�=cPO2=cX{<_aE^lZnNR88o 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 EUm3|)?EnA( literal 0 HcmV?d00001 From aa037f78e49436c30823520c768f5795fa1bd96d Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Fri, 6 Jul 2018 08:19:28 +0300 Subject: [PATCH 009/184] Screenshot path pattern (closes #1602, #1651, #1974, #1975) (#2562) * Screenshot file pattern * refactor test constrants * small refactoring * renames * don't correct file path for custom file path * try to fix tests2 * revert back correct file path for custom path * revert dedent module * fix review issues --- src/browser/connection/index.js | 10 +- src/cli/argument-parser.js | 4 +- src/cli/cli.js | 2 +- src/runner/index.js | 6 +- src/runner/task.js | 2 +- src/screenshots/capturer.js | 111 +++++++--------- src/screenshots/index.js | 86 ++++--------- src/screenshots/path-pattern.js | 119 ++++++++++++++++++ src/utils/correct-file-path.js | 17 +++ src/utils/escape-user-agent.js | 5 + test/functional/assertion-helper.js | 6 +- .../api/es-next/take-screenshot/test.js | 50 ++++++-- test/functional/setup.js | 41 +++--- test/server/cli-argument-parser-test.js | 1 + test/server/path-pattern-test.js | 78 ++++++++++++ test/server/util-test.js | 16 +++ 16 files changed, 386 insertions(+), 168 deletions(-) create mode 100644 src/screenshots/path-pattern.js create mode 100644 src/utils/correct-file-path.js create mode 100644 src/utils/escape-user-agent.js create mode 100644 test/server/path-pattern-test.js create mode 100644 test/server/util-test.js diff --git a/src/browser/connection/index.js b/src/browser/connection/index.js index adb63584..07611e1a 100644 --- a/src/browser/connection/index.js +++ b/src/browser/connection/index.js @@ -11,14 +11,10 @@ import STATUS from './status'; import { GeneralError } from '../../errors/runtime'; import MESSAGE from '../../errors/runtime/message'; - -// Const const IDLE_PAGE_TEMPLATE = read('../../client/browser/idle-page/index.html.mustache'); - var connections = {}; - export default class BrowserConnection extends EventEmitter { constructor (gateway, browserInfo, permanent) { super(); @@ -202,7 +198,11 @@ export default class BrowserConnection extends EventEmitter { establish (userAgent) { this.ready = true; - this.browserInfo.userAgent = parseUserAgent(userAgent).toString(); + const parsedUserAgent = parseUserAgent(userAgent); + + this.browserInfo.userAgent = parsedUserAgent.toString(); + this.browserInfo.fullUserAgent = userAgent; + this.browserInfo.parsedUserAgent = parsedUserAgent; this._waitForHeartbeat(); this.emit('ready'); diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index 8780e22b..b0408d3e 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -19,7 +19,7 @@ const DEFAULT_TEST_LOOKUP_DIRS = ['test/', 'tests/']; const TEST_FILE_GLOB_PATTERN = `./**/*@(${Compiler.getSupportedTestFileExtensions().join('|')})`; const DESCRIPTION = dedent(` - In the browser list, you can use browser names (e.g. "ie9", "chrome", etc.) as well as paths to executables. + In the browser list, you can use browser names (e.g. "ie", "chrome", etc.) as well as paths to executables. To run tests against all installed browsers, use the "all" alias. @@ -33,7 +33,6 @@ const DESCRIPTION = dedent(` More info: https://devexpress.github.io/testcafe/documentation `); - export default class CLIArgumentParser { constructor (cwd) { this.program = new Command('testcafe'); @@ -89,6 +88,7 @@ export default class CLIArgumentParser { .option('-r, --reporter ', 'specify the reporters and optionally files where reports are saved') .option('-s, --screenshots ', 'enable screenshot capturing and specify the path to save the screenshots to') .option('-S, --screenshots-on-fails', 'take a screenshot whenever a test fails') + .option('-p, --screenshot-path-pattern ', 'use patterns to compose screenshot file names and paths: ${BROWSER}, ${BROWSER_VERSION}, ${OS}, etc.') .option('-q, --quarantine-mode', 'enable the quarantine mode') .option('-d, --debug-mode', 'execute test steps one by one pausing the test after each step') .option('-e, --skip-js-errors', 'make tests not fail when a JS error happens on a page') diff --git a/src/cli/cli.js b/src/cli/cli.js index 2c89aa00..ed526cd7 100644 --- a/src/cli/cli.js +++ b/src/cli/cli.js @@ -93,7 +93,7 @@ async function runTests (argParser) { .browsers(browsers) .concurrency(concurrency) .filter(argParser.filter) - .screenshots(opts.screenshots, opts.screenshotsOnFails) + .screenshots(opts.screenshots, opts.screenshotsOnFails, opts.screenshotPathPattern) .startApp(opts.app, opts.appInitDelay); runner.once('done-bootstrapping', () => log.hideSpinner()); diff --git a/src/runner/index.js b/src/runner/index.js index 425892e3..b9c7f484 100644 --- a/src/runner/index.js +++ b/src/runner/index.js @@ -11,12 +11,10 @@ import { GeneralError } from '../errors/runtime'; import MESSAGE from '../errors/runtime/message'; import { assertType, is } from '../errors/runtime/type-assertions'; - const DEFAULT_SELECTOR_TIMEOUT = 10000; const DEFAULT_ASSERTION_TIMEOUT = 3000; const DEFAULT_PAGE_LOAD_TIMEOUT = 3000; - export default class Runner extends EventEmitter { constructor (proxy, browserConnectionGateway) { super(); @@ -30,6 +28,7 @@ export default class Runner extends EventEmitter { proxyBypass: null, screenshotPath: null, takeScreenshotsOnFails: false, + screenshotPathPattern: null, skipJsErrors: false, quarantineMode: false, debugMode: false, @@ -198,9 +197,10 @@ export default class Runner extends EventEmitter { return this; } - screenshots (path, takeOnFails = false) { + screenshots (path, takeOnFails = false, pattern = null) { this.opts.takeScreenshotsOnFails = takeOnFails; this.opts.screenshotPath = path; + this.opts.screenshotPathPattern = pattern; return this; } diff --git a/src/runner/task.js b/src/runner/task.js index 7793506f..554e1d1d 100644 --- a/src/runner/task.js +++ b/src/runner/task.js @@ -12,7 +12,7 @@ export default class Task extends EventEmitter { this.running = false; this.browserConnectionGroups = browserConnectionGroups; this.tests = tests; - this.screenshots = new Screenshots(opts.screenshotPath); + this.screenshots = new Screenshots(opts.screenshotPath, opts.screenshotPathPattern); this.warningLog = new WarningLog(); this.fixtureHookController = new FixtureHookController(tests, browserConnectionGroups.length); diff --git a/src/screenshots/capturer.js b/src/screenshots/capturer.js index 55060ca9..d347e598 100644 --- a/src/screenshots/capturer.js +++ b/src/screenshots/capturer.js @@ -1,46 +1,21 @@ import { join as joinPath, dirname, basename } from 'path'; -import sanitizeFilename from 'sanitize-filename'; import { generateThumbnail } from 'testcafe-browser-tools'; import cropScreenshot from './crop'; import { ensureDir } from '../utils/promisified-functions'; import { isInQueue, addToQueue } from '../utils/async-queue'; import WARNING_MESSAGE from '../notifications/warning-message'; - - -const PNG_EXTENSION_RE = /(\.png)$/; - +import escapeUserAgent from '../utils/escape-user-agent'; +import correctFilePath from '../utils/correct-file-path'; export default class Capturer { - constructor (baseScreenshotsPath, testEntry, connection, namingOptions, warningLog) { - this.enabled = !!baseScreenshotsPath; - this.baseScreenshotsPath = baseScreenshotsPath; - this.testEntry = testEntry; - this.provider = connection.provider; - this.browserId = connection.id; - this.baseDirName = namingOptions.baseDirName; - this.userAgentName = namingOptions.userAgentName; - this.quarantine = namingOptions.quarantine; - this.attemptNumber = this.quarantine ? this.quarantine.getNextAttemptNumber() : null; - this.testIndex = namingOptions.testIndex; - this.screenshotIndex = 1; - this.errorScreenshotIndex = 1; - this.warningLog = warningLog; - - var testDirName = `test-${this.testIndex}`; - var screenshotsPath = this.enabled ? joinPath(this.baseScreenshotsPath, this.baseDirName, testDirName) : ''; - - this.screenshotsPath = screenshotsPath; - this.screenshotPathForReport = screenshotsPath; - } - - static _correctFilePath (path) { - var correctedPath = path - .replace(/\\/g, '/') - .split('/') - .map(str => sanitizeFilename(str)) - .join('/'); - - return PNG_EXTENSION_RE.test(correctedPath) ? correctedPath : `${correctedPath}.png`; + constructor (baseScreenshotsPath, testEntry, connection, pathPattern, warningLog) { + this.enabled = !!baseScreenshotsPath; + this.baseScreenshotsPath = baseScreenshotsPath; + this.testEntry = testEntry; + this.provider = connection.provider; + this.browserId = connection.id; + this.warningLog = warningLog; + this.pathPattern = pathPattern; } static _getDimensionWithoutScrollbar (fullDimension, documentDimension, bodyDimension) { @@ -80,30 +55,50 @@ export default class Capturer { }; } - _getFileName (forError) { - var fileName = `${forError ? this.errorScreenshotIndex : this.screenshotIndex}.png`; + _joinWithBaseScreenshotPath (path) { + return joinPath(this.baseScreenshotsPath, path); + } + + _updateScreenshotPathForTestEntry (customPath) { + // NOTE: if test contains takeScreenshot action with custom path + // we should specify the most common screenshot folder in report + let screenshotPathForTestEntry = this.baseScreenshotsPath; + + if (!customPath) { + const pathForReport = this.pathPattern.getPathForReport(); + + screenshotPathForTestEntry = this._joinWithBaseScreenshotPath(pathForReport); + } + + this.testEntry.path = screenshotPathForTestEntry; + } + + _incrementFileIndexes (forError) { if (forError) - this.errorScreenshotIndex++; + this.pathPattern.data.errorFileIndex++; + else - this.screenshotIndex++; + this.pathPattern.data.fileIndex++; + } + + _getCustomScreenshotPath (customPath) { + const correctedCustomPath = correctFilePath(customPath); - return fileName; + return this._joinWithBaseScreenshotPath(correctedCustomPath); } - _getScreenshotPath (fileName, customPath) { - if (customPath) - return joinPath(this.baseScreenshotsPath, Capturer._correctFilePath(customPath)); + _getScreenshotPath (forError) { + const path = this.pathPattern.getPath(forError); - var screenshotPath = this.attemptNumber !== null ? - joinPath(this.screenshotsPath, `run-${this.attemptNumber}`) : this.screenshotsPath; + this._incrementFileIndexes(forError); - return joinPath(screenshotPath, this.userAgentName, fileName); + return this._joinWithBaseScreenshotPath(path); } _getThumbnailPath (screenshotPath) { - var imageName = basename(screenshotPath); - var imageDir = dirname(screenshotPath); + const imageName = basename(screenshotPath); + const imageDir = dirname(screenshotPath); return joinPath(imageDir, 'thumbnails', imageName); } @@ -117,12 +112,8 @@ export default class Capturer { if (!this.enabled) return null; - var fileName = this._getFileName(forError); - - fileName = forError ? joinPath('errors', fileName) : fileName; - - var screenshotPath = this._getScreenshotPath(fileName, customPath); - var thumbnailPath = this._getThumbnailPath(screenshotPath); + const screenshotPath = customPath ? this._getCustomScreenshotPath(customPath) : this._getScreenshotPath(forError); + const thumbnailPath = this._getThumbnailPath(screenshotPath); if (isInQueue(screenshotPath)) this.warningLog.addWarning(WARNING_MESSAGE.screenshotRewritingError, screenshotPath); @@ -135,18 +126,13 @@ export default class Capturer { await generateThumbnail(screenshotPath, thumbnailPath); }); - // NOTE: if test contains takeScreenshot action with custom path - // we should specify the most common screenshot folder in report - if (customPath) - this.screenshotPathForReport = this.baseScreenshotsPath; - - this.testEntry.path = this.screenshotPathForReport; + this._updateScreenshotPathForTestEntry(customPath); const screenshot = { screenshotPath, thumbnailPath, - userAgent: this.userAgentName, - quarantineAttemptID: this.attemptNumber, + userAgent: escapeUserAgent(this.pathPattern.data.parsedUserAgent), + quarantineAttemptID: this.pathPattern.data.quarantineAttempt, takenOnFail: forError, }; @@ -155,7 +141,6 @@ export default class Capturer { return screenshotPath; } - async captureAction (options) { return await this._capture(false, options); } diff --git a/src/screenshots/index.js b/src/screenshots/index.js index 4e7ed786..df6f5cf2 100644 --- a/src/screenshots/index.js +++ b/src/screenshots/index.js @@ -1,56 +1,19 @@ import { find } from 'lodash'; -import sanitizeFilename from 'sanitize-filename'; import moment from 'moment'; import Capturer from './capturer'; +import PathPattern from './path-pattern'; export default class Screenshots { - constructor (path) { - this.enabled = !!path; - this.screenshotsPath = path; - this.testEntries = []; - this.screenshotBaseDirName = Screenshots._getScreenshotBaseDirName(); - this.userAgentNames = []; - } - - static _getScreenshotBaseDirName () { - var now = Date.now(); - - return moment(now).format('YYYY-MM-DD_hh-mm-ss'); - } - - static _escapeUserAgent (userAgent) { - return sanitizeFilename(userAgent.toString()).replace(/\s+/g, '_'); - } - - _getUsedUserAgent (name, testIndex, quarantineAttemptNum) { - var userAgent = null; - - for (var i = 0; i < this.userAgentNames.length; i++) { - userAgent = this.userAgentNames[i]; - - if (userAgent.name === name && userAgent.testIndex === testIndex && - userAgent.quarantineAttemptNum === quarantineAttemptNum) - return userAgent; - } - - return null; - } - - _getUserAgentName (userAgent, testIndex, quarantineAttemptNum) { - var userAgentName = Screenshots._escapeUserAgent(userAgent); - var usedUserAgent = this._getUsedUserAgent(userAgentName, testIndex, quarantineAttemptNum); - - if (usedUserAgent) { - usedUserAgent.index++; - return `${userAgentName}_${usedUserAgent.index}`; - } - - this.userAgentNames.push({ name: userAgentName, index: 0, testIndex, quarantineAttemptNum }); - return userAgentName; + constructor (path, pattern) { + this.enabled = !!path; + this.screenshotsPath = path; + this.screenshotsPattern = pattern; + this.testEntries = []; + this.now = moment(); } _addTestEntry (test) { - var testEntry = { + const testEntry = { test: test, path: this.screenshotsPath || '', screenshots: [] @@ -65,6 +28,15 @@ export default class Screenshots { return find(this.testEntries, entry => entry.test === test); } + _ensureTestEntry (test) { + let testEntry = this._getTestEntry(test); + + if (!testEntry) + testEntry = this._addTestEntry(test); + + return testEntry; + } + getScreenshotsInfo (test) { return this._getTestEntry(test).screenshots; } @@ -78,20 +50,16 @@ export default class Screenshots { } createCapturerFor (test, testIndex, quarantine, connection, warningLog) { - var testEntry = this._getTestEntry(test); - - if (!testEntry) - testEntry = this._addTestEntry(test); - - const quarantineAttemptNum = quarantine ? quarantine.getNextAttemptNumber() : null; - - var namingOptions = { + const testEntry = this._ensureTestEntry(test); + const pathPattern = new PathPattern(this.screenshotsPattern, { testIndex, - quarantine, - baseDirName: this.screenshotBaseDirName, - userAgentName: this._getUserAgentName(connection.userAgent, testIndex, quarantineAttemptNum) - }; - - return new Capturer(this.screenshotsPath, testEntry, connection, namingOptions, warningLog); + quarantineAttempt: quarantine ? quarantine.getNextAttemptNumber() : null, + now: this.now, + fixture: test.fixture.name, + test: test.name, + parsedUserAgent: connection.browserInfo.parsedUserAgent, + }); + + return new Capturer(this.screenshotsPath, testEntry, connection, pathPattern, warningLog); } } diff --git a/src/screenshots/path-pattern.js b/src/screenshots/path-pattern.js new file mode 100644 index 00000000..fd241d32 --- /dev/null +++ b/src/screenshots/path-pattern.js @@ -0,0 +1,119 @@ +import { escapeRegExp as escapeRe } from 'lodash'; +import correctFilePath from '../utils/correct-file-path'; +import escapeUserAgent from '../utils/escape-user-agent'; + +const DATE_FORMAT = 'YYYY-MM-DD'; +const TIME_FORMAT = 'HH-mm-ss'; + +const SCRENSHOT_EXTENTION = 'png'; + +const ERRORS_FOLDER = 'errors'; + +const PLACEHOLDERS = { + DATE: '${DATE}', + TIME: '${TIME}', + TEST_INDEX: '${TEST_INDEX}', + FILE_INDEX: '${FILE_INDEX}', + QUARANTINE_ATTEMPT: '${QUARANTINE_ATTEMPT}', + FIXTURE: '${FIXTURE}', + TEST: '${TEST}', + USERAGENT: '${USERAGENT}', + BROWSER: '${BROWSER}', + BROWSER_VERSION: '${BROWSER_VERSION}', + OS: '${OS}', + OS_VERSION: '${OS_VERSION}' +}; + +const DEFAULT_PATH_PATTERN_FOR_REPORT = `${PLACEHOLDERS.DATE}_${PLACEHOLDERS.TIME}\\test-${PLACEHOLDERS.TEST_INDEX}`; +const DEFAULT_PATH_PATTERN = `${DEFAULT_PATH_PATTERN_FOR_REPORT}\\${PLACEHOLDERS.USERAGENT}\\${PLACEHOLDERS.FILE_INDEX}.${SCRENSHOT_EXTENTION}`; +const QUARANTINE_MODE_DEFAULT_PATH_PATTERN = `${DEFAULT_PATH_PATTERN_FOR_REPORT}\\run-${PLACEHOLDERS.QUARANTINE_ATTEMPT}\\${PLACEHOLDERS.USERAGENT}\\${PLACEHOLDERS.FILE_INDEX}.${SCRENSHOT_EXTENTION}`; + +export default class PathPattern { + constructor (pattern, data) { + this.pattern = this._ensurePattern(pattern, data.quarantineAttempt); + this.data = this._addDefaultFields(data); + this.placeholderToDataMap = this._createPlaceholderToDataMap(); + } + + _ensurePattern (pattern, quarantineAttempt) { + if (pattern) + return pattern; + + return quarantineAttempt ? QUARANTINE_MODE_DEFAULT_PATH_PATTERN : DEFAULT_PATH_PATTERN; + } + + _addDefaultFields (data) { + const defaultFields = { + formattedDate: data.now.format(DATE_FORMAT), + formattedTime: data.now.format(TIME_FORMAT), + fileIndex: 1, + errorFileIndex: 1 + }; + + return Object.assign({}, defaultFields, data); + } + + _createPlaceholderToDataMap () { + return { + [PLACEHOLDERS.DATE]: this.data.formattedDate, + [PLACEHOLDERS.TIME]: this.data.formattedTime, + [PLACEHOLDERS.TEST_INDEX]: this.data.testIndex, + [PLACEHOLDERS.QUARANTINE_ATTEMPT]: this.data.quarantineAttempt || 1, + [PLACEHOLDERS.FIXTURE]: this.data.fixture, + [PLACEHOLDERS.TEST]: this.data.test, + [PLACEHOLDERS.FILE_INDEX]: forError => forError ? this.data.errorFileIndex : this.data.fileIndex, + [PLACEHOLDERS.USERAGENT]: this.data.parsedUserAgent.toString(), + [PLACEHOLDERS.BROWSER]: this.data.parsedUserAgent.browser, + [PLACEHOLDERS.BROWSER_VERSION]: this.data.parsedUserAgent.browserVersion, + [PLACEHOLDERS.OS]: this.data.parsedUserAgent.os, + [PLACEHOLDERS.OS_VERSION]: this.data.parsedUserAgent.osVersion + }; + } + + static _buildPath (pattern, placeholderToDataMap, forError) { + let resultFilePath = pattern; + + for (const placeholder in placeholderToDataMap) { + const findPlaceholderRegExp = new RegExp(escapeRe(placeholder), 'g'); + + resultFilePath = resultFilePath.replace(findPlaceholderRegExp, () => { + if (placeholder === PLACEHOLDERS.FILE_INDEX) { + const getFileIndexFn = placeholderToDataMap[placeholder]; + let result = getFileIndexFn(forError); + + if (forError) + result = `${ERRORS_FOLDER}\\${result}`; + + return result; + } + + else if (placeholder === PLACEHOLDERS.USERAGENT) { + const userAgent = placeholderToDataMap[placeholder]; + + return escapeUserAgent(userAgent); + } + + return placeholderToDataMap[placeholder]; + }); + } + + return resultFilePath; + } + + getPath (forError) { + const path = PathPattern._buildPath(this.pattern, this.placeholderToDataMap, forError); + + return correctFilePath(path, SCRENSHOT_EXTENTION); + } + + getPathForReport () { + const path = PathPattern._buildPath(DEFAULT_PATH_PATTERN_FOR_REPORT, this.placeholderToDataMap); + + return correctFilePath(path); + } + + // For testing purposes + static get PLACEHOLDERS () { + return PLACEHOLDERS; + } +} diff --git a/src/utils/correct-file-path.js b/src/utils/correct-file-path.js new file mode 100644 index 00000000..3d03ae73 --- /dev/null +++ b/src/utils/correct-file-path.js @@ -0,0 +1,17 @@ +import sanitizeFilename from 'sanitize-filename'; +import { escapeRegExp as escapeRe } from 'lodash'; + +export default function (path, expectedExtention) { + const correctedPath = path + .replace(/\\/g, '/') + .split('/') + .map(str => sanitizeFilename(str)) + .join('/'); + + if (!expectedExtention) + return correctedPath; + + const extentionRe = new RegExp(escapeRe(expectedExtention)); + + return extentionRe.test(correctedPath) ? correctedPath : `${correctedPath}.${expectedExtention}`; +} diff --git a/src/utils/escape-user-agent.js b/src/utils/escape-user-agent.js new file mode 100644 index 00000000..6c9a7a05 --- /dev/null +++ b/src/utils/escape-user-agent.js @@ -0,0 +1,5 @@ +import sanitizeFilename from 'sanitize-filename'; + +export default function escapeUserAgent (userAgent) { + return sanitizeFilename(userAgent.toString()).replace(/\s+/g, '_'); +} diff --git a/test/functional/assertion-helper.js b/test/functional/assertion-helper.js index 3e7c3b21..439c31b6 100644 --- a/test/functional/assertion-helper.js +++ b/test/functional/assertion-helper.js @@ -244,7 +244,7 @@ exports.checkScreenshotsCreated = function ({ forError, customPath, screenshotsC var taskDirPath = path.join(SCREENSHOTS_PATH, taskDirs[0]); if (customPath) { - var customDirExists = taskDirPath.indexOf(customPath) !== -1; + var customDirExists = taskDirPath.includes(customPath); var hasScreenshots = getScreenshotFilesCount(taskDirPath, customPath) === expectedScreenshotCount * expectedSubDirCount; @@ -314,3 +314,7 @@ exports.removeScreenshotDir = function () { del(SCREENSHOTS_PATH); }; +exports.SCREENSHOTS_PATH = SCREENSHOTS_PATH; + +exports.THUMBNAILS_DIR_NAME = THUMBNAILS_DIR_NAME; + diff --git a/test/functional/fixtures/api/es-next/take-screenshot/test.js b/test/functional/fixtures/api/es-next/take-screenshot/test.js index 0e93feae..6948c0a9 100644 --- a/test/functional/fixtures/api/es-next/take-screenshot/test.js +++ b/test/functional/fixtures/api/es-next/take-screenshot/test.js @@ -1,18 +1,20 @@ -var path = require('path'); -var expect = require('chai').expect; -var config = require('../../../../config.js'); -var assertionHelper = require('../../../../assertion-helper.js'); - -var CUSTOM_SCREENSHOT_DIR = '___test-screenshots___'; -var SCREENSHOT_PATH_MESSAGE_RE = /^___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1$/; -var SCREENSHOT_ON_FAIL_PATH_MESSAGE_RE = /^.*run-1/; -var SLASH_RE = /[\\/]/g; +const path = require('path'); +const fs = require('fs'); +const expect = require('chai').expect; +const config = require('../../../../config.js'); +const assertionHelper = require('../../../../assertion-helper.js'); + +const SCREENSHOTS_PATH = assertionHelper.SCREENSHOTS_PATH; +const THUMBNAILS_DIR_NAME = assertionHelper.THUMBNAILS_DIR_NAME; +const SCREENSHOT_PATH_MESSAGE_RE = /^___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1$/; +const SCREENSHOT_ON_FAIL_PATH_MESSAGE_RE = /^.*run-1/; +const SLASH_RE = /[\\/]/g; var getReporter = function (scope) { const userAgents = { }; function patchScreenshotPath (screenshotPath) { - return screenshotPath.replace(SCREENSHOT_ON_FAIL_PATH_MESSAGE_RE, '').replace(CUSTOM_SCREENSHOT_DIR, '').replace(SLASH_RE, '_'); + return screenshotPath.replace(SCREENSHOT_ON_FAIL_PATH_MESSAGE_RE, '').replace(SCREENSHOTS_PATH, '').replace(SLASH_RE, '_'); } function prepareScreenshot (screenshot, quarantine) { @@ -58,7 +60,7 @@ describe('[API] t.takeScreenshot()', function () { return runTests('./testcafe-fixtures/take-screenshot.js', 'Take a screenshot with a custom path (OS separator)', { setScreenshotPath: true }) .then(function () { - expect(testReport.screenshotPath).eql(CUSTOM_SCREENSHOT_DIR); + expect(testReport.screenshotPath).eql(SCREENSHOTS_PATH); const screenshotsCheckingOptions = { forError: false, screenshotsCount: 2, customPath: 'custom' }; @@ -70,7 +72,7 @@ describe('[API] t.takeScreenshot()', function () { return runTests('./testcafe-fixtures/take-screenshot.js', 'Take a screenshot with a custom path (DOS separator)', { setScreenshotPath: true }) .then(function () { - expect(testReport.screenshotPath).contains(CUSTOM_SCREENSHOT_DIR); + expect(testReport.screenshotPath).contains(SCREENSHOTS_PATH); const screenshotsCheckingOptions = { forError: false, screenshotsCount: 2, customPath: 'custom' }; @@ -136,7 +138,7 @@ describe('[API] t.takeScreenshot()', function () { return runTests('./testcafe-fixtures/take-screenshot.js', 'Take screenshots with same path', { setScreenshotPath: true }).then(function () { - const screenshotFileName = path.join(CUSTOM_SCREENSHOT_DIR, '1.png'); + const screenshotFileName = path.join(SCREENSHOTS_PATH, '1.png'); expect(testReport.warnings).eql([ `The file at "${screenshotFileName}" already exists. It has just been rewritten ` + @@ -203,6 +205,28 @@ describe('[API] t.takeScreenshot()', function () { expect(result.unstable).eql(true); }); }); + + it('Should allow to use a custom path pattern', function () { + return runTests('./testcafe-fixtures/take-screenshot.js', 'Take a screenshot', + { + setScreenshotPath: true, + screenshotPathPattern: '${TEST}-${FILE_INDEX}', + only: 'chrome' + }) + .then(() => { + expect(SCREENSHOT_PATH_MESSAGE_RE.test(testReport.screenshotPath)).eql(true); + + const screenshot1Path = path.join(assertionHelper.SCREENSHOTS_PATH, 'Take a screenshot-1.png'); + const screenshot2Path = path.join(assertionHelper.SCREENSHOTS_PATH, 'Take a screenshot-2.png'); + const thumbnail1Path = path.join(assertionHelper.SCREENSHOTS_PATH, THUMBNAILS_DIR_NAME, 'Take a screenshot-1.png'); + const thumbnail2Path = path.join(assertionHelper.SCREENSHOTS_PATH, THUMBNAILS_DIR_NAME, 'Take a screenshot-2.png'); + + expect(fs.existsSync(screenshot1Path)).eql(true); + expect(fs.existsSync(screenshot2Path)).eql(true); + expect(fs.existsSync(thumbnail1Path)).eql(true); + expect(fs.existsSync(thumbnail2Path)).eql(true); + }); + }); } }); diff --git a/test/functional/setup.js b/test/functional/setup.js index 7b0a48ef..9cbf4bcf 100644 --- a/test/functional/setup.js +++ b/test/functional/setup.js @@ -158,25 +158,26 @@ before(function () { global.testCafe = testCafe; global.runTests = function (fixture, testName, opts) { - var report = ''; - var runner = testCafe.createRunner(); - var fixturePath = typeof fixture !== 'string' || path.isAbsolute(fixture) ? fixture : path.join(path.dirname(caller()), fixture); - var skipJsErrors = opts && opts.skipJsErrors; - var disablePageReloads = opts && opts.disablePageReloads; - var quarantineMode = opts && opts.quarantineMode; - var selectorTimeout = opts && opts.selectorTimeout || FUNCTIONAL_TESTS_SELECTOR_TIMEOUT; - var assertionTimeout = opts && opts.assertionTimeout || FUNCTIONAL_TESTS_ASSERTION_TIMEOUT; - var pageLoadTimeout = opts && opts.pageLoadTimeout || FUNCTIONAL_TESTS_PAGE_LOAD_TIMEOUT; - var onlyOption = opts && opts.only; - var skipOption = opts && opts.skip; - var screenshotPath = opts && opts.setScreenshotPath ? '___test-screenshots___' : ''; - var screenshotsOnFails = opts && opts.screenshotsOnFails; - var speed = opts && opts.speed; - var appCommand = opts && opts.appCommand; - var appInitDelay = opts && opts.appInitDelay; - var externalProxyHost = opts && opts.useProxy; - var proxyBypass = opts && opts.proxyBypass; - var customReporters = opts && opts.reporters; + let report = ''; + const runner = testCafe.createRunner(); + const fixturePath = typeof fixture !== 'string' || path.isAbsolute(fixture) ? fixture : path.join(path.dirname(caller()), fixture); + const skipJsErrors = opts && opts.skipJsErrors; + const disablePageReloads = opts && opts.disablePageReloads; + const quarantineMode = opts && opts.quarantineMode; + const selectorTimeout = opts && opts.selectorTimeout || FUNCTIONAL_TESTS_SELECTOR_TIMEOUT; + const assertionTimeout = opts && opts.assertionTimeout || FUNCTIONAL_TESTS_ASSERTION_TIMEOUT; + const pageLoadTimeout = opts && opts.pageLoadTimeout || FUNCTIONAL_TESTS_PAGE_LOAD_TIMEOUT; + const onlyOption = opts && opts.only; + const skipOption = opts && opts.skip; + const screenshotPath = opts && opts.setScreenshotPath ? '___test-screenshots___' : ''; + const screenshotPathPattern = opts && opts.screenshotPathPattern; + const screenshotsOnFails = opts && opts.screenshotsOnFails; + const speed = opts && opts.speed; + const appCommand = opts && opts.appCommand; + const appInitDelay = opts && opts.appInitDelay; + const externalProxyHost = opts && opts.useProxy; + const proxyBypass = opts && opts.proxyBypass; + const customReporters = opts && opts.reporters; var actualBrowsers = browsersInfo.filter(function (browserInfo) { var { alias, userAgent } = browserInfo.settings; @@ -227,7 +228,7 @@ before(function () { return testName ? test === testName : true; }) .src(fixturePath) - .screenshots(screenshotPath, screenshotsOnFails) + .screenshots(screenshotPath, screenshotsOnFails, screenshotPathPattern) .startApp(appCommand, appInitDelay) .run({ skipJsErrors, disablePageReloads, quarantineMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed }) .then(function () { diff --git a/test/server/cli-argument-parser-test.js b/test/server/cli-argument-parser-test.js index 77593bce..dda2ff54 100644 --- a/test/server/cli-argument-parser-test.js +++ b/test/server/cli-argument-parser-test.js @@ -413,6 +413,7 @@ describe('CLI argument parser', function () { { long: '--list-browsers', short: '-b' }, { long: '--reporter', short: '-r' }, { long: '--screenshots', short: '-s' }, + { long: '--screenshot-path-pattern', short: '-p' }, { long: '--screenshots-on-fails', short: '-S' }, { long: '--quarantine-mode', short: '-q' }, { long: '--debug-mode', short: '-d' }, diff --git a/test/server/path-pattern-test.js b/test/server/path-pattern-test.js new file mode 100644 index 00000000..e9310a9a --- /dev/null +++ b/test/server/path-pattern-test.js @@ -0,0 +1,78 @@ +const PathPattern = require('../../lib/screenshots/path-pattern'); +const expect = require('chai').expect; +const moment = require('moment'); + +describe('Screenshot path pattern', () => { + const createPathPattern = (pattern, data) => { + data = data || {}; + data.now = data.now || moment(); + data.parsedUserAgent = data.parsedUserAgent || {}; + data.quarantineAttempt = data.quarantineAttempt || null; + + return new PathPattern(pattern, data); + }; + + describe('Default pattern', () => { + it('Normal run', () => { + const pathPattern = createPathPattern(); + + expect(pathPattern.pattern).eql('${DATE}_${TIME}\\test-${TEST_INDEX}\\${USERAGENT}\\${FILE_INDEX}.png'); + }); + + it('Quarantine mode', () => { + const pathPattern = createPathPattern(void 0, { quarantineAttempt: 1 }); + + expect(pathPattern.pattern).eql('${DATE}_${TIME}\\test-${TEST_INDEX}\\run-${QUARANTINE_ATTEMPT}\\${USERAGENT}\\${FILE_INDEX}.png'); + }); + }); + + it('Should replace all placeholders', () => { + const pattern = Object.getOwnPropertyNames(PathPattern.PLACEHOLDERS).map(name => PathPattern.PLACEHOLDERS[name]).join('#'); + const dateStr = '2010-01-02'; + const timeStr = '11:12:13'; + const data = { + now: moment(dateStr + ' ' + timeStr), + testIndex: 12, + fileIndex: 34, + quarantineAttempt: 56, + fixture: 'fixture', + test: 'test', + parsedUserAgent: { + browser: 'Chrome', + browserVersion: '67.0.3396', + os: 'Windows', + osVersion: '8.1.0.0', + toString: function () { + return 'full_user_agent'; + } + } + }; + const expectedParsedPattern = [ + dateStr, + timeStr.replace(/:/g, '-'), + data.testIndex, + data.fileIndex, + data.quarantineAttempt, + data.fixture, + data.test, + data.parsedUserAgent.toString(), + data.parsedUserAgent.browser, + data.parsedUserAgent.browserVersion, + data.parsedUserAgent.os, + data.parsedUserAgent.osVersion + ].join('#') + '.png'; + + const pathPattern = createPathPattern(pattern, data); + + const path = pathPattern.getPath(false); + + expect(path).eql(expectedParsedPattern); + }); + + it('Should add `errors` folder before filename', () => { + const pathPattern = createPathPattern('${FILE_INDEX}'); + const path = pathPattern.getPath(true); + + expect(path).eql('errors/1.png'); + }); +}); diff --git a/test/server/util-test.js b/test/server/util-test.js new file mode 100644 index 00000000..a27d8886 --- /dev/null +++ b/test/server/util-test.js @@ -0,0 +1,16 @@ +const expect = require('chai').expect; +const correctFilePath = require('../../lib/utils/correct-file-path'); +const escapeUserAgent = require('../../lib/utils/escape-user-agent'); + +describe('Utils', () => { + it('Correct File Path', () => { + expect(correctFilePath('\\test')).eql('/test'); + expect(correctFilePath('"')).eql(''); + expect(correctFilePath('test.png', 'test.png')); + expect(correctFilePath('test', 'png')).eql('test.png'); + }); + + it('Escape user agent', () => { + expect(escapeUserAgent('Chrome 67.0.3396 / Windows 8.1.0.0')).eql('Chrome_67.0.3396_Windows_8.1.0.0'); + }); +}); From 7e1b8b4245948075544f3ce99fcb0a0d33526590 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Fri, 6 Jul 2018 14:33:40 +0300 Subject: [PATCH 010/184] rename 'quarantineAttemptID' to 'quarantineAttempt' (#2602) --- src/reporter/index.js | 4 +- src/screenshots/capturer.js | 6 +- .../api/es-next/take-screenshot/test.js | 6 +- test/server/reporter-test.js | 60 +++++++++---------- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/reporter/index.js b/src/reporter/index.js index aa3933a2..626d242a 100644 --- a/src/reporter/index.js +++ b/src/reporter/index.js @@ -104,9 +104,9 @@ export default class Reporter { if (testRun.quarantine) { reportItem.quarantine = testRun.quarantine.attempts.reduce((result, errors, index) => { const passed = !errors.length; - const quarantineAttemptID = index + 1; + const quarantineAttempt = index + 1; - result[quarantineAttemptID] = { passed }; + result[quarantineAttempt] = { passed }; return result; }, {}); diff --git a/src/screenshots/capturer.js b/src/screenshots/capturer.js index d347e598..9adc6799 100644 --- a/src/screenshots/capturer.js +++ b/src/screenshots/capturer.js @@ -131,9 +131,9 @@ export default class Capturer { const screenshot = { screenshotPath, thumbnailPath, - userAgent: escapeUserAgent(this.pathPattern.data.parsedUserAgent), - quarantineAttemptID: this.pathPattern.data.quarantineAttempt, - takenOnFail: forError, + userAgent: escapeUserAgent(this.pathPattern.data.parsedUserAgent), + quarantineAttempt: this.pathPattern.data.quarantineAttempt, + takenOnFail: forError, }; this.testEntry.screenshots.push(screenshot); diff --git a/test/functional/fixtures/api/es-next/take-screenshot/test.js b/test/functional/fixtures/api/es-next/take-screenshot/test.js index 6948c0a9..1fddb8e5 100644 --- a/test/functional/fixtures/api/es-next/take-screenshot/test.js +++ b/test/functional/fixtures/api/es-next/take-screenshot/test.js @@ -20,7 +20,7 @@ var getReporter = function (scope) { function prepareScreenshot (screenshot, quarantine) { screenshot.screenshotPath = patchScreenshotPath(screenshot.screenshotPath); screenshot.thumbnailPath = patchScreenshotPath(screenshot.thumbnailPath); - screenshot.isPassedAttempt = quarantine[screenshot.quarantineAttemptID].passed; + screenshot.isPassedAttempt = quarantine[screenshot.quarantineAttempt].passed; userAgents[screenshot.userAgent] = true; } @@ -181,8 +181,8 @@ describe('[API] t.takeScreenshot()', function () { screenshotPath, thumbnailPath, takenOnFail, - quarantineAttemptID: attempt, - isPassedAttempt: attempt > 1, + quarantineAttempt: attempt, + isPassedAttempt: attempt > 1, userAgent }; }; diff --git a/test/server/reporter-test.js b/test/server/reporter-test.js index fc92acee..a022fabe 100644 --- a/test/server/reporter-test.js +++ b/test/server/reporter-test.js @@ -43,11 +43,11 @@ describe('Reporter', function () { fixture: fixtureMocks[0], skip: false, screenshots: [{ - screenshotPath: 'screenshot1.png', - thumbnailPath: 'thumbnail1.png', - userAgent: 'chrome', - takenOnFail: false, - quarantineAttemptID: 2 + screenshotPath: 'screenshot1.png', + thumbnailPath: 'thumbnail1.png', + userAgent: 'chrome', + takenOnFail: false, + quarantineAttempt: 2 }], meta: { run: 'run-001' @@ -58,17 +58,17 @@ describe('Reporter', function () { fixture: fixtureMocks[0], skip: false, screenshots: [{ - screenshotPath: 'screenshot1.png', - thumbnailPath: 'thumbnail1.png', - userAgent: 'chrome', - takenOnFail: false, - quarantineAttemptID: null + screenshotPath: 'screenshot1.png', + thumbnailPath: 'thumbnail1.png', + userAgent: 'chrome', + takenOnFail: false, + quarantineAttempt: null }, { - screenshotPath: 'screenshot2.png', - thumbnailPath: 'thumbnail2.png', - userAgent: 'chrome', - takenOnFail: true, - quarantineAttemptID: null + screenshotPath: 'screenshot2.png', + thumbnailPath: 'thumbnail2.png', + userAgent: 'chrome', + takenOnFail: true, + quarantineAttempt: null }], meta: { run: 'run-001' @@ -327,11 +327,11 @@ describe('Reporter', function () { }, screenshotPath: '/screenshots/1445437598847', screenshots: [{ - screenshotPath: 'screenshot1.png', - thumbnailPath: 'thumbnail1.png', - userAgent: 'chrome', - takenOnFail: false, - quarantineAttemptID: 2 + screenshotPath: 'screenshot1.png', + thumbnailPath: 'thumbnail1.png', + userAgent: 'chrome', + takenOnFail: false, + quarantineAttempt: 2 }] }, { @@ -365,17 +365,17 @@ describe('Reporter', function () { quarantine: null, screenshotPath: '/screenshots/1445437598847', screenshots: [{ - screenshotPath: 'screenshot1.png', - thumbnailPath: 'thumbnail1.png', - userAgent: 'chrome', - takenOnFail: false, - quarantineAttemptID: null + screenshotPath: 'screenshot1.png', + thumbnailPath: 'thumbnail1.png', + userAgent: 'chrome', + takenOnFail: false, + quarantineAttempt: null }, { - screenshotPath: 'screenshot2.png', - thumbnailPath: 'thumbnail2.png', - userAgent: 'chrome', - takenOnFail: true, - quarantineAttemptID: null + screenshotPath: 'screenshot2.png', + thumbnailPath: 'thumbnail2.png', + userAgent: 'chrome', + takenOnFail: true, + quarantineAttempt: null }] }, { From 3615ea04d0a7dc0df259b5d3a48a61d5b957064a Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Mon, 9 Jul 2018 13:07:24 +0300 Subject: [PATCH 011/184] Update README.md for the Studio Release (#2594) --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 847bedde..99c66443 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ ## Table of contents * [Features](#features) +* [IDE for End-to-End Web Testing](#ide-for-end-to-end-web-testing) * [Getting Started](#getting-started) * [Documentation](#documentation) * [Community](#community) @@ -81,6 +82,18 @@ const macOSInput = Selector('.column').find('label').withText('MacOS').child('in You can run TestCafe from a console, and its reports can be viewed in a CI system's interface (TeamCity, Jenkins, Travis & etc.) +## IDE for End-to-End Web Testing + +We've got one more tool for you! + +Check out [TestCafe Studio](https://testcafe-studio.devexpress.com): all the perks of TestCafe + GUI + Visual Test Recorder + +![Get Started with TestCafe Studio](https://raw.githubusercontent.com/DevExpress/testcafe/master/media/testcafe-studio-get-started.gif) + +

+Record and Run a Test in TestCafe Studio +

+ ## Getting Started ### Installation From 8cde8f7618527c589c08c42a095b743490785ef9 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Mon, 9 Jul 2018 16:02:02 +0300 Subject: [PATCH 012/184] Avoid Marionette connection with custom user profiles (closes #2589) (#2590) * Avoid Marionette connection with custom user profiles(closes #2589) * Add tests * Fix remarks --- .../built-in/chrome/create-temp-profile.js | 45 ++++++++++++ .../provider/built-in/chrome/local-chrome.js | 3 +- .../provider/built-in/chrome/runtime-info.js | 53 ++------------ .../built-in/firefox/create-temp-profile.js | 64 +++++++++++++++++ .../provider/built-in/firefox/index.js | 5 +- .../built-in/firefox/local-firefox.js | 16 +++-- .../built-in/firefox/marionette-client.js | 14 ++-- .../provider/built-in/firefox/runtime-info.js | 70 ++----------------- test/functional/config.js | 11 +-- .../browser-provider/chrome-emulation/test.js | 11 ++- .../browser-provider/custom-profile/test.js | 40 +++++++++++ .../testcafe-fixtures/index-test.js | 9 +++ test/functional/utils/null-stream.js | 1 + 13 files changed, 203 insertions(+), 139 deletions(-) create mode 100644 src/browser/provider/built-in/chrome/create-temp-profile.js create mode 100644 src/browser/provider/built-in/firefox/create-temp-profile.js create mode 100644 test/functional/fixtures/browser-provider/custom-profile/test.js create mode 100644 test/functional/fixtures/browser-provider/custom-profile/testcafe-fixtures/index-test.js create mode 100644 test/functional/utils/null-stream.js diff --git a/src/browser/provider/built-in/chrome/create-temp-profile.js b/src/browser/provider/built-in/chrome/create-temp-profile.js new file mode 100644 index 00000000..63efba2d --- /dev/null +++ b/src/browser/provider/built-in/chrome/create-temp-profile.js @@ -0,0 +1,45 @@ +import path from 'path'; +import tmp from 'tmp'; +import { writeFile, ensureDir } from '../../../../utils/promisified-functions'; + + +export default async function (proxyHostName) { + tmp.setGracefulCleanup(); + + const tempDir = tmp.dirSync({ unsafeCleanup: true }); + const profileDirName = path.join(tempDir.name, 'Default'); + + await ensureDir(profileDirName); + + const preferences = { + 'credentials_enable_service': false, + + 'devtools': { + 'preferences': { + 'currentDockState': '"undocked"', + 'lastDockState': '"bottom"' + } + }, + + 'profile': { + 'content_settings': { + 'exceptions': { + 'automatic_downloads': { + [proxyHostName]: { setting: 1 } + } + } + }, + + 'password_manager_enabled': false + }, + + 'translate': { + 'enabled': false + } + }; + + await writeFile(path.join(profileDirName, 'Preferences'), JSON.stringify(preferences)); + await writeFile(path.join(tempDir.name, 'First Run'), ''); + + return tempDir; +} diff --git a/src/browser/provider/built-in/chrome/local-chrome.js b/src/browser/provider/built-in/chrome/local-chrome.js index 3ee07831..62649cbf 100644 --- a/src/browser/provider/built-in/chrome/local-chrome.js +++ b/src/browser/provider/built-in/chrome/local-chrome.js @@ -6,8 +6,9 @@ import BrowserStarter from '../../utils/browser-starter'; const browserStarter = new BrowserStarter(); function buildChromeArgs (config, cdpPort, platformArgs, profileDir) { - return [`--remote-debugging-port=${cdpPort}`] + return [] .concat( + cdpPort ? [`--remote-debugging-port=${cdpPort}`] : [], !config.userProfile ? [`--user-data-dir=${profileDir.name}`] : [], config.headless ? ['--headless'] : [], config.userArgs ? [config.userArgs] : [], diff --git a/src/browser/provider/built-in/chrome/runtime-info.js b/src/browser/provider/built-in/chrome/runtime-info.js index 7e55789b..ab291b09 100644 --- a/src/browser/provider/built-in/chrome/runtime-info.js +++ b/src/browser/provider/built-in/chrome/runtime-info.js @@ -1,60 +1,17 @@ -import path from 'path'; -import tmp from 'tmp'; import { getFreePort } from 'endpoint-utils'; import getConfig from './config'; -import { writeFile, ensureDir } from '../../../../utils/promisified-functions'; +import createTempProfile from './create-temp-profile'; var commonTempProfile = null; -async function createTempUserDir (proxyHostName) { - tmp.setGracefulCleanup(); - - const tempDir = tmp.dirSync({ unsafeCleanup: true }); - const profileDirName = path.join(tempDir.name, 'Default'); - - await ensureDir(profileDirName); - - const preferences = { - 'credentials_enable_service': false, - - 'devtools': { - 'preferences': { - 'currentDockState': '"undocked"', - 'lastDockState': '"bottom"' - } - }, - - 'profile': { - 'content_settings': { - 'exceptions': { - 'automatic_downloads': { - [proxyHostName]: { setting: 1 } - } - } - }, - - 'password_manager_enabled': false - }, - - 'translate': { - 'enabled': false - } - }; - - await writeFile(path.join(profileDirName, 'Preferences'), JSON.stringify(preferences)); - await writeFile(path.join(tempDir.name, 'First Run'), ''); - - return tempDir; -} - -async function getTempProfileDir (proxyHostName, config) { +async function getTempProfile (proxyHostName, config) { var tempProfile = commonTempProfile; var shouldUseCommonProfile = !config.headless && !config.emulation; if (!shouldUseCommonProfile || !commonTempProfile) - tempProfile = await createTempUserDir(proxyHostName); + tempProfile = await createTempProfile(proxyHostName); if (shouldUseCommonProfile && !commonTempProfile) commonTempProfile = tempProfile; @@ -64,8 +21,8 @@ async function getTempProfileDir (proxyHostName, config) { export default async function (proxyHostName, configString) { var config = getConfig(configString); - var tempProfileDir = !config.userProfile ? await getTempProfileDir(proxyHostName, config) : null; - var cdpPort = config.cdpPort || await getFreePort(); + var tempProfileDir = !config.userProfile ? await getTempProfile(proxyHostName, config) : null; + var cdpPort = config.cdpPort || (!config.userProfile ? await getFreePort() : null); return { config, cdpPort, tempProfileDir }; } diff --git a/src/browser/provider/built-in/firefox/create-temp-profile.js b/src/browser/provider/built-in/firefox/create-temp-profile.js new file mode 100644 index 00000000..c30e7f88 --- /dev/null +++ b/src/browser/provider/built-in/firefox/create-temp-profile.js @@ -0,0 +1,64 @@ +import path from 'path'; +import tmp from 'tmp'; +import { writeFile } from '../../../../utils/promisified-functions'; + + +async function generatePreferences (profileDir, { marionettePort, config }) { + var prefsFileName = path.join(profileDir, 'user.js'); + + var prefs = [ + 'user_pref("browser.link.open_newwindow.override.external", 2);', + 'user_pref("app.update.enabled", false);', + 'user_pref("app.update.auto", false);', + 'user_pref("app.update.mode", 0);', + 'user_pref("app.update.service.enabled", false);', + 'user_pref("browser.shell.checkDefaultBrowser", false);', + 'user_pref("browser.usedOnWindows10", true);', + 'user_pref("browser.rights.3.shown", true);', + 'user_pref("browser.startup.homepage_override.mstone","ignore");', + 'user_pref("browser.tabs.warnOnCloseOtherTabs", false);', + 'user_pref("browser.tabs.warnOnClose", false);', + 'user_pref("browser.sessionstore.resume_from_crash", false);', + 'user_pref("toolkit.telemetry.reportingpolicy.firstRun", false);', + 'user_pref("toolkit.telemetry.enabled", false);', + 'user_pref("toolkit.telemetry.rejected", true);', + 'user_pref("datareporting.healthreport.uploadEnabled", false);', + 'user_pref("datareporting.healthreport.service.enabled", false);', + 'user_pref("datareporting.healthreport.service.firstRun", false);', + 'user_pref("datareporting.policy.dataSubmissionEnabled", false);', + 'user_pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);', + 'user_pref("app.shield.optoutstudies.enabled", false);', + 'user_pref("extensions.shield-recipe-client.enabled", false);', + 'user_pref("extensions.shield-recipe-client.first_run", false);', + 'user_pref("extensions.shield-recipe-client.startupExperimentPrefs.browser.newtabpage.activity-stream.enabled", false);', + 'user_pref("devtools.toolbox.host", "window");', + 'user_pref("devtools.toolbox.previousHost", "bottom");', + 'user_pref("signon.rememberSignons", false);' + ]; + + if (marionettePort) { + prefs = prefs.concat([ + `user_pref("marionette.port", ${marionettePort});`, + 'user_pref("marionette.enabled", true);' + ]); + } + + if (config.disableMultiprocessing) { + prefs = prefs.concat([ + 'user_pref("browser.tabs.remote.autostart", false);', + 'user_pref("browser.tabs.remote.autostart.2", false);', + ]); + } + + await writeFile(prefsFileName, prefs.join('\n')); +} + +export default async function (runtimeInfo) { + tmp.setGracefulCleanup(); + + const tmpDir = tmp.dirSync({ unsafeCleanup: true }); + + await generatePreferences(tmpDir.name, runtimeInfo); + + return tmpDir; +} diff --git a/src/browser/provider/built-in/firefox/index.js b/src/browser/provider/built-in/firefox/index.js index f41a1b7f..bbb3aa1c 100644 --- a/src/browser/provider/built-in/firefox/index.js +++ b/src/browser/provider/built-in/firefox/index.js @@ -13,7 +13,7 @@ export default { async _createMarionetteClient (runtimeInfo) { try { - var marionetteClient = new MarionetteClient(runtimeInfo.marionettePort); + const marionetteClient = new MarionetteClient(runtimeInfo.marionettePort); await marionetteClient.connect(); @@ -35,7 +35,8 @@ export default { await this.waitForConnectionReady(runtimeInfo.browserId); - runtimeInfo.marionetteClient = await this._createMarionetteClient(runtimeInfo); + if (runtimeInfo.marionettePort) + runtimeInfo.marionetteClient = await this._createMarionetteClient(runtimeInfo); this.openedBrowsers[browserId] = runtimeInfo; }, diff --git a/src/browser/provider/built-in/firefox/local-firefox.js b/src/browser/provider/built-in/firefox/local-firefox.js index 72b55cd6..75aff2cb 100644 --- a/src/browser/provider/built-in/firefox/local-firefox.js +++ b/src/browser/provider/built-in/firefox/local-firefox.js @@ -14,10 +14,11 @@ function correctOpenParametersForMac (parameters) { parameters.macOpenCmdTemplate += ' {{{pageUrl}}}'; } -function buildFirefoxArgs (config, platformArgs, profileDir) { - return ['-marionette'] +function buildFirefoxArgs (config, platformArgs, { marionettePort, tempProfileDir }) { + return [] .concat( - !config.userProfile ? ['-no-remote', '-new-instance', `-profile "${profileDir.name}"`] : [], + marionettePort ? ['-marionette'] : [], + !config.userProfile ? ['-no-remote', '-new-instance', `-profile "${tempProfileDir.name}"`] : [], config.headless ? ['-headless'] : [], config.userArgs ? [config.userArgs] : [], platformArgs ? [platformArgs] : [] @@ -26,14 +27,15 @@ function buildFirefoxArgs (config, platformArgs, profileDir) { } export async function start (pageUrl, runtimeInfo) { - const { browserName, config, tempProfileDir } = runtimeInfo; - const firefoxInfo = await browserTools.getBrowserInfo(config.path || browserName); - const firefoxOpenParameters = Object.assign({}, firefoxInfo); + const { browserName, config } = runtimeInfo; + + const firefoxInfo = await browserTools.getBrowserInfo(config.path || browserName); + const firefoxOpenParameters = Object.assign({}, firefoxInfo); if (OS.mac && !config.userProfile) correctOpenParametersForMac(firefoxOpenParameters); - firefoxOpenParameters.cmd = buildFirefoxArgs(config, firefoxOpenParameters.cmd, tempProfileDir, runtimeInfo.newInstance); + firefoxOpenParameters.cmd = buildFirefoxArgs(config, firefoxOpenParameters.cmd, runtimeInfo, runtimeInfo.newInstance); await browserStarter.startBrowser(firefoxOpenParameters, pageUrl); } diff --git a/src/browser/provider/built-in/firefox/marionette-client.js b/src/browser/provider/built-in/firefox/marionette-client.js index 0bbf10c6..d795bd04 100644 --- a/src/browser/provider/built-in/firefox/marionette-client.js +++ b/src/browser/provider/built-in/firefox/marionette-client.js @@ -7,10 +7,10 @@ import delay from '../../../../utils/delay'; import { GET_WINDOW_DIMENSIONS_INFO_SCRIPT } from '../../utils/client-functions'; -const CONNECTION_READY_TIMEOUT = 300; -const MAX_CONNECTION_RETRY_COUNT = 100; -const MAX_RESIZE_RETRY_COUNT = 2; -const HEADER_SEPARATOR = ':'; +const CONNECTION_TIMEOUT = 30000; +const CONNECTION_RETRY_DELAY = 300; +const MAX_RESIZE_RETRY_COUNT = 2; +const HEADER_SEPARATOR = ':'; module.exports = class MarionetteClient { constructor (port = 2828, host = '127.0.0.1') { @@ -43,14 +43,16 @@ module.exports = class MarionetteClient { .then(() => true) .catch(() => { this.socket.removeAllListeners('connect'); - return delay(CONNECTION_READY_TIMEOUT); + return delay(CONNECTION_RETRY_DELAY); }); } async _connectSocket (port, host) { + const connectionStartTime = Date.now(); + var connected = await this._attemptToConnect(port, host); - for (var i = 0; !connected && i < MAX_CONNECTION_RETRY_COUNT; i++) + while (!connected && Date.now() - connectionStartTime < CONNECTION_TIMEOUT) connected = await this._attemptToConnect(port, host); if (!connected) diff --git a/src/browser/provider/built-in/firefox/runtime-info.js b/src/browser/provider/built-in/firefox/runtime-info.js index 1fd31ce9..f5267b6f 100644 --- a/src/browser/provider/built-in/firefox/runtime-info.js +++ b/src/browser/provider/built-in/firefox/runtime-info.js @@ -1,74 +1,14 @@ -import path from 'path'; -import tmp from 'tmp'; import { getFreePort } from 'endpoint-utils'; import getConfig from './config'; -import { writeFile } from '../../../../utils/promisified-functions'; +import createTempProfile from './create-temp-profile'; -function createTempProfileDir () { - tmp.setGracefulCleanup(); - - return tmp.dirSync({ unsafeCleanup: true }); -} - -async function generatePrefs (profileDir, { marionettePort, config }) { - var prefsFileName = path.join(profileDir, 'user.js'); - - var prefs = [ - 'user_pref("browser.link.open_newwindow.override.external", 2);', - 'user_pref("app.update.enabled", false);', - 'user_pref("app.update.auto", false);', - 'user_pref("app.update.mode", 0);', - 'user_pref("app.update.service.enabled", false);', - 'user_pref("browser.shell.checkDefaultBrowser", false);', - 'user_pref("browser.usedOnWindows10", true);', - 'user_pref("browser.rights.3.shown", true);', - 'user_pref("browser.startup.homepage_override.mstone","ignore");', - 'user_pref("browser.tabs.warnOnCloseOtherTabs", false);', - 'user_pref("browser.tabs.warnOnClose", false);', - 'user_pref("browser.sessionstore.resume_from_crash", false);', - 'user_pref("toolkit.telemetry.reportingpolicy.firstRun", false);', - 'user_pref("toolkit.telemetry.enabled", false);', - 'user_pref("toolkit.telemetry.rejected", true);', - 'user_pref("datareporting.healthreport.uploadEnabled", false);', - 'user_pref("datareporting.healthreport.service.enabled", false);', - 'user_pref("datareporting.healthreport.service.firstRun", false);', - 'user_pref("datareporting.policy.dataSubmissionEnabled", false);', - 'user_pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);', - 'user_pref("app.shield.optoutstudies.enabled", false);', - 'user_pref("extensions.shield-recipe-client.enabled", false);', - 'user_pref("extensions.shield-recipe-client.first_run", false);', - 'user_pref("extensions.shield-recipe-client.startupExperimentPrefs.browser.newtabpage.activity-stream.enabled", false);', - 'user_pref("devtools.toolbox.host", "window");', - 'user_pref("devtools.toolbox.previousHost", "bottom");', - 'user_pref("signon.rememberSignons", false);' - ]; - - if (marionettePort) { - prefs = prefs.concat([ - `user_pref("marionette.port", ${marionettePort});`, - 'user_pref("marionette.enabled", true);' - ]); - } - - if (config.disableMultiprocessing) { - prefs = prefs.concat([ - 'user_pref("browser.tabs.remote.autostart", false);', - 'user_pref("browser.tabs.remote.autostart.2", false);', - ]); - } - - await writeFile(prefsFileName, prefs.join('\n')); -} - export default async function (configString) { - var config = getConfig(configString); - var marionettePort = config.marionettePort || await getFreePort(); - var tempProfileDir = !config.userProfile ? createTempProfileDir() : null; - var runtimeInfo = { config, tempProfileDir, marionettePort }; + const config = getConfig(configString); + const marionettePort = config.marionettePort || (!config.userProfile ? await getFreePort() : null); + const runtimeInfo = { config, marionettePort }; - if (!config.userProfile) - await generatePrefs(tempProfileDir.name, runtimeInfo); + runtimeInfo.tempProfileDir = !config.userProfile ? await createTempProfile(runtimeInfo) : null; return runtimeInfo; } diff --git a/test/functional/config.js b/test/functional/config.js index f6015ee5..5636cc16 100644 --- a/test/functional/config.js +++ b/test/functional/config.js @@ -130,7 +130,8 @@ testingEnvironments[testingEnvironmentNames.localBrowsersIE] = { }; testingEnvironments[testingEnvironmentNames.localBrowsersChromeFirefox] = { - isLocalBrowsers: true, + isLocalBrowsers: true, + isHeadlessBrowsers: true, browsers: [ { @@ -225,9 +226,11 @@ module.exports = { return this.currentEnvironment.isLocalBrowsers; }, - testingEnvironmentNames: testingEnvironmentNames, - testingEnvironments: testingEnvironments, - browserProviderNames: browserProviderNames, + isTravisEnvironment, + + testingEnvironmentNames, + testingEnvironments, + browserProviderNames, testCafe: { hostname: hostname, diff --git a/test/functional/fixtures/browser-provider/chrome-emulation/test.js b/test/functional/fixtures/browser-provider/chrome-emulation/test.js index a2a0546c..adebabe8 100644 --- a/test/functional/fixtures/browser-provider/chrome-emulation/test.js +++ b/test/functional/fixtures/browser-provider/chrome-emulation/test.js @@ -1,10 +1,9 @@ -const path = require('path'); -const expect = require('chai').expect; -const config = require('../../../config'); +const path = require('path'); +const expect = require('chai').expect; +const config = require('../../../config'); +const nullStream = require('../../../utils/null-stream'); -const NULL_STREAM = { write: () => {}, end: () => {} }; - if (config.useLocalBrowsers) { describe('Browser Provider - Chrome Emulation Mode', function () { it('Should emulate touch event handlers', function () { @@ -12,7 +11,7 @@ if (config.useLocalBrowsers) { .createRunner() .src(path.join(__dirname, './testcafe-fixtures/index-test.js')) .filter(fixtureName => fixtureName === 'Check presence of touch event handlers') - .reporter('minimal', NULL_STREAM) + .reporter('minimal', nullStream) .browsers('chrome:headless:emulation:device=iphone 6 --no-sandbox') .run() .then(failedCount => { diff --git a/test/functional/fixtures/browser-provider/custom-profile/test.js b/test/functional/fixtures/browser-provider/custom-profile/test.js new file mode 100644 index 00000000..05cda3a4 --- /dev/null +++ b/test/functional/fixtures/browser-provider/custom-profile/test.js @@ -0,0 +1,40 @@ +const path = require('path'); +const { expect } = require('chai'); +const Promise = require('pinkie'); +const config = require('../../../config'); +const nullStream = require('../../../utils/null-stream'); +const createChromeProfile = require('../../../../../lib/browser/provider/built-in/chrome/create-temp-profile'); +const createFirefoxProfile = require('../../../../../lib/browser/provider/built-in/firefox/create-temp-profile'); + + +if (config.useLocalBrowsers && !config.isTravisEnvironment) { + describe('Browser Provider - Custom User Profile', function () { + it('Should run tests in userProfile mode', function () { + return testCafe + .createRunner() + .src(path.join(__dirname, './testcafe-fixtures/index-test.js')) + .reporter('minimal', nullStream) + .browsers('chrome:userProfile', 'firefox:userProfile') + .run() + .then(failedCount => { + expect(failedCount).eql(0); + }); + }); + + it('Should run tests with the explicitly specified profile', function () { + return Promise + .all([createChromeProfile('localhost'), createFirefoxProfile({ config: {} })]) + .then(([chromeProfile, firefoxProfile]) => { + return testCafe + .createRunner() + .src(path.join(__dirname, './testcafe-fixtures/index-test.js')) + .reporter('minimal', nullStream) + .browsers(`chrome --user-data-dir=${chromeProfile.name}`, `firefox -profile ${firefoxProfile.name}`) + .run(); + }) + .then(failedCount => { + expect(failedCount).eql(0); + }); + }); + }); +} diff --git a/test/functional/fixtures/browser-provider/custom-profile/testcafe-fixtures/index-test.js b/test/functional/fixtures/browser-provider/custom-profile/testcafe-fixtures/index-test.js new file mode 100644 index 00000000..63af3782 --- /dev/null +++ b/test/functional/fixtures/browser-provider/custom-profile/testcafe-fixtures/index-test.js @@ -0,0 +1,9 @@ +import { ClientFunction } from 'testcafe'; + +fixture `Custom user profile`; + +const checkIsEqual = ClientFunction(() => 42 === 42); + +test('Test', async t => { + await t.expect(checkIsEqual).ok(); +}); diff --git a/test/functional/utils/null-stream.js b/test/functional/utils/null-stream.js new file mode 100644 index 00000000..5d7269ce --- /dev/null +++ b/test/functional/utils/null-stream.js @@ -0,0 +1 @@ +module.exports = { write: () => {}, end: () => {} }; From 27fb1e7195db32bb2acf9721b1d23330c2458cb4 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Tue, 10 Jul 2018 14:06:05 +0300 Subject: [PATCH 013/184] fix 'wrong callsite for RequestHooks errors' (close #2555) (#2603) * tmp * fix 'wrong callsite for RequestHooks errors' (close #2555) --- src/api/request-hooks/request-logger.js | 13 +- src/api/request-hooks/request-mock.js | 7 +- src/errors/runtime/message.js | 3 +- src/errors/test-run/index.js | 11 -- src/errors/test-run/templates.js | 6 - src/errors/test-run/type.js | 3 +- test/server/api-test.js | 114 ++++++++++++++++++ .../cannot-stringify-request-body.js | 10 ++ .../cannot-stringify-response-body.js | 10 ++ ...equest-to-was-not-called-before-respond.js | 7 ++ ...pond-was-not-called-after-on-request-to.js | 7 ++ test/server/request-hooks-test.js | 81 ++----------- test/server/test-run-error-formatting-test.js | 5 - 13 files changed, 174 insertions(+), 103 deletions(-) create mode 100644 test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-request-body.js create mode 100644 test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-response-body.js create mode 100644 test/server/data/test-suites/request-hooks/request-mock/on-request-to-was-not-called-before-respond.js create mode 100644 test/server/data/test-suites/request-hooks/request-mock/respond-was-not-called-after-on-request-to.js diff --git a/src/api/request-hooks/request-logger.js b/src/api/request-hooks/request-logger.js index 3db88188..324e7d73 100644 --- a/src/api/request-hooks/request-logger.js +++ b/src/api/request-hooks/request-logger.js @@ -3,7 +3,8 @@ import RequestHook from './hook'; import { parse as parseUserAgent } from 'useragent'; import testRunTracker from '../test-run-tracker'; import ReExecutablePromise from '../../utils/re-executable-promise'; -import { RequestHookConfigureAPIError } from '../../errors/test-run/index'; +import { APIError } from '../../errors/runtime'; +import MESSAGE from '../../errors/runtime/message'; const DEFAULT_OPTIONS = { logRequestHeaders: false, @@ -14,10 +15,10 @@ const DEFAULT_OPTIONS = { stringifyResponseBody: false }; -class RequestLogger extends RequestHook { +class RequestLoggerImplementation extends RequestHook { constructor (requestFilterRuleInit, options) { options = Object.assign({}, DEFAULT_OPTIONS, options); - RequestLogger._assertLogOptions(options); + RequestLoggerImplementation._assertLogOptions(options); const configureResponseEventOptions = new ConfigureResponseEventOptions(options.logResponseHeaders, options.logResponseBody); @@ -30,10 +31,10 @@ class RequestLogger extends RequestHook { static _assertLogOptions (logOptions) { if (!logOptions.logRequestBody && logOptions.stringifyRequestBody) - throw new RequestHookConfigureAPIError(RequestLogger.name, 'Cannot stringify the request body because it is not logged. Specify { logRequestBody: true } in log options.'); + throw new APIError('RequestLogger', MESSAGE.requestHookConfigureAPIError, 'RequestLogger', 'Cannot stringify the request body because it is not logged. Specify { logRequestBody: true } in log options.'); if (!logOptions.logResponseBody && logOptions.stringifyResponseBody) - throw new RequestHookConfigureAPIError(RequestLogger.name, 'Cannot stringify the response body because it is not logged. Specify { logResponseBody: true } in log options.'); + throw new APIError('RequestLogger', MESSAGE.requestHookConfigureAPIError, 'RequestLogger', 'Cannot stringify the response body because it is not logged. Specify { logResponseBody: true } in log options.'); } onRequest (event) { @@ -120,6 +121,6 @@ class RequestLogger extends RequestHook { } export default function createRequestLogger (requestFilterRuleInit, logOptions) { - return new RequestLogger(requestFilterRuleInit, logOptions); + return new RequestLoggerImplementation(requestFilterRuleInit, logOptions); } diff --git a/src/api/request-hooks/request-mock.js b/src/api/request-hooks/request-mock.js index bdc14de7..1134d88f 100644 --- a/src/api/request-hooks/request-mock.js +++ b/src/api/request-hooks/request-mock.js @@ -1,6 +1,7 @@ import RequestHook from './hook'; import { ResponseMock, RequestFilterRule } from 'testcafe-hammerhead'; -import { RequestHookConfigureAPIError } from '../../errors/test-run/index'; +import { APIError } from '../../errors/runtime'; +import MESSAGE from '../../errors/runtime/message'; class RequestMock extends RequestHook { constructor () { @@ -21,7 +22,7 @@ class RequestMock extends RequestHook { // API onRequestTo (requestFilterRuleInit) { if (this.pendingRequestFilterRuleInit) - throw new RequestHookConfigureAPIError(RequestMock.name, "The 'respond' method was not called after 'onRequestTo'. You must call the 'respond' method to provide the mocked response."); + throw new APIError('onRequestTo', MESSAGE.requestHookConfigureAPIError, RequestMock.name, "The 'respond' method was not called after 'onRequestTo'. You must call the 'respond' method to provide the mocked response."); this.pendingRequestFilterRuleInit = requestFilterRuleInit; @@ -30,7 +31,7 @@ class RequestMock extends RequestHook { respond (body, statusCode, headers) { if (!this.pendingRequestFilterRuleInit) - throw new RequestHookConfigureAPIError(RequestMock.name, "The 'onRequestTo' method was not called before 'respond'. You must call the 'onRequestTo' method to provide the URL requests to which are mocked."); + throw new APIError('respond', MESSAGE.requestHookConfigureAPIError, RequestMock.name, "The 'onRequestTo' method was not called before 'respond'. You must call the 'onRequestTo' method to provide the URL requests to which are mocked."); const mock = new ResponseMock(body, statusCode, headers); const rule = new RequestFilterRule(this.pendingRequestFilterRuleInit); diff --git a/src/errors/runtime/message.js b/src/errors/runtime/message.js index db9199d6..289fa487 100644 --- a/src/errors/runtime/message.js +++ b/src/errors/runtime/message.js @@ -28,5 +28,6 @@ export default { invalidValueType: '{smthg} is expected to be a {type}, but it was {actual}.', unsupportedUrlProtocol: 'The specified "{url}" test page URL uses an unsupported {protocol}:// protocol. Only relative URLs or absolute URLs with http://, https:// and file:// protocols are supported.', unableToOpenBrowser: 'Was unable to open the browser "{alias}" due to error.\n\n{errMessage}', - testControllerProxyCantResolveTestRun: `Cannot implicitly resolve the test run in the context of which the test controller action should be executed. Use test function's 't' argument instead.` + testControllerProxyCantResolveTestRun: `Cannot implicitly resolve the test run in the context of which the test controller action should be executed. Use test function's 't' argument instead.`, + requestHookConfigureAPIError: 'There was an error while configuring the request hook:\n\n{requestHookName}: {errMsg}' }; diff --git a/src/errors/test-run/index.js b/src/errors/test-run/index.js index fbb0ce68..6c741d25 100644 --- a/src/errors/test-run/index.js +++ b/src/errors/test-run/index.js @@ -477,14 +477,3 @@ export class SetNativeDialogHandlerCodeWrongTypeError extends TestRunErrorBase { this.actualType = actualType; } } - -// Request Hooks -export class RequestHookConfigureAPIError extends TestRunErrorBase { - constructor (requestHookName, errMsg) { - super(TYPE.requestHookConfigureAPIError); - - this.requestHookName = requestHookName; - this.errMsg = errMsg; - } -} - diff --git a/src/errors/test-run/templates.js b/src/errors/test-run/templates.js index 04e00e90..e33fc4e8 100644 --- a/src/errors/test-run/templates.js +++ b/src/errors/test-run/templates.js @@ -262,12 +262,6 @@ export default { ${err.errMsg} `), - [TYPE.requestHookConfigureAPIError]: err => markup(err, ` - There was an error while configuring the request hook: - - ${err.requestHookName}: ${err.errMsg} - `), - [TYPE.assertionUnawaitedPromiseError]: err => markup(err, ` Attempted to run assertions on a Promise object. Did you forget to await it? If not, pass "{ allowUnawaitedPromise: true }" to the assertion options. `) diff --git a/src/errors/test-run/type.js b/src/errors/test-run/type.js index f6ea778a..2186b5fb 100644 --- a/src/errors/test-run/type.js +++ b/src/errors/test-run/type.js @@ -57,6 +57,5 @@ export default { invalidElementScreenshotDimensionsError: 'invalidElementScreenshotDimensionsError', roleSwitchInRoleInitializerError: 'roleSwitchInRoleInitializerError', assertionExecutableArgumentError: 'assertionExecutableArgumentError', - assertionUnawaitedPromiseError: 'assertionUnawaitedPromiseError', - requestHookConfigureAPIError: 'requestHookConfigureAPIError' + assertionUnawaitedPromiseError: 'assertionUnawaitedPromiseError' }; diff --git a/test/server/api-test.js b/test/server/api-test.js index 68fe8510..77dbdc42 100644 --- a/test/server/api-test.js +++ b/test/server/api-test.js @@ -1336,4 +1336,118 @@ describe('API', function () { }); }); }); + + describe('Request Hooks', () => { + describe('Should raise errors for wrong RequestLogger construction', () => { + it('Cannot stringify the request body', () => { + const testFile = resolve('test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-request-body.js'); + + return compile(testFile) + .then(() => { + throw new Error('Promise rejection expected'); + }) + .catch(err => { + assertAPIError(err, { + stackTop: testFile, + + message: 'Cannot prepare tests due to an error.\n\n' + + 'There was an error while configuring the request hook:\n\n' + + 'RequestLogger: Cannot stringify the request body because it is not logged. Specify { logRequestBody: true } in log options.', + + callsite: ' 1 |import { RequestLogger } from \'testcafe\';\n' + + ' 2 |\n' + + ' 3 |fixture `Fixture`;\n' + + ' 4 |\n' + + " > 5 |const logger = new RequestLogger('', {\n" + + ' 6 | logRequestBody: false,\n' + + ' 7 | stringifyRequestBody: true\n' + + ' 8 |});' + }); + }); + }); + + it('Cannot stringify the response body', () => { + const testFile = resolve('test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-response-body.js'); + + return compile(testFile) + .then(() => { + throw new Error('Promise rejection expected'); + }) + .catch(err => { + assertAPIError(err, { + stackTop: testFile, + + message: 'Cannot prepare tests due to an error.\n\n' + + 'There was an error while configuring the request hook:\n\n' + + 'RequestLogger: Cannot stringify the response body because it is not logged. Specify { logResponseBody: true } in log options.', + + callsite: ' 1 |import { RequestLogger } from \'testcafe\';\n' + + ' 2 |\n' + + ' 3 |fixture `Fixture`;\n' + + ' 4 |\n' + + " > 5 |const logger = new RequestLogger('', {\n" + + ' 6 | logResponseBody: false,\n' + + ' 7 | stringifyResponseBody: true\n' + + ' 8 |});' + }); + }); + }); + }); + + describe('Should raise errors for wrong RequestMock api order call', () => { + it("The 'respond' method was not called after 'onRequestTo'", () => { + const testFile = resolve('test/server/data/test-suites/request-hooks/request-mock/respond-was-not-called-after-on-request-to.js'); + + return compile(testFile) + .then(() => { + throw new Error('Promise rejection expected'); + }) + .catch(err => { + assertAPIError(err, { + stackTop: testFile, + + message: 'Cannot prepare tests due to an error.\n\n' + + 'There was an error while configuring the request hook:\n\n' + + "RequestMock: The 'respond' method was not called after 'onRequestTo'. You must call the 'respond' method to provide the mocked response.", + + callsite: ' 1 |import { RequestMock } from \'testcafe\';\n' + + ' 2 |\n' + + ' 3 |fixture `Fixture`;\n' + + ' 4 |\n' + + ' > 5 |const mock = RequestMock().onRequestTo({}).onRequestTo({});\n' + + ' 6 |\n' + + ' 7 |test(\'test\', async t => {});\n' + + ' 8 |\n' + }); + }); + }); + + it("The 'onRequestTo' method was not called before 'respond'", () => { + const testFile = resolve('test/server/data/test-suites/request-hooks/request-mock/on-request-to-was-not-called-before-respond.js'); + + return compile(testFile) + .then(() => { + throw new Error('Promise rejection expected'); + }) + .catch(err => { + assertAPIError(err, { + stackTop: testFile, + + message: 'Cannot prepare tests due to an error.\n\n' + + 'There was an error while configuring the request hook:\n\n' + + "RequestMock: The 'onRequestTo' method was not called before 'respond'. You must call the 'onRequestTo' method to provide the URL requests to which are mocked.", + + callsite: ' 1 |import { RequestMock } from \'testcafe\';\n' + + ' 2 |\n' + + ' 3 |fixture `Fixture`;\n' + + ' 4 |\n' + + ' > 5 |const mock = RequestMock().respond(() => {}).onRequestTo({});\n' + + ' 6 |\n' + + ' 7 |test(\'test\', async t => {});\n' + + ' 8 |' + }); + }); + }); + }); + }); }); diff --git a/test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-request-body.js b/test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-request-body.js new file mode 100644 index 00000000..de01617a --- /dev/null +++ b/test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-request-body.js @@ -0,0 +1,10 @@ +import { RequestLogger } from 'testcafe'; + +fixture `Fixture`; + +const logger = new RequestLogger('', { + logRequestBody: false, + stringifyRequestBody: true +}); + +test('test', async () => {}); diff --git a/test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-response-body.js b/test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-response-body.js new file mode 100644 index 00000000..7ed2ea1f --- /dev/null +++ b/test/server/data/test-suites/request-hooks/request-logger/cannot-stringify-response-body.js @@ -0,0 +1,10 @@ +import { RequestLogger } from 'testcafe'; + +fixture `Fixture`; + +const logger = new RequestLogger('', { + logResponseBody: false, + stringifyResponseBody: true +}); + +test('test', async () => {}); diff --git a/test/server/data/test-suites/request-hooks/request-mock/on-request-to-was-not-called-before-respond.js b/test/server/data/test-suites/request-hooks/request-mock/on-request-to-was-not-called-before-respond.js new file mode 100644 index 00000000..297fe7c3 --- /dev/null +++ b/test/server/data/test-suites/request-hooks/request-mock/on-request-to-was-not-called-before-respond.js @@ -0,0 +1,7 @@ +import { RequestMock } from 'testcafe'; + +fixture `Fixture`; + +const mock = RequestMock().respond(() => {}).onRequestTo({}); + +test('test', async t => {}); diff --git a/test/server/data/test-suites/request-hooks/request-mock/respond-was-not-called-after-on-request-to.js b/test/server/data/test-suites/request-hooks/request-mock/respond-was-not-called-after-on-request-to.js new file mode 100644 index 00000000..f672f3a1 --- /dev/null +++ b/test/server/data/test-suites/request-hooks/request-mock/respond-was-not-called-after-on-request-to.js @@ -0,0 +1,7 @@ +import { RequestMock } from 'testcafe'; + +fixture `Fixture`; + +const mock = RequestMock().onRequestTo({}).onRequestTo({}); + +test('test', async t => {}); diff --git a/test/server/request-hooks-test.js b/test/server/request-hooks-test.js index cf5b5e13..da940298 100644 --- a/test/server/request-hooks-test.js +++ b/test/server/request-hooks-test.js @@ -6,10 +6,7 @@ const RequestLogger = exportableLib.RequestLogger; const RequestHook = exportableLib.RequestHook; const Promise = require('pinkie'); const nanoid = require('nanoid'); - -const assertThrow = require('./helpers/assert-error').assertThrow; -const expect = require('chai').expect; -const noop = require('lodash').noop; +const expect = require('chai').expect; describe('RequestLogger', () => { const createProxyRequestEventMock = (testRunId, requestId) => { @@ -102,32 +99,6 @@ describe('RequestLogger', () => { }); }); - describe('Assert log options', () => { - it('Related to request body', () => { - assertThrow(() => { - RequestLogger('http://example.com', { stringifyRequestBody: true }); - }, { - isTestCafeError: true, - requestHookName: 'RequestLogger', - errMsg: 'Cannot stringify the request body because it is not logged. Specify { logRequestBody: true } in log options.', - type: 'requestHookConfigureAPIError', - callsite: null - }); - }); - - it('Related to response body', () => { - assertThrow(() => { - RequestLogger('http://example.com', { stringifyResponseBody: true }); - }, { - isTestCafeError: true, - requestHookName: 'RequestLogger', - errMsg: 'Cannot stringify the response body because it is not logged. Specify { logResponseBody: true } in log options.', - type: 'requestHookConfigureAPIError', - callsite: null - }); - }); - }); - it('.clear method', () => { const logger = new RequestLogger('http://example.com'); @@ -206,46 +177,18 @@ describe('RequestLogger', () => { }); describe('RequestMock', () => { - describe('Throwing errors', () => { - describe('Chaining', () => { - it('.respond().onRequestTo()', () => { - assertThrow(() => { - RequestMock().respond(noop).onRequestTo({}); - }, { - isTestCafeError: true, - requestHookName: 'RequestMock', - errMsg: "The 'onRequestTo' method was not called before 'respond'. You must call the 'onRequestTo' method to provide the URL requests to which are mocked.", - type: 'requestHookConfigureAPIError', - callsite: null - }); - }); - - it('onRequestTo().onRequestTo()', () => { - assertThrow(() => { - RequestMock().onRequestTo({}).onRequestTo({}); - }, { - isTestCafeError: true, - requestHookName: 'RequestMock', - errMsg: "The 'respond' method was not called after 'onRequestTo'. You must call the 'respond' method to provide the mocked response.", - type: 'requestHookConfigureAPIError', - callsite: null - }); - }); + describe('Throwing errors on construction', () => { + it('Without configure', () => { + expect(() => { + RequestMock(); + }).to.not.throw; }); - - describe('Construction', () => { - it('Without configure', () => { - expect(() => { - RequestMock(); - }).to.not.throw; - }); - it('With configure', () => { - expect(() => { - RequestMock() - .onRequestTo('http://example.com') - .respond(''); - }).to.not.throw; - }); + it('With configure', () => { + expect(() => { + RequestMock() + .onRequestTo('http://example.com') + .respond(''); + }).to.not.throw; }); }); diff --git a/test/server/test-run-error-formatting-test.js b/test/server/test-run-error-formatting-test.js index 77233695..49aea84b 100644 --- a/test/server/test-run-error-formatting-test.js +++ b/test/server/test-run-error-formatting-test.js @@ -61,7 +61,6 @@ var InvalidElementScreenshotDimensionsError = require('../../lib/error var SetTestSpeedArgumentError = require('../../lib/errors/test-run').SetTestSpeedArgumentError; var RoleSwitchInRoleInitializerError = require('../../lib/errors/test-run').RoleSwitchInRoleInitializerError; var ActionRoleArgumentError = require('../../lib/errors/test-run').ActionRoleArgumentError; -var RequestHookConfigureAPIError = require('../../lib/errors/test-run').RequestHookConfigureAPIError; var TEST_FILE_STACK_ENTRY_RE = new RegExp('\\s*\\n?\\(' + escapeRe(require.resolve('./data/test-callsite')), 'g'); @@ -337,10 +336,6 @@ describe('Error formatting', function () { assertErrorMessage('assertion-executable-argument-error', new AssertionExecutableArgumentError('actual', '1 + temp', 'Unexpected identifier')); }); - it('Should format "requestHookConfigureAPIError"', () => { - assertErrorMessage('request-hook-configure-api-error', new RequestHookConfigureAPIError('RequestMock', 'test error message')); - }); - it('Should format "assertionUnawaitedPromiseError"', function () { assertErrorMessage('assertion-unawaited-promise-error', new AssertionUnawaitedPromiseError(testCallsite)); }); From 4b5547a7c11cf6772aaffc4a9a78d622f403aea7 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 11 Jul 2018 11:48:24 +0300 Subject: [PATCH 014/184] Bump version (v0.20.5-alpha.1) (#2611) --- .publishrc | 2 +- package.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.publishrc b/.publishrc index 5727c783..2414a453 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "latest", + "publishTag": "alpha", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index 42c1a125..57d32e78 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.20.4", + "version": "0.20.5-alpha.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" @@ -105,8 +105,8 @@ "sanitize-filename": "^1.6.0", "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", - "testcafe-browser-tools": "1.6.3", - "testcafe-hammerhead": "14.1.1", + "testcafe-browser-tools": "1.6.4", + "testcafe-hammerhead": "14.2.0", "testcafe-legacy-api": "3.1.7", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", From 3cd7b7d61359a6200e8204534b1a3d25ba6c5435 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Wed, 11 Jul 2018 17:58:28 +0300 Subject: [PATCH 015/184] Added a clear message about failed CORS validation requests (close #2482) (#2613) * add clear message about failed CORS validation requests (close #2482) * tmp * formatting * rename * add condition * fix lint --- package.json | 2 +- src/api/request-hooks/hook.js | 2 ++ src/api/request-hooks/request-mock.js | 8 +++++-- src/notifications/warning-message.js | 3 ++- src/test-run/index.js | 6 +++++ .../pages/failed-cors-validation.html | 24 +++++++++++++++++++ .../api/es-next/request-hooks/test.js | 17 +++++++++++-- .../basic.js} | 0 .../request-mock/failed-cors-validation.js | 15 ++++++++++++ 9 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 test/functional/fixtures/api/es-next/request-hooks/pages/failed-cors-validation.html rename test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/{request-mock.js => request-mock/basic.js} (100%) create mode 100644 test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-mock/failed-cors-validation.js diff --git a/package.json b/package.json index 57d32e78..a5d5d8fb 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.4", - "testcafe-hammerhead": "14.2.0", + "testcafe-hammerhead": "14.2.1", "testcafe-legacy-api": "3.1.7", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", diff --git a/src/api/request-hooks/hook.js b/src/api/request-hooks/hook.js index da1ed8f9..4ee026e2 100644 --- a/src/api/request-hooks/hook.js +++ b/src/api/request-hooks/hook.js @@ -6,6 +6,8 @@ export default class RequestHook { this.requestFilterRules = this._prepareRequestFilterRules(requestFilterRules); this._instantiatedRequestFilterRules = []; this.responseEventConfigureOpts = responseEventConfigureOpts; + + this.warningLog = null; } _prepareRequestFilterRules (rules) { diff --git a/src/api/request-hooks/request-mock.js b/src/api/request-hooks/request-mock.js index 1134d88f..8f246f9f 100644 --- a/src/api/request-hooks/request-mock.js +++ b/src/api/request-hooks/request-mock.js @@ -1,7 +1,8 @@ import RequestHook from './hook'; -import { ResponseMock, RequestFilterRule } from 'testcafe-hammerhead'; +import { ResponseMock, RequestFilterRule, SAME_ORIGIN_CHECK_FAILED_STATUS_CODE } from 'testcafe-hammerhead'; import { APIError } from '../../errors/runtime'; import MESSAGE from '../../errors/runtime/message'; +import WARNING_MESSAGE from '../../notifications/warning-message'; class RequestMock extends RequestHook { constructor () { @@ -17,7 +18,10 @@ class RequestMock extends RequestHook { event.setMock(mock); } - onResponse () {} + onResponse (event) { + if (event.statusCode === SAME_ORIGIN_CHECK_FAILED_STATUS_CODE) + this.warningLog.addWarning(WARNING_MESSAGE.requestMockCORSValidationFailed, RequestMock.name, event._requestFilterRule); + } // API onRequestTo (requestFilterRuleInit) { diff --git a/src/notifications/warning-message.js b/src/notifications/warning-message.js index 2a521f82..ea1f5c13 100644 --- a/src/notifications/warning-message.js +++ b/src/notifications/warning-message.js @@ -8,5 +8,6 @@ export default { resizeNotSupportedByBrowserProvider: 'The window resize functionality is not supported by the "{providerName}" browser provider.', maximizeNotSupportedByBrowserProvider: 'The window maximization functionality is not supported by the "{providerName}" browser provider.', resizeError: 'Was unable to resize the window due to an error.\n\n{errMessage}', - maximizeError: 'Was unable to maximize the window due to an error.\n\n{errMessage}' + maximizeError: 'Was unable to maximize the window due to an error.\n\n{errMessage}', + requestMockCORSValidationFailed: '{RequestHook}: CORS validation failed for a request specified as {requestFilterRule}' }; diff --git a/src/test-run/index.js b/src/test-run/index.js index 162972a8..73bed7ea 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -110,6 +110,8 @@ export default class TestRun extends EventEmitter { this.quarantine = null; + this.warningLog = warningLog; + this.injectable.scripts.push('/testcafe-core.js'); this.injectable.scripts.push('/testcafe-ui.js'); this.injectable.scripts.push('/testcafe-automation.js'); @@ -150,6 +152,8 @@ export default class TestRun extends EventEmitter { } _initRequestHook (hook) { + hook.warningLog = this.warningLog; + hook._instantiateRequestFilterRules(); hook._instantiatedRequestFilterRules.forEach(rule => { this.session.addRequestEventListeners(rule, { @@ -161,6 +165,8 @@ export default class TestRun extends EventEmitter { } _disposeRequestHook (hook) { + hook.warningLog = null; + hook._instantiatedRequestFilterRules.forEach(rule => { this.session.removeRequestEventListeners(rule); }); diff --git a/test/functional/fixtures/api/es-next/request-hooks/pages/failed-cors-validation.html b/test/functional/fixtures/api/es-next/request-hooks/pages/failed-cors-validation.html new file mode 100644 index 00000000..c61f3d9a --- /dev/null +++ b/test/functional/fixtures/api/es-next/request-hooks/pages/failed-cors-validation.html @@ -0,0 +1,24 @@ + + + + + Title + + + + Request status:Not send + + + diff --git a/test/functional/fixtures/api/es-next/request-hooks/test.js b/test/functional/fixtures/api/es-next/request-hooks/test.js index 03dab87e..fbd34abf 100644 --- a/test/functional/fixtures/api/es-next/request-hooks/test.js +++ b/test/functional/fixtures/api/es-next/request-hooks/test.js @@ -1,6 +1,19 @@ +const expect = require('chai').expect; + describe('Request Hooks', () => { - it('RequestMock', () => { - return runTests('./testcafe-fixtures/request-mock.js', 'Basic', { only: 'chrome' }); + describe('RequestMock', () => { + it('Basic', () => { + return runTests('./testcafe-fixtures/request-mock/basic.js', 'Basic', { only: 'chrome' }); + }); + + it('Request failed the CORS validation', () => { + return runTests('./testcafe-fixtures/request-mock/failed-cors-validation.js', 'Failed CORS validation', { only: 'chrome' }) + .then(() => { + expect(testReport.warnings).eql([ + 'RequestMock: CORS validation failed for a request specified as { url: "http://dummy-url.com/get" }' + ]); + }); + }); }); describe('RequestLogger', () => { diff --git a/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-mock.js b/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-mock/basic.js similarity index 100% rename from test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-mock.js rename to test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-mock/basic.js diff --git a/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-mock/failed-cors-validation.js b/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-mock/failed-cors-validation.js new file mode 100644 index 00000000..bba73c42 --- /dev/null +++ b/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-mock/failed-cors-validation.js @@ -0,0 +1,15 @@ +import { Selector, RequestMock } from 'testcafe'; + +const mock = RequestMock() + .onRequestTo('http://dummy-url.com/get') + .respond({ prop: 'value' }, 200, { 'not-specify-cors-headers': true }); + +fixture `Failed CORS validation` + .page('http://localhost:3000/fixtures/api/es-next/request-hooks/pages/failed-cors-validation.html') + .requestHooks(mock); + +test('Failed CORS validation', async t => { + await t + .click('#btnSendFetch') + .expect(Selector('#requestStatusText').textContent).eql('Sent'); +}); From d2cbf9838c981b9b1409e4231f04e6acda57fd51 Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Thu, 12 Jul 2018 16:54:02 +0300 Subject: [PATCH 016/184] [docs] describe new properties of testRunInfo (#2605) --- .../reporter-plugin/reporter-methods.md | 53 ++++++++++++++----- .../using-testcafe/command-line-interface.md | 7 +-- .../programming-interface/runner.md | 4 +- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/docs/articles/documentation/extending-testcafe/reporter-plugin/reporter-methods.md b/docs/articles/documentation/extending-testcafe/reporter-plugin/reporter-methods.md index f775e2bf..0aadbc24 100644 --- a/docs/articles/documentation/extending-testcafe/reporter-plugin/reporter-methods.md +++ b/docs/articles/documentation/extending-testcafe/reporter-plugin/reporter-methods.md @@ -6,7 +6,12 @@ checked: false --- # Reporter Methods -You should implement the following methods to create a [reporter](README.md#implementing-the-reporter). +You should implement the following methods to create a [reporter](README.md#implementing-the-reporter): + +* [reportTaskStart](#reporttaskstart) +* [reportFixtureStart](#reportfixturestart) +* [reportTestDone](#reporttestdone) +* [reportTaskDone](#reporttaskdone) > You can use the [helper methods and libraries](helpers.md) within the reporter methods to output the required data. @@ -81,19 +86,9 @@ reportTestDone (name, testRunInfo, meta) Parameter | Type | Description ------------- | ------ | ------------------------------------------------------------- `name` | String | The test name. -`testRunInfo` | Object | The object providing detailed information about the test run. +`testRunInfo` | Object | The [testRunInfo](#testruninfo-object) object. `meta` | Object | The test metadata. See [Specifying Testing Metadata](../../test-api/test-code-structure.md#specifying-testing-metadata) for more information. -The `testRunInfo` object has the following properties. - -Property | Type | Description ----------------- | ---------------- | -------------------------------------------------------- -`errs` | Array or Strings | An array of errors that occurred during a test run. -`durationMs` | Number | The time spent on test execution (in milliseconds). -`unstable` | Boolean | Specifies if the test is marked as unstable. -`screenshotPath` | String | The directory path where screenshots have been saved to. -`skipped` | Boolean | Specifies if the test was skipped. - **Example** ```js @@ -124,6 +119,40 @@ reportTestDone (name, testRunInfo, meta) { //=> skipped First fixture - Fourth test in first fixture ``` +### testRunInfo Object + +The `testRunInfo` object provides detailed information about the test run. The object has the following properties: + +Property | Type | Description +------------------- | ---------------- | -------------------------------------------------------- +`errs` | Array of Strings | An array of errors that occurred during the test run. +`durationMs` | Number | The time spent on test execution (in milliseconds). +`unstable` | Boolean | Specifies if the test is marked as unstable. +`screenshotPath` | String | The directory path where screenshots are saved to. +`screenshots` | Array of Objects | An array of [screenshot](#screenshots-object) objects. +`quarantine` | Object | A [quarantine](#quarantine-object) object. +`skipped` | Boolean | Specifies if the test was skipped. + +### screenshots Object + +The `screenshot` object provides information about the screenshot captured during the test run. The object has the following properties: + +Property | Type | Description +------------------- | ---------------- | -------------------------------------------------------- +`screenshotPath` | String | The directory path where the screenshot was saved to. +`thumbnailPath` | String | The directory path where the screenshot's thumbnail was saved to. +`userAgent` | String | The user agent string of the browser where the screenshot was captured. +`quarantineAttempt` | Number | The [quarantine](../../using-testcafe/programming-interface/runner.md#quarantine-mode) attempt's number. +`takenOnFail` | Boolean | Specifies if the screenshot was captured when the test failed. + +### quarantine Object + +The `quarantine` object provides information about [quarantine](../../using-testcafe/programming-interface/runner.md#quarantine-mode)'s attempts in the form of key-value pairs. + +Key | Value +----------------------------------| ------------------------------------------------ +The quarantine attempt's number. | The object that provides information about the attempt. The object has the boolean `passed` property that specifies if the test passed in the current attempt. + ## reportTaskDone Fires when the task ends. diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 73c79b72..a6886d60 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -288,12 +288,7 @@ testcafe all tests/sample-fixture.js -S -s screenshots ### -q, --quarantine-mode -Enables the quarantine mode for tests that fail. -In this mode, a failed test is executed several times. -The test result depends on the outcome (*passed* or *failed*) that occurs most often. -That is, if the test fails on most attempts, the result is *failed*. - -If the test result differs between test runs, the test is marked as unstable. +Enables the [quarantine mode](programming-interface/runner.md#quarantine-mode) for tests that fail. ```sh testcafe all tests/sample-fixture.js -q diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index 925fc2d7..64f0f6be 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -462,9 +462,7 @@ You can also cancel all pending tasks at once using the [runner.stop](#stop) fun The quarantine mode is designed to isolate *non-deterministic* tests (that is, tests that sometimes pass and fail without a clear reason) from the rest of the test base (*healthy* tests). -When quarantine mode is enabled, tests are not marked as *failed* after the first unsuccessful run but rather sent to quarantine. -After that, these tests are run again several times. The outcome of the most runs (*passed* or *failed*) is recorded as the test result. -A test is separately marked *unstable* if the outcome varies between runs. The test counts the run that was quarantined. +In this mode, a failed test is executed several times. The test result depends on the outcome (passed or failed) that occurs most often. That is, if the test fails on most attempts, the result is failed. If the test result differs between test runs, the test is marked as unstable. To learn more about non-deterministic tests, see Martin Fowler's [Eradicating Non-Determinism in Tests](http://martinfowler.com/articles/nonDeterminism.html) article. From da2f66263da36c93b2d6d69c5f317291cce9a4f4 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Sat, 14 Jul 2018 12:24:40 +0300 Subject: [PATCH 017/184] Implemented development mode with non-minified client scripts (#2616) * client-scripts-template-render * gulp * tmp2 * fix tests * pass flag to the proxy * remove through2 * rename '--development-mode' to '--dev' --- Gulpfile.js | 41 +++++++++++++++++-------- package.json | 4 +-- src/cli/argument-parser.js | 1 + src/cli/cli.js | 2 +- src/index.js | 4 +-- src/testcafe.js | 33 ++++++++++---------- test/server/browser-connection-test.js | 5 --- test/server/cli-argument-parser-test.js | 4 ++- 8 files changed, 55 insertions(+), 39 deletions(-) diff --git a/Gulpfile.js b/Gulpfile.js index cc7eea1a..6447d580 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -11,9 +11,10 @@ var mocha = require('gulp-mocha-simple'); var mustache = require('gulp-mustache'); var rename = require('gulp-rename'); var webmake = require('gulp-webmake'); -var gulpif = require('gulp-if'); var uglify = require('gulp-uglify'); var ll = require('gulp-ll-next'); +const clone = require('gulp-clone'); +const mergeStreams = require('merge-stream'); var del = require('del'); var fs = require('fs'); var path = require('path'); @@ -61,10 +62,10 @@ var CLIENT_TESTS_SETTINGS_BASE = { scripts: [ { src: '/async.js', path: 'test/client/vendor/async.js' }, - { src: '/hammerhead.js', path: 'node_modules/testcafe-hammerhead/lib/client/hammerhead.js' }, - { src: '/core.js', path: 'lib/client/core/index.js' }, - { src: '/ui.js', path: 'lib/client/ui/index.js' }, - { src: '/automation.js', path: 'lib/client/automation/index.js' }, + { src: '/hammerhead.js', path: 'node_modules/testcafe-hammerhead/lib/client/hammerhead.min.js' }, + { src: '/core.js', path: 'lib/client/core/index.min.js' }, + { src: '/ui.js', path: 'lib/client/ui/index.min.js' }, + { src: '/automation.js', path: 'lib/client/automation/index.min.js' }, { src: '/driver.js', path: 'lib/client/driver/index.js' }, { src: '/legacy-runner.js', path: 'node_modules/testcafe-legacy-api/lib/client/index.js' }, { src: '/before-test.js', path: 'test/client/before-test.js' } @@ -225,25 +226,41 @@ gulp.step('client-scripts-bundle', function () { return { code: transformed.code.replace(/^('|")use strict('|");?/, '') }; } })) - .pipe(gulpif(!DEV_MODE, uglify())) .pipe(gulp.dest('lib')); }); gulp.step('client-scripts-templates-render', function () { - return gulp + const scripts = gulp .src([ 'src/client/core/index.js.wrapper.mustache', 'src/client/ui/index.js.wrapper.mustache', 'src/client/automation/index.js.wrapper.mustache', 'src/client/driver/index.js.wrapper.mustache' ], { base: 'src' }) - .pipe(rename(wrapperPath => { - wrapperPath.extname = ''; - wrapperPath.basename = wrapperPath.basename.replace('.wrapper', ''); + .pipe(rename(file => { + file.extname = ''; + file.basename = file.basename.replace('.js.wrapper', ''); + })) + .pipe(data(file => { + const sourceFilePath = path.resolve('lib', file.relative + '.js'); + + return { + source: fs.readFileSync(sourceFilePath) + }; })) - .pipe(data(file => ({ source: fs.readFileSync(path.resolve('lib', file.relative)) }))) .pipe(mustache()) - .pipe(gulpif(!DEV_MODE, uglify())) + .pipe(rename(file => { + file.extname = '.js'; + })); + + const bundledScripts = scripts + .pipe(clone()) + .pipe(uglify()) + .pipe(rename(file => { + file.extname = '.min.js'; + })); + + return mergeStreams(scripts, bundledScripts) .pipe(gulp.dest('lib')); }); diff --git a/package.json b/package.json index a5d5d8fb..85513ecc 100644 --- a/package.json +++ b/package.json @@ -137,10 +137,10 @@ "express-ntlm": "^2.1.5", "gulp": "^4.0.0", "gulp-babel": "^6.1.1", + "gulp-clone": "^2.0.1", "gulp-eslint": "^4.0.0", "gulp-gh-pages": "^0.5.4", "gulp-git": "^2.4.2", - "gulp-if": "^2.0.0", "gulp-less": "^4.0.0", "gulp-ll-next": "^2.1.0", "gulp-mocha": "^5.0.0", @@ -157,7 +157,7 @@ "js-yaml": "^3.6.1", "license-checker": "^20.0.0", "markdownlint": ">=0.0.8", - "merge-stream": "^1.0.0", + "merge-stream": "^1.0.1", "minimist": "^1.2.0", "multer": "^1.1.0", "npm-auditor": "^1.1.1", diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index b0408d3e..0d80e794 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -110,6 +110,7 @@ export default class CLIArgumentParser { .option('--ssl', 'specify SSL options to run TestCafe proxy server over the HTTPS protocol') .option('--proxy-bypass ', 'specify a comma-separated list of rules that define URLs accessed bypassing the proxy server') .option('--disable-page-reloads', 'disable page reloads between tests') + .option('--dev', 'enables the mechanisms for error logging and diagnosing') .option('--qr-code', 'outputs QR-code that repeats URLs used to connect the remote browsers') // NOTE: these options will be handled by chalk internally diff --git a/src/cli/cli.js b/src/cli/cli.js index ed526cd7..93feb81d 100644 --- a/src/cli/cli.js +++ b/src/cli/cli.js @@ -72,7 +72,7 @@ async function runTests (argParser) { log.showSpinner(); - var testCafe = await createTestCafe(opts.hostname, port1, port2, opts.ssl); + const testCafe = await createTestCafe(opts.hostname, port1, port2, opts.ssl, opts.dev); var concurrency = argParser.concurrency || 1; var remoteBrowsers = await remotesWizard(testCafe, argParser.remoteCount, opts.qrCode); var browsers = argParser.browsers.concat(remoteBrowsers); diff --git a/src/index.js b/src/index.js index fb9aff6d..2f3b7abc 100644 --- a/src/index.js +++ b/src/index.js @@ -36,14 +36,14 @@ async function getValidPort (port) { } // API -async function createTestCafe (hostname, port1, port2, sslOptions) { +async function createTestCafe (hostname, port1, port2, sslOptions, developmentMode) { [hostname, port1, port2] = await Promise.all([ getValidHostname(hostname), getValidPort(port1), getValidPort(port2) ]); - var testcafe = new TestCafe(hostname, port1, port2, sslOptions); + const testcafe = new TestCafe(hostname, port1, port2, sslOptions, developmentMode); setupExitHook(cb => testcafe.close().then(cb)); diff --git a/src/testcafe.js b/src/testcafe.js index 2c130a06..d49c5917 100644 --- a/src/testcafe.js +++ b/src/testcafe.js @@ -8,34 +8,35 @@ import browserProviderPool from './browser/provider/pool'; import Runner from './runner'; // Const -const CORE_SCRIPT = read('./client/core/index.js'); -const DRIVER_SCRIPT = read('./client/driver/index.js'); -const UI_SCRIPT = read('./client/ui/index.js'); -const AUTOMATION_SCRIPT = read('./client/automation/index.js'); -const UI_STYLE = read('./client/ui/styles.css'); -const UI_SPRITE = read('./client/ui/sprite.png', true); -const FAVICON = read('./client/ui/favicon.ico', true); - +const UI_STYLE = read('./client/ui/styles.css'); +const UI_SPRITE = read('./client/ui/sprite.png', true); +const FAVICON = read('./client/ui/favicon.ico', true); export default class TestCafe { - constructor (hostname, port1, port2, sslOptions) { + constructor (hostname, port1, port2, sslOptions, developmentMode) { this.closed = false; - this.proxy = new Proxy(hostname, port1, port2, sslOptions); + this.proxy = new Proxy(hostname, port1, port2, sslOptions, developmentMode); this.browserConnectionGateway = new BrowserConnectionGateway(this.proxy); this.runners = []; - this._registerAssets(); + this._registerAssets(developmentMode); } - _registerAssets () { - this.proxy.GET('/testcafe-core.js', { content: CORE_SCRIPT, contentType: 'application/x-javascript' }); - this.proxy.GET('/testcafe-driver.js', { content: DRIVER_SCRIPT, contentType: 'application/x-javascript' }); + _registerAssets (developmentMode) { + const scriptNameSuffix = developmentMode ? 'js' : 'min.js'; + const coreScript = read(`./client/core/index.${scriptNameSuffix}`); + const driverScript = read(`./client/driver/index.${scriptNameSuffix}`); + const uiScript = read(`./client/ui/index.${scriptNameSuffix}`); + const automationScript = read(`./client/automation/index.${scriptNameSuffix}`); + + this.proxy.GET('/testcafe-core.js', { content: coreScript, contentType: 'application/x-javascript' }); + this.proxy.GET('/testcafe-driver.js', { content: driverScript, contentType: 'application/x-javascript' }); this.proxy.GET('/testcafe-legacy-runner.js', { content: LEGACY_RUNNER_SCRIPT, contentType: 'application/x-javascript' }); - this.proxy.GET('/testcafe-automation.js', { content: AUTOMATION_SCRIPT, contentType: 'application/x-javascript' }); - this.proxy.GET('/testcafe-ui.js', { content: UI_SCRIPT, contentType: 'application/x-javascript' }); + this.proxy.GET('/testcafe-automation.js', { content: automationScript, contentType: 'application/x-javascript' }); + this.proxy.GET('/testcafe-ui.js', { content: uiScript, contentType: 'application/x-javascript' }); this.proxy.GET('/testcafe-ui-sprite.png', { content: UI_SPRITE, contentType: 'image/png' }); this.proxy.GET('/favicon.ico', { content: FAVICON, contentType: 'image/x-icon' }); diff --git a/test/server/browser-connection-test.js b/test/server/browser-connection-test.js index 3f0c9580..176ee8d3 100644 --- a/test/server/browser-connection-test.js +++ b/test/server/browser-connection-test.js @@ -24,7 +24,6 @@ describe('Browser connection', function () { } }; - // Fixture setup/teardown before(function () { this.timeout(20000); @@ -47,8 +46,6 @@ describe('Browser connection', function () { return testCafe.close(); }); - - // Test setup/teardown beforeEach(function () { return testCafe .createBrowserConnection() @@ -62,8 +59,6 @@ describe('Browser connection', function () { connection.close(); }); - - // Tests it('Should fire "ready" event and redirect to idle page once established', function () { var eventFired = false; diff --git a/test/server/cli-argument-parser-test.js b/test/server/cli-argument-parser-test.js index dda2ff54..03d3dba4 100644 --- a/test/server/cli-argument-parser-test.js +++ b/test/server/cli-argument-parser-test.js @@ -386,7 +386,7 @@ describe('CLI argument parser', function () { }); it('Should parse command line arguments', function () { - return parse('-r list -S -q -e --hostname myhost --proxy localhost:1234 --proxy-bypass localhost:5678 --qr-code --app run-app --speed 0.5 --debug-on-fail --disable-page-reloads ie test/server/data/file-list/file-1.js') + return parse('-r list -S -q -e --hostname myhost --proxy localhost:1234 --proxy-bypass localhost:5678 --qr-code --app run-app --speed 0.5 --debug-on-fail --disable-page-reloads --dev ie test/server/data/file-list/file-1.js') .then(function (parser) { expect(parser.browsers).eql(['ie']); expect(parser.src).eql([path.resolve(process.cwd(), 'test/server/data/file-list/file-1.js')]); @@ -398,6 +398,7 @@ describe('CLI argument parser', function () { expect(parser.opts.quarantineMode).to.be.ok; expect(parser.opts.skipJsErrors).to.be.ok; expect(parser.opts.disablePageReloads).to.be.ok; + expect(parser.opts.dev).to.be.ok; expect(parser.opts.speed).eql(0.5); expect(parser.opts.qrCode).to.be.ok; expect(parser.opts.proxy).to.be.ok; @@ -435,6 +436,7 @@ describe('CLI argument parser', function () { { long: '--proxy' }, { long: '--proxy-bypass' }, { long: '--disable-page-reloads' }, + { long: '--dev' }, { long: '--ssl' }, { long: '--qr-code' }, { long: '--color' }, From 73ce9996a020eb391e791a9bffc1c3b43264032a Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Mon, 16 Jul 2018 16:58:54 +0300 Subject: [PATCH 018/184] [docs] screenshot path pattern (#2620) * [docs] screenshot path pattern * placeholders in uppercase * fix Mikhail's remarks * fix one more MIkhail's remark * fix broken links and default patterns --- .../test-api/actions/take-screenshot.md | 9 +---- .../using-testcafe/command-line-interface.md | 39 ++++++++++++++++++- .../programming-interface/runner.md | 7 ++-- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/docs/articles/documentation/test-api/actions/take-screenshot.md b/docs/articles/documentation/test-api/actions/take-screenshot.md index 4ce6007e..b947fe03 100644 --- a/docs/articles/documentation/test-api/actions/take-screenshot.md +++ b/docs/articles/documentation/test-api/actions/take-screenshot.md @@ -21,12 +21,7 @@ t.takeScreenshot( [path] ) Parameter | Type | Description ------------------- | ------ | ----------------------------------------------------------------------------------------------------- -`path` *(optional)* | String | The relative path and the name of the screenshot file to be created. Resolved from the *screenshot directory* specified by using the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. - -By default, the path to which screenshots are saved is specified as: - -* `{currentDate}\test-{testIndex}\{userAgent}\{screenshotIndex}.png` if the [quarantine mode](../../using-testcafe/command-line-interface.md#-q---quarantine-mode) is disabled; -* `{currentDate}\test-{testIndex}\run-{quarantineAttempt}\{userAgent}\{screenshotIndex}.png` if the [quarantine mode](../../using-testcafe/command-line-interface.md#-q---quarantine-mode) is enabled. +`path` *(optional)* | String | The screenshot file's relative path and name. The path is resolved relative to the root directory specified by the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. This path overrides the relative path specified by the default or custom [path patterns](../../using-testcafe/command-line-interface.md#path-patterns). The following example shows how to use the `t.takeScreenshot` action. @@ -55,7 +50,7 @@ Takes a screenshot of the specified page element. Parameter | Type | Description ------------------------ | ------ | ----------------------------------------------------------------------------------------------------- `selector` | Function | String | Selector | Snapshot | Promise | Identifies the webpage element whose screenshot will be taken. See [Selecting Target Elements](README.md#selecting-target-elements). -`path` *(optional)* | String | The relative path and the name of the screenshot file to be created. Resolved from the *screenshot directory* specified by using the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. +`path` *(optional)* | String | The screenshot file's relative path and name. The path is resolved relative to the root directory specified by using the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. This path overrides the relative path specified by the default or custom [path patterns](../../using-testcafe/command-line-interface.md#path-patterns). `options` *(optional)* | Object | Options that define how the screenshot will be taken. See details below. ```js diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index a6886d60..46fb892d 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -26,6 +26,7 @@ testcafe [options] * [-r \, --reporter \](#-r-namefile---reporter-namefile) * [-s \, --screenshots \](#-s-path---screenshots-path) * [-S, --screenshots-on-fails](#-s---screenshots-on-fails) + * [-p, --screenshot-path-pattern](#-p---screenshot-path-pattern) * [-q, --quarantine-mode](#-q---quarantine-mode) * [-e, --skip-js-errors](#-e---skip-js-errors) * [-c \, --concurrency \](#-c-n---concurrency-n) @@ -268,12 +269,23 @@ Note that only one reporter can write to `stdout`. All other reporters must outp ### -s \, --screenshots \ -Enables screenshot capturing and specifies the directory where screenshots are saved. +Enables screenshot capturing and specifies the root directory where screenshots are saved. ```sh testcafe all tests/sample-fixture.js -s screenshots ``` +#### Path Patterns + +The captured screenshots are organized into subdirectories within the root directory. The screenshots' relative path and name are defined using the default screenshot path patterns: + +* `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is disabled; +* `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is enabled. +* `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\errors\{$FILE_INDEX}.png` if the [--screenshots-on-fails](#-s---screenshots-on-fails) option is specified. +* `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\errors\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) and [--screenshots-on-fails](#-s---screenshots-on-fails) option are enabled. + +You can also specify a custom pattern using the [--screenshot-path-pattern](#-p---screenshot-path-pattern) option. + ### -S, --screenshots-on-fails Takes a screenshot whenever a test fails. Screenshots are saved to the directory specified in the **-screenshots \** option. @@ -286,6 +298,31 @@ For example, the following command runs tests from the testcafe all tests/sample-fixture.js -S -s screenshots ``` +### -p, --screenshot-path-pattern + +Specifies a custom pattern to compose screenshot files' relative path and name. This pattern overrides the default [path pattern](#path-patterns). + +You can use the following placeholders in the pattern: + +Placeholder | Description +----------- | ----------- +`${DATE}` | The test run's start date (YYYY-MM-DD). +`${TIME}` | The test run's start time (HH-mm-ss). +`${TEST_INDEX}` | The test's index. +`${FILE_INDEX}` | The screenshot file's index. +`${QUARANTINE_ATTEMPT}` | The [quarantine](programming-interface/runner.md#quarantine-mode) attempt's number. If the quarantine mode is disabled, the `${QUARANTINE_ATTEMPT}` placeholder's value is 1. +`${FIXTURE}` | The fixture's name. +`${TEST}` | The test's name. +`${USERAGENT}` | The combination of `${BROWSER}`, `${BROWSER_VERSION}`, `${OS}`, and `${OS_VERSION}`. +`${BROWSER}` | The browser's name. +`${BROWSER_VERSION}` | The browser's version. +`${OS}` | The operation system's name. +`${OS_VERSION}` | The operation system's version. + +```sh +testcafe all tests/sample-fixture.js -s screenshots -p "${DATE}_${TIME}/test-${TEST_INDEX}/${USERAGENT}/${FILE_INDEX}.png" +``` + ### -q, --quarantine-mode Enables the [quarantine mode](programming-interface/runner.md#quarantine-mode) for tests that fail. diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index 64f0f6be..e686add7 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -201,13 +201,14 @@ createTestCafe('localhost', 1337, 1338) Enables TestCafe to take screenshots of the tested webpages. ```text -screenshots(path [, takeOnFails]) → this +screenshots(path [, takeOnFails, pathPattern]) → this ``` Parameter | Type | Description | Default -------------------------- | ------- | ----------------------------------------------------------------------------- | ------- -`path` | String | The path to which the screenshots are saved. +`path` | String | The root path where the screenshots are saved. The relative path is specified by the default [path patterns](../command-line-interface.md#path-patterns) or by the method's `screenshotPathPattern` parameter. `takeOnFails` *(optional)* | Boolean | Specifies if screenshots should be taken automatically when a test fails. | `false` +`sceenshotPathPattern` *(optional)* | String | The pattern to compose screenshot files' relative path and name. See [--screenshot-path-pattern](../command-line-interface.md#-p---screenshot-path-pattern) for information about available placeholders. The `screenshots` function should be called to allow TestCafe to take screenshots when the [t.takeScreenshot](../../test-api/actions/take-screenshot.md) action is called from test code. @@ -219,7 +220,7 @@ Set the `takeOnFails` parameter to `true` to take a screenshot when a test fails **Example** ```js -runner.screenshots('reports/screenshots/', true); +runner.screenshots('reports/screenshots/', true, '${DATE}_${TIME}/test-${TEST_INDEX}/${USERAGENT}/${FILE_INDEX}.png'); ``` ### reporter From 3ac1c50601e62305e47aa4950a23e50ba3606ba2 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Tue, 17 Jul 2018 11:31:08 +0300 Subject: [PATCH 019/184] Correctors checked the option description (#2629) --- src/cli/argument-parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index 0d80e794..afcf451f 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -110,7 +110,7 @@ export default class CLIArgumentParser { .option('--ssl', 'specify SSL options to run TestCafe proxy server over the HTTPS protocol') .option('--proxy-bypass ', 'specify a comma-separated list of rules that define URLs accessed bypassing the proxy server') .option('--disable-page-reloads', 'disable page reloads between tests') - .option('--dev', 'enables the mechanisms for error logging and diagnosing') + .option('--dev', 'enables mechanisms to log and diagnose errors') .option('--qr-code', 'outputs QR-code that repeats URLs used to connect the remote browsers') // NOTE: these options will be handled by chalk internally From d392931aaaeff9af54efe7cedfe24183f1ccab64 Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Wed, 18 Jul 2018 10:51:21 +0300 Subject: [PATCH 020/184] [docs] Dirk corrections (#2634) --- .../reporter-plugin/reporter-methods.md | 6 +++--- .../using-testcafe/command-line-interface.md | 14 +++++++------- .../using-testcafe/programming-interface/runner.md | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/articles/documentation/extending-testcafe/reporter-plugin/reporter-methods.md b/docs/articles/documentation/extending-testcafe/reporter-plugin/reporter-methods.md index 0aadbc24..890b107c 100644 --- a/docs/articles/documentation/extending-testcafe/reporter-plugin/reporter-methods.md +++ b/docs/articles/documentation/extending-testcafe/reporter-plugin/reporter-methods.md @@ -128,7 +128,7 @@ Property | Type | Description `errs` | Array of Strings | An array of errors that occurred during the test run. `durationMs` | Number | The time spent on test execution (in milliseconds). `unstable` | Boolean | Specifies if the test is marked as unstable. -`screenshotPath` | String | The directory path where screenshots are saved to. +`screenshotPath` | String | The path where screenshots are saved. `screenshots` | Array of Objects | An array of [screenshot](#screenshots-object) objects. `quarantine` | Object | A [quarantine](#quarantine-object) object. `skipped` | Boolean | Specifies if the test was skipped. @@ -139,8 +139,8 @@ The `screenshot` object provides information about the screenshot captured durin Property | Type | Description ------------------- | ---------------- | -------------------------------------------------------- -`screenshotPath` | String | The directory path where the screenshot was saved to. -`thumbnailPath` | String | The directory path where the screenshot's thumbnail was saved to. +`screenshotPath` | String | The path where the screenshot was saved. +`thumbnailPath` | String | The path where the screenshot's thumbnail was saved. `userAgent` | String | The user agent string of the browser where the screenshot was captured. `quarantineAttempt` | Number | The [quarantine](../../using-testcafe/programming-interface/runner.md#quarantine-mode) attempt's number. `takenOnFail` | Boolean | Specifies if the screenshot was captured when the test failed. diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 46fb892d..ae1782e3 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -348,7 +348,7 @@ Specifies that tests should run concurrently. TestCafe opens `n` instances of the same browser and creates a pool of browser instances. Tests are run concurrently against this pool, that is, each test is run in the first free instance. -See [Concurrent Test Execution](common-concepts/concurrent-test-execution.md) to learn more about concurrent test execution. +See [Concurrent Test Execution](common-concepts/concurrent-test-execution.md) for more information about concurrent test execution. The following example shows how to run tests in three Chrome instances: @@ -425,7 +425,7 @@ You can also use the **Unlock page** switch in the footer to unlock the tested p Specifies whether to automatically enter the [debug mode](#-d---debug-mode) when a test fails. -If this option is enabled, TestCafe pauses the test at the moment it fails. This allows you to view the tested page and determine the cause of the fail. +If this option is enabled, TestCafe pauses the test when it fails. This allows you to view the tested page and determine the cause of the fail. When you are done, click the **Finish** button in the footer to end test execution. @@ -443,7 +443,7 @@ testcafe chrome my-tests --app "node server.js" --app-init-delay 4000 ### --selector-timeout \ -Specifies the time (in milliseconds) within which [selectors](../test-api/selecting-page-elements/selectors/README.md) attempts to obtain a node to be returned. See [Selector Timeout](../test-api/selecting-page-elements/selectors/using-selectors.md#selector-timeout). +Specifies the time (in milliseconds) within which [selectors](../test-api/selecting-page-elements/selectors/README.md) attempt to obtain a node to be returned. See [Selector Timeout](../test-api/selecting-page-elements/selectors/using-selectors.md#selector-timeout). **Default value**: `10000` @@ -453,7 +453,7 @@ testcafe ie my-tests --selector-timeout 500000 ### --assertion-timeout \ -Specifies the time (in milliseconds) within which TestCafe makes attempts to successfully execute an [assertion](../test-api/assertions/README.md) +Specifies the time (in milliseconds) TestCafe attempts to successfully execute an [assertion](../test-api/assertions/README.md) if a [selector property](../test-api/selecting-page-elements/selectors/using-selectors.md#define-assertion-actual-value) or a [client function](../test-api/obtaining-data-from-the-client/README.md) was passed as an actual value. See [Smart Assertion Query Mechanism](../test-api/assertions/README.md#smart-assertion-query-mechanism). @@ -504,7 +504,7 @@ Specifies the resources accessed bypassing the proxy server. When you access the Internet through a proxy server specified using the [--proxy](#--proxy-host) option, you may still need some local or external resources to be accessed directly. In this instance, provide their URLs to the `--proxy-bypass` option. -The `rules` parameter takes a comma-separated list (without spaces) of URLs that require direct access. You can replace parts of the URL with wildcards `*`. TestCafe will correspond these symbols to any number of characters in the URL. Wildcards at the beginning and end of the rules can be omitted (`*.mycompany.com` and `.mycompany.com` have the same effect). +The `rules` parameter takes a comma-separated list (without spaces) of URLs that require direct access. You can replace parts of the URL with the `*` wildcard that matches any number of characters. Wildcards at the beginning and end of the rules can be omitted (`*.mycompany.com` and `.mycompany.com` have the same effect). The following example uses the proxy server at `proxy.corp.mycompany.com` with the `localhost:8080` address accessed directly: @@ -563,8 +563,8 @@ testcafe remote my-tests --qr-code ### --color -Enables colors on the command line. +Enables colors in the command line. ### --no-color -Disables colors on the command line. +Disables colors in the command line. diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index e686add7..8e91b98f 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -300,7 +300,7 @@ concurrency(n) → this ``` TestCafe opens `n` instances of the same browser and creates a pool of browser instances. -Tests are run concurrently against this pool, that is, each test is run in the first free instance. +Tests are run concurrently against this pool, that is, each test is run in the first available instance. The `concurrency` function takes the following parameters: @@ -460,12 +460,12 @@ You can also cancel all pending tasks at once using the [runner.stop](#stop) fun #### Quarantine Mode -The quarantine mode is designed to isolate *non-deterministic* tests (that is, tests that sometimes pass and fail without a clear reason) +The quarantine mode is designed to isolate *non-deterministic* tests (that is, tests that sometimes pass and fail without any apparent reason) from the rest of the test base (*healthy* tests). In this mode, a failed test is executed several times. The test result depends on the outcome (passed or failed) that occurs most often. That is, if the test fails on most attempts, the result is failed. If the test result differs between test runs, the test is marked as unstable. -To learn more about non-deterministic tests, see Martin Fowler's [Eradicating Non-Determinism in Tests](http://martinfowler.com/articles/nonDeterminism.html) article. +See Martin Fowler's [Eradicating Non-Determinism in Tests](http://martinfowler.com/articles/nonDeterminism.html) article for more information about non-deterministic tests. ### stop From 94c4d6c6d8f8e24741b7140c85b8afbc7c3ecde6 Mon Sep 17 00:00:00 2001 From: Artem Lavrov Date: Wed, 18 Jul 2018 12:08:54 +0300 Subject: [PATCH 021/184] bump version (v0.20.5) (#2636) --- CHANGELOG.md | 20 +++++++++++++++++++- package.json | 4 ++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40181724..7849fe8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## v0.20.5 (2018-7-18) + +### Bug fixes + +* The `buttons` property was added to the `MouseEvent` instance ([#2056](https://github.com/DevExpress/testcafe/issues/2056)) +* Response headers were converted to lowercase ([#2534](https://github.com/DevExpress/testcafe/issues/2534)) +* Updated flow definitions ([#2053](https://github.com/DevExpress/testcafe/issues/2053)) +* An `AttributesWrapper` instance is now updated when the the element's property specifies the `disabled` attribute ([#2539](https://github.com/DevExpress/testcafe/issues/2539)) +* TestCafe no longer hangs when it redirects from a tested page to the 'about:error' page with a hash ([#2371](https://github.com/DevExpress/testcafe/issues/2371)) +* TestCafe now reports a warning for a mocked request if CORS validation failed ([#2482](https://github.com/DevExpress/testcafe/issues/2482)) +* Prevented situations when a request logger tries to stringify a body that is not logged ([#2555](https://github.com/DevExpress/testcafe/issues/2555)) +* The Selector API now reports `NaN` instead of `integer` when type validation fails ([#2470](https://github.com/DevExpress/testcafe/issues/2470)) +* Enabled `noImplicitAny` and disabled `skipLibCheck` in the TypeScript compiler ([#2497](https://github.com/DevExpress/testcafe/issues/2497)) +* Pages with `rel=prefetch` links no longer hang during test execution ([#2528](https://github.com/DevExpress/testcafe/issues/2528)) +* Fixed the `TypeError: this.res.setHeader is not a function` error in Firefox ([#2438](https://github.com/DevExpress/testcafe/issues/2438)) +* The `formtarget` attribute was overridden ([testcafe-hammerhead/#1513](https://github.com/DevExpress/testcafe-hammerhead/issues/1513)) +* `fetch.toString()` now equals `function fetch() { [native code] }` ([testcafe-hammerhead/#1662](https://github.com/DevExpress/testcafe-hammerhead/issues/1662)) + ## v0.20.4 (2018-6-25) ### Enhancements @@ -8,7 +26,7 @@ ### Bug fixes -* `fetch` requests are now correctly proxied in a specific case ([testcafe-hammerhead/#1613](https://github.com/DevExpress/testcafe-hammerhead/issues/1613)) +* `fetch` requests now correctly proxied in a specific case ([testcafe-hammerhead/#1613](https://github.com/DevExpress/testcafe-hammerhead/issues/1613)) * Resources responding with `304` HTTP status code and with the 'content-length: ' header are proxied correctly now ([testcafe-hammerhead/#1602](https://github.com/DevExpress/testcafe-hammerhead/issues/1602)) * The `transfer` argument of `window.postMessage` is passed correctly now ([testcafe-hammerhead/#1535](https://github.com/DevExpress/testcafe-hammerhead/issues/1535)) * Incorrect focus events order in IE has been fixed ([#2072](https://github.com/DevExpress/testcafe/issues/2072)) diff --git a/package.json b/package.json index 85513ecc..53549d8e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.20.5-alpha.1", + "version": "0.20.5", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" @@ -106,7 +106,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.4", - "testcafe-hammerhead": "14.2.1", + "testcafe-hammerhead": "14.2.2", "testcafe-legacy-api": "3.1.7", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", From 0f8498cb656086b66bda1d42f4da1e0b8cda077e Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 18 Jul 2018 12:11:48 +0300 Subject: [PATCH 022/184] Use the 'latest' tag --- .publishrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.publishrc b/.publishrc index 2414a453..dbc8b1c8 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "alpha", + "publishTag": " latest", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } From 92b3bed69fd473f3dcac2c0b3d7f30ed95dbc1f7 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 18 Jul 2018 12:33:07 +0300 Subject: [PATCH 023/184] Use the 'latest' tag --- .publishrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.publishrc b/.publishrc index dbc8b1c8..5727c783 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": " latest", + "publishTag": "latest", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } From 3d5fbb0f6105feaa481818b740628802153615ab Mon Sep 17 00:00:00 2001 From: Helen Dikareva Date: Fri, 20 Jul 2018 14:41:09 +0300 Subject: [PATCH 024/184] Dragging for links fixed (closes #2529) (#2593) --- src/client/automation/playback/drag/base.js | 19 ++--- src/client/automation/playback/move/index.js | 16 +++-- src/test-run/commands/options.js | 12 ++-- test/client/fixtures/automation/drag-test.js | 2 +- .../api/es-next/drag/pages/drag-and-drop.html | 6 +- .../fixtures/api/es-next/drag/test.js | 4 ++ .../testcafe-fixtures/drag-and-drop-test.js | 69 +++++++++++++++++++ test/server/test-run-command-options-test.js | 13 ++-- 8 files changed, 112 insertions(+), 29 deletions(-) diff --git a/src/client/automation/playback/drag/base.js b/src/client/automation/playback/drag/base.js index df6f28d5..b27d3176 100644 --- a/src/client/automation/playback/drag/base.js +++ b/src/client/automation/playback/drag/base.js @@ -29,7 +29,9 @@ export default class DragAutomationBase extends VisibleElementAutomation { this.offsetX = mouseOptions.offsetX; this.offsetY = mouseOptions.offsetY; - this.endPoint = null; + this.endPoint = null; + this.simulateDefaultBehavior = true; + this.downEvent = featureDetection.isTouchDevice ? 'touchstart' : 'mousedown'; this.upEvent = featureDetection.isTouchDevice ? 'touchend' : 'mouseup'; @@ -44,7 +46,7 @@ export default class DragAutomationBase extends VisibleElementAutomation { return cursor .leftButtonDown() .then(() => { - eventSimulator[this.downEvent](eventArgs.element, eventArgs.options); + this.simulateDefaultBehavior = eventSimulator[this.downEvent](eventArgs.element, eventArgs.options); return this._focus(eventArgs); }); @@ -70,12 +72,13 @@ export default class DragAutomationBase extends VisibleElementAutomation { this.endPoint = endPoint; var dragOptions = new MoveOptions({ - offsetX: offsets.offsetX, - offsetY: offsets.offsetY, - modifiers: this.modifiers, - speed: this.speed, - minMovingTime: MIN_MOVING_TIME, - holdLeftButton: true + offsetX: offsets.offsetX, + offsetY: offsets.offsetY, + modifiers: this.modifiers, + speed: this.speed, + minMovingTime: MIN_MOVING_TIME, + holdLeftButton: true, + skipDefaultDragBehavior: this.simulateDefaultBehavior === false }, false); var moveAutomation = new MoveAutomation(element, dragOptions); diff --git a/src/client/automation/playback/move/index.js b/src/client/automation/playback/move/index.js index 77ff80da..22f72820 100644 --- a/src/client/automation/playback/move/index.js +++ b/src/client/automation/playback/move/index.js @@ -88,9 +88,10 @@ export default class MoveAutomation { this.speed = moveOptions.speed; this.cursorSpeed = this.holdLeftButton ? this.automationSettings.draggingSpeed : this.automationSettings.cursorSpeed; - this.minMovingTime = moveOptions.minMovingTime || null; - this.modifiers = moveOptions.modifiers || {}; - this.skipScrolling = moveOptions.skipScrolling; + this.minMovingTime = moveOptions.minMovingTime || null; + this.modifiers = moveOptions.modifiers || {}; + this.skipScrolling = moveOptions.skipScrolling; + this.skipDefaultDragBehavior = moveOptions.skipDefaultDragBehavior; this.endPoint = null; @@ -263,8 +264,10 @@ export default class MoveAutomation { var isDocumentBody = this.element.tagName && domUtils.isBodyElement(this.element); return { - x: Math.floor(isDocumentBody ? clientPosition.x + this.offsetX : clientPosition.x + this.offsetX - scroll.left), - y: Math.floor(isDocumentBody ? clientPosition.y + this.offsetY : clientPosition.y + this.offsetY - scroll.top) + x: Math.floor(isDocumentBody ? clientPosition.x + this.offsetX : clientPosition.x + this.offsetX - + scroll.left), + y: Math.floor(isDocumentBody ? clientPosition.y + this.offsetY : clientPosition.y + this.offsetY - + scroll.top) }; } @@ -426,7 +429,8 @@ export default class MoveAutomation { var draggable = findDraggableElement(this.dragElement); - if (draggable && featureDetection.hasDataTransfer) { + // NOTE: we should skip simulating drag&drop's native behavior if the mousedown event was prevented (GH - 2529) + if (draggable && featureDetection.hasDataTransfer && !this.skipDefaultDragBehavior) { this.dragAndDropState.enabled = true; this.dragElement = draggable; this.dragAndDropState.element = this.dragElement; diff --git a/src/test-run/commands/options.js b/src/test-run/commands/options.js index cfbcc5d7..86d833ea 100644 --- a/src/test-run/commands/options.js +++ b/src/test-run/commands/options.js @@ -161,10 +161,11 @@ export class MoveOptions extends MouseOptions { constructor (obj, validate) { super(); - this.speed = null; - this.minMovingTime = null; - this.holdLeftButton = false; - this.skipScrolling = false; + this.speed = null; + this.minMovingTime = null; + this.holdLeftButton = false; + this.skipScrolling = false; + this.skipDefaultDragBehavior = false; this._assignFrom(obj, validate); } @@ -174,7 +175,8 @@ export class MoveOptions extends MouseOptions { { name: 'speed' }, { name: 'minMovingTime' }, { name: 'holdLeftButton' }, - { name: 'skipScrolling', type: booleanOption } + { name: 'skipScrolling', type: booleanOption }, + { name: 'skipDefaultDragBehavior', type: booleanOption } ]); } } diff --git a/test/client/fixtures/automation/drag-test.js b/test/client/fixtures/automation/drag-test.js index 5066a7c0..13e179bf 100644 --- a/test/client/fixtures/automation/drag-test.js +++ b/test/client/fixtures/automation/drag-test.js @@ -202,7 +202,7 @@ $(document).ready(function () { }); if (!featureDetection.isTouchDevice) { - asyncTest('GH372-"mousemove" event sent to wrong element during dragging', function () { + asyncTest('GH372 - The mousemove event is sent to a wrong element during dragging', function () { var $firstTarget = createTarget(10, 10); var $secondTarget = createTarget(110, 110); var elementCenter = getCenter($firstTarget[0]); diff --git a/test/functional/fixtures/api/es-next/drag/pages/drag-and-drop.html b/test/functional/fixtures/api/es-next/drag/pages/drag-and-drop.html index ef21189d..6766de61 100644 --- a/test/functional/fixtures/api/es-next/drag/pages/drag-and-drop.html +++ b/test/functional/fixtures/api/es-next/drag/pages/drag-and-drop.html @@ -127,9 +127,9 @@ waitForNextEvent(0); - document.addEventListener('click', function () { - throw new Error('The "click" is raised but should not be'); - }); + document.onclick = function () { + throw new Error('Click is raised but should not'); + }; diff --git a/test/functional/fixtures/api/es-next/drag/test.js b/test/functional/fixtures/api/es-next/drag/test.js index 96ff76f0..3fd932e6 100644 --- a/test/functional/fixtures/api/es-next/drag/test.js +++ b/test/functional/fixtures/api/es-next/drag/test.js @@ -139,5 +139,9 @@ describe('[API] Drag actions', function () { it('Should reproduce native browser behavior', function () { return runTests('./testcafe-fixtures/drag-and-drop-test.js', 'drag link and image', { only: ['chrome'] }); }); + + it('Should not raise the drag and drop events if the mousedown event was prevented', function () { + return runTests('./testcafe-fixtures/drag-and-drop-test.js', 'Default drag events should not be simulated if the mousedown event was prevented', { skip: ['iphone', 'ipad', 'android'] }); + }); }); }); diff --git a/test/functional/fixtures/api/es-next/drag/testcafe-fixtures/drag-and-drop-test.js b/test/functional/fixtures/api/es-next/drag/testcafe-fixtures/drag-and-drop-test.js index 04a93546..95f3cb9e 100644 --- a/test/functional/fixtures/api/es-next/drag/testcafe-fixtures/drag-and-drop-test.js +++ b/test/functional/fixtures/api/es-next/drag/testcafe-fixtures/drag-and-drop-test.js @@ -79,3 +79,72 @@ test.page `http://localhost:3000/fixtures/api/es-next/drag/pages/invalid-drag-an .expect(draggable.parent(0).id).eql('from') .expect(ClientFunction(() => window.dradendRaised)()).eql(true); }); + +test('Default drag events should not be simulated if the mousedown event was prevented', async t => { + const link = Selector('#link'); + const target = Selector('#to-display-values'); + + const setEventHandlers = ClientFunction(shouldPreventMousedown => { + function handler (e) { + window[e.type + 'Raised'] = true; + + if (shouldPreventMousedown && e.type === 'mousedown') + e.preventDefault(); + } + + document.ondragstart = handler; + document.ondragend = handler; + + document.onmousedown = handler; + document.onmouseup = handler; + + // NOTE: we should reset the onclick handler because of GH-2640 + document.onclick = () => { + }; + }); + + const getEventsResult = ClientFunction(() => { + return { + dragstart: window.dragstartRaised, + dragend: window.dragendRaised, + + mousedown: window.mousedownRaised, + mouseup: window.mouseupRaised + }; + }); + + const clearEventsResult = ClientFunction(() => { + window.dragstartRaised = false; + window.dragendRaised = false; + + window.mousedownRaised = false; + window.mouseupRaised = false; + }); + + + await clearEventsResult(); + await setEventHandlers(); + + await t + .dragToElement(link, target) + .expect(getEventsResult()).eql({ + dragstart: true, + dragend: true, + + mousedown: true, + mouseup: false + }); + + await clearEventsResult(); + await setEventHandlers(true); + + await t + .dragToElement(link, target) + .expect(getEventsResult()).eql({ + dragstart: false, + dragend: false, + + mousedown: true, + mouseup: true + }); +}); diff --git a/test/server/test-run-command-options-test.js b/test/server/test-run-command-options-test.js index 1e62e232..ddb0bd95 100644 --- a/test/server/test-run-command-options-test.js +++ b/test/server/test-run-command-options-test.js @@ -126,12 +126,13 @@ describe('Test run command options', function () { }, false); expect(JSON.parse(JSON.stringify(options))).eql({ - offsetX: null, - offsetY: 15, - speed: 20, - minMovingTime: null, - holdLeftButton: true, - skipScrolling: false, + offsetX: null, + offsetY: 15, + speed: 20, + minMovingTime: null, + holdLeftButton: true, + skipDefaultDragBehavior: false, + skipScrolling: false, modifiers: { ctrl: true, From bfc89a6fb4364f45d3feb179e8389d6e004d3524 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 20 Jul 2018 16:39:58 +0300 Subject: [PATCH 025/184] [docs] Describe establishing HTTPS connection to TestCafe (#2633) * Describe establishing HTTPS connection to TestCafe * Add an article before 'TestCafe server' * Address Margarita's remarks * Address Miher's and Andrew's remarks --- .../using-testcafe/command-line-interface.md | 18 + .../using-testcafe/common-concepts/README.md | 1 + ...nnect-to-the-testcafe-server-over-https.md | 60 +++ .../programming-interface/createtestcafe.md | 36 +- .../images/proxy-connection-protocols.svg | 413 ++++++++++++++++++ docs/nav/nav-menu.yml | 2 + 6 files changed, 529 insertions(+), 1 deletion(-) create mode 100644 docs/articles/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.md create mode 100644 docs/articles/images/proxy-connection-protocols.svg diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index ae1782e3..2a50c2ef 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -45,6 +45,7 @@ testcafe [options] * [--proxy-bypass \](#--proxy-bypass-rules) * [--ports \](#--ports-port1port2) * [--hostname \](#--hostname-name) + * [--ssl \](#--ssl-options) * [--speed \](#--speed-factor) * [--qr-code](#--qr-code) * [--color](#--color) @@ -536,6 +537,23 @@ Specifies your computer's hostname. It is used when running tests in [remote bro If the hostname is not specified, TestCafe uses the operating system hostname or network IP address of the current machine. +### --ssl \ + +Provides options that allow you to establish HTTPS connection between the client browser and the TestCafe server. + +The `options` parameter contains options required to initialize +[a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). +The most commonly used SSL options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in Node.js documentation. +Options are specified in a semicolon-separated string. + +```sh +testcafe --ssl pfx=path/to/file.pfx;rejectUnauthorized=true;... +``` + +Provide the `--ssl` flag if the tested webpage uses browser features that require +secure origin ([Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API), [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API), [ApplePaySession](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession), [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto), etc). +See [Connect to the TestCafe Server over HTTPS](common-concepts/connect-to-the-testcafe-server-over-https.md) for more information. + ### --speed \ Specifies the test execution speed. diff --git a/docs/articles/documentation/using-testcafe/common-concepts/README.md b/docs/articles/documentation/using-testcafe/common-concepts/README.md index a5245524..1b5dffaa 100644 --- a/docs/articles/documentation/using-testcafe/common-concepts/README.md +++ b/docs/articles/documentation/using-testcafe/common-concepts/README.md @@ -8,3 +8,4 @@ permalink: /documentation/using-testcafe/common-concepts/ * [Browsers](browsers/README.md) * [Concurrent Test Execution](concurrent-test-execution.md) * [Reporters](reporters.md) +* [Connect to the TestCafe Server over HTTPS](connect-to-the-testcafe-server-over-https.md) diff --git a/docs/articles/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.md b/docs/articles/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.md new file mode 100644 index 00000000..1b809947 --- /dev/null +++ b/docs/articles/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.md @@ -0,0 +1,60 @@ +--- +layout: docs +title: Connect to the TestCafe Server over HTTPS +permalink: /documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.html +--- +# Connect to TestCafe Server over HTTPS + +TestCafe is a proxy-based testing tool. Browser requests are sent via the TestCafe proxy server to the tested website. All requests between the browser and the TestCafe server are sent over the HTTP protocol. + +![Connection Protocols](../../../images/proxy-connection-protocols.svg) + +Some browser features (like +[Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API), +[Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API), +[ApplePaySession](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession), or +[SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto)) +require secure origin. This means that the website should be served over the HTTPS protocol. If you run tests against pages with this kind of browser API in a regular way, these tests fail with JavaScript errors. + +TestCafe can serve the proxied tested page over the HTTPS protocol. When this option is enabled, the client browser connects to the TestCafe proxy server over HTTPS. This allows you to test webpages that use browser features that require secure origin. + +Use the [--ssl](../command-line-interface.md#--ssl-options) flag when you run tests from the command line to enable HTTPS. Specify options required to initialize +[a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener) after this flag in a semicolon-separated string. The most commonly used SSL options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in Node.js documentation. + +The example below uses the PFX encoded private key and certificate chain to create an HTTPS server. + +```sh +testcafe --ssl pfx=path/to/file.pfx;rejectUnauthorized=true;... +``` + +When you use the programming interface, pass HTTPS server options to the [createTestCafe](../programming-interface/createtestcafe.md) method. + +The following example uses the [openssl-self-signed-certificate](https://www.npmjs.com/package/openssl-self-signed-certificate) module to generate a self-signed certificate for development use. + +```js +'use strict'; + +const createTestCafe = require('testcafe'); +const selfSignedSertificate = require('openssl-self-signed-certificate'); +let runner = null; + +const sslOptions = { + key: selfSignedSertificate.key, + cert: selfSignedSertificate.cert +}; + +createTestCafe('localhost', 1337, 1338, sslOptions) + .then(testcafe => { + runner = testcafe.createRunner(); + }) + .then(() => { + return runner + .src('test.js') + + // Browsers restrict self-signed certificate usage unless you + // explicitly set a flag specific to each browser. + // For Chrome, this is '--allow-insecure-localhost'. + .browsers('chrome --allow-insecure-localhost') + .run(); + }); +``` \ No newline at end of file diff --git a/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md b/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md index cb3c84e8..c8bdaacf 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md @@ -9,25 +9,59 @@ checked: true Creates a [TestCafe](testcafe.md) server instance. ```text -async createTestCafe([hostname], [port1], [port2]) → Promise +async createTestCafe([hostname], [port1], [port2], [sslOptions]) → Promise ``` Parameter | Type | Description | Default ----------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- `hostname` *(optional)* | String | The hostname or IP you will use to address the TestCafe server. Must resolve to the current machine. To test on external devices, use the hostname that is visible in the network shared with these devices. | Hostname of the OS. If the hostname does not resolve to the current machine - its network IP address. `port1`, `port2` *(optional)* | Number | Ports that will be used to serve tested webpages. | Free ports selected automatically. +`sslOptions` *(optional)* | Object | Options that allow you to establish HTTPS connection between the TestCafe server and the client browser. This object should contain options required to initialize [a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). The most commonly used SSL options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in Node.js documentation. See [Connect to the TestCafe Server over HTTPS](../common-concepts/connect-to-the-testcafe-server-over-https.md) for more information. **Example** +Create a `TestCafe` instance with the `createTestCafe` function. + ```js const createTestCafe = require('testcafe'); createTestCafe('localhost', 1337, 1338) .then(testcafe => { + runner = testcafe.createRunner(); /* ... */ }); ``` +Establish HTTPS connection with the TestCafe server. The [openssl-self-signed-certificate](https://www.npmjs.com/package/openssl-self-signed-certificate) module is used to generate a self-signed certificate for development use. + +```js +'use strict'; + +const createTestCafe = require('testcafe'); +const selfSignedSertificate = require('openssl-self-signed-certificate'); +let runner = null; + +const sslOptions = { + key: selfSignedSertificate.key, + cert: selfSignedSertificate.cert +}; + +createTestCafe('localhost', 1337, 1338, sslOptions) + .then(testcafe => { + runner = testcafe.createRunner(); + }) + .then(() => { + return runner + .src('test.js') + + // Browsers restrict self-signed certificate usage unless you + // explicitly set a flag specific to each browser. + // For Chrome, this is '--allow-insecure-localhost'. + .browsers('chrome --allow-insecure-localhost') + .run(); + }); +``` + ## See Also * [TestCafe Class](testcafe.md) \ No newline at end of file diff --git a/docs/articles/images/proxy-connection-protocols.svg b/docs/articles/images/proxy-connection-protocols.svg new file mode 100644 index 00000000..04bdb1d4 --- /dev/null +++ b/docs/articles/images/proxy-connection-protocols.svg @@ -0,0 +1,413 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Browser + + TestCafe Server + + HTTP + + Tested Website + + + HTTPS + HTTP + + diff --git a/docs/nav/nav-menu.yml b/docs/nav/nav-menu.yml index 59bf7312..522c1e5b 100644 --- a/docs/nav/nav-menu.yml +++ b/docs/nav/nav-menu.yml @@ -38,6 +38,8 @@ url: /documentation/using-testcafe/common-concepts/concurrent-test-execution.md - name: Reporters url: /documentation/using-testcafe/common-concepts/reporters.md + - name: Connect to the TestCafe Server over HTTPS + url: /documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.md - name: TEST API url: /documentation/test-api/README.md content: From 7edc60e7024f01f8198443f93f6fc99eb5d089c1 Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Mon, 23 Jul 2018 15:32:46 +0300 Subject: [PATCH 026/184] [docs] corrections - screenshotpathpattern (#2645) * [docs] corrections - screenshotpathpattern * minor changes * more dirk's corrections * replace root with base, rewrite paragraph about path parameter * corrections from Anna Zelenova --- .../test-api/actions/take-screenshot.md | 26 +++++++------------ .../using-testcafe/command-line-interface.md | 8 +++--- .../programming-interface/runner.md | 6 ++--- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/docs/articles/documentation/test-api/actions/take-screenshot.md b/docs/articles/documentation/test-api/actions/take-screenshot.md index b947fe03..de3c1268 100644 --- a/docs/articles/documentation/test-api/actions/take-screenshot.md +++ b/docs/articles/documentation/test-api/actions/take-screenshot.md @@ -6,12 +6,11 @@ checked: true --- # Take Screenshot -This topic describes how you can take screenshots of the tested page. +This topic describes how to take screenshots of the tested page. -**Note**: these actions require a [ICCCM/EWMH-compliant window manager](https://en.wikipedia.org/wiki/Comparison_of_X_window_managers) on Linux. +**Note**: these actions require an [ICCCM/EWMH-compliant window manager](https://en.wikipedia.org/wiki/Comparison_of_X_window_managers) on Linux. -> Important! If the screenshot directory is not specified with the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option, -> the screenshot actions are ignored. +> Important! Screenshot actions are ignored if the screenshot directory is not specified with the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. ## Take a Screenshot of the Entire Page @@ -21,9 +20,9 @@ t.takeScreenshot( [path] ) Parameter | Type | Description ------------------- | ------ | ----------------------------------------------------------------------------------------------------- -`path` *(optional)* | String | The screenshot file's relative path and name. The path is resolved relative to the root directory specified by the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. This path overrides the relative path specified by the default or custom [path patterns](../../using-testcafe/command-line-interface.md#path-patterns). +`path` *(optional)* | String | The screenshot file's relative path and name. The path is relative to the base directory specified by the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. This path overrides the relative path the default or custom [path patterns](../../using-testcafe/command-line-interface.md#path-patterns) specify. -The following example shows how to use the `t.takeScreenshot` action. +The following example shows how to use the `t.takeScreenshot` action: ```js import { Selector } from 'testcafe'; @@ -49,9 +48,9 @@ Takes a screenshot of the specified page element. Parameter | Type | Description ------------------------ | ------ | ----------------------------------------------------------------------------------------------------- -`selector` | Function | String | Selector | Snapshot | Promise | Identifies the webpage element whose screenshot will be taken. See [Selecting Target Elements](README.md#selecting-target-elements). -`path` *(optional)* | String | The screenshot file's relative path and name. The path is resolved relative to the root directory specified by using the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. This path overrides the relative path specified by the default or custom [path patterns](../../using-testcafe/command-line-interface.md#path-patterns). -`options` *(optional)* | Object | Options that define how the screenshot will be taken. See details below. +`selector` | Function | String | Selector | Snapshot | Promise | Identifies the webpage element whose screenshot should be taken. See [Selecting Target Elements](README.md#selecting-target-elements). +`path` *(optional)* | String | The screenshot file's relative path and name. The path is relative to the root directory specified by using the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. This path overrides the relative path the default or custom [path patterns](../../using-testcafe/command-line-interface.md#path-patterns) specify. +`options` *(optional)* | Object | Options that define how the screenshot is taken. See details below. ```js import { Selector } from 'testcafe'; @@ -67,16 +66,11 @@ test('Take a screenshot of a fieldset', async t => { }); ``` -By default, the path to which screenshots are saved is specified as: - -* `{currentDate}\test-{testIndex}\{userAgent}\{screenshotIndex}.png` if the [quarantine mode](../../using-testcafe/command-line-interface.md#-q---quarantine-mode) is disabled; -* `{currentDate}\test-{testIndex}\run-{quarantineAttempt}\{userAgent}\{screenshotIndex}.png` if the [quarantine mode](../../using-testcafe/command-line-interface.md#-q---quarantine-mode) is enabled. - -The `options` object contains the following properties. +The `options` object contains the following properties: Property | Type | Description | Default --------------- | ---- | ------------- | ---------- -`scrollTargetX`, `scrollTargetY` | Number | If the target element is too big to fit into the browser window, the page will be scrolled to put this point to the center of the viewport. The coordinates of this point are calculated relative to the target element. If the numbers are positive, the point is positioned relative to the top-left corner of the element. If the numbers are negative, the point is positioned relative to the bottom-right corner. If the target element fits into the browser window, these properties have no effect. | The center of the element. If the `crop` rectangle is specified, its center. If the `crop` rectangle is larger than the viewport, the center of the viewport. +`scrollTargetX`, `scrollTargetY` | Number | If the target element is too big to fit into the browser window, the page is scrolled to put this point to the center of the viewport. The coordinates of this point are calculated relative to the target element. If the numbers are positive, the point is positioned relative to the top-left corner of the element. If the numbers are negative, the point is positioned relative to the bottom-right corner. If the target element fits into the browser window, these properties have no effect. | The center of the element. If the `crop` rectangle is specified, its center. If the `crop` rectangle is larger than the viewport, the center of the viewport. `includeMargins` | Boolean | Specifies whether to include target element's margins in the screenshot. When it is enabled, the `scrollTargetX`, `scrollTargetY` and `crop` rectangle coordinates are calculated from the corners where top and left (or bottom and right) margins intersect. | `false` `includeBorders` | Boolean | Specifies whether to include target element's borders in the screenshot. When it is enabled, the `scrollTargetX`, `scrollTargetY` and `crop` rectangle coordinates are calculated from the corners where top and left (or bottom and right) internal edges of the element intersect. | `true` `includePaddings` | Boolean | Specifies whether to include target element's paddings in the screenshot. When it is enabled, the `scrollTargetX`, `scrollTargetY` and `crop` rectangle coordinates are calculated from the corners where top and left (or bottom and right) edges of the element's content area intersect. | `true` diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 2a50c2ef..3c117a3d 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -270,7 +270,7 @@ Note that only one reporter can write to `stdout`. All other reporters must outp ### -s \, --screenshots \ -Enables screenshot capturing and specifies the root directory where screenshots are saved. +Enables screenshots and specifies the base directory where they are saved. ```sh testcafe all tests/sample-fixture.js -s screenshots @@ -278,14 +278,14 @@ testcafe all tests/sample-fixture.js -s screenshots #### Path Patterns -The captured screenshots are organized into subdirectories within the root directory. The screenshots' relative path and name are defined using the default screenshot path patterns: +The captured screenshots are organized into subdirectories within the base directory. The following path patterns are used to define screenshots' relative path and name: * `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is disabled; * `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is enabled. * `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\errors\{$FILE_INDEX}.png` if the [--screenshots-on-fails](#-s---screenshots-on-fails) option is specified. * `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\errors\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) and [--screenshots-on-fails](#-s---screenshots-on-fails) option are enabled. -You can also specify a custom pattern using the [--screenshot-path-pattern](#-p---screenshot-path-pattern) option. +You can also use the [--screenshot-path-pattern](#-p---screenshot-path-pattern) option to specify a custom pattern. ### -S, --screenshots-on-fails @@ -306,7 +306,7 @@ Specifies a custom pattern to compose screenshot files' relative path and name. You can use the following placeholders in the pattern: Placeholder | Description ------------ | ----------- +----------- | ------------ `${DATE}` | The test run's start date (YYYY-MM-DD). `${TIME}` | The test run's start time (HH-mm-ss). `${TEST_INDEX}` | The test's index. diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index 8e91b98f..291dfd78 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -206,9 +206,9 @@ screenshots(path [, takeOnFails, pathPattern]) → this Parameter | Type | Description | Default -------------------------- | ------- | ----------------------------------------------------------------------------- | ------- -`path` | String | The root path where the screenshots are saved. The relative path is specified by the default [path patterns](../command-line-interface.md#path-patterns) or by the method's `screenshotPathPattern` parameter. +`path` | String | The base path where the screenshots are saved. Note that to construct a complete path to these screenshots, TestCafe uses default [path patterns](../command-line-interface.md#path-patterns). You can override these patterns using the method's `screenshotPathPattern` parameter. `takeOnFails` *(optional)* | Boolean | Specifies if screenshots should be taken automatically when a test fails. | `false` -`sceenshotPathPattern` *(optional)* | String | The pattern to compose screenshot files' relative path and name. See [--screenshot-path-pattern](../command-line-interface.md#-p---screenshot-path-pattern) for information about available placeholders. +`sceenshotPathPattern` *(optional)* | String | The pattern to compose screenshot files' relative path and name. See [--screenshot-path-pattern](../command-line-interface.md#-p---screenshot-path-pattern) for information about the available placeholders. The `screenshots` function should be called to allow TestCafe to take screenshots when the [t.takeScreenshot](../../test-api/actions/take-screenshot.md) action is called from test code. @@ -403,7 +403,7 @@ async run(options) → Promise You can pass the following options to the `runner.run` function. Parameter | Type | Description | Default ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- +----------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- `skipJsErrors` | Boolean | Defines whether to continue running a test after a JavaScript error occurs on a page (`true`), or consider such a test failed (`false`). | `false` `quarantineMode` | Boolean | Defines whether to enable the [quarantine mode](#quarantine-mode). | `false` `selectorTimeout` | Number | Specifies the time (in milliseconds) within which [selectors](../../test-api/selecting-page-elements/selectors/README.md) make attempts to obtain a node to be returned. See [Selector Timeout](../../test-api/selecting-page-elements/selectors/using-selectors.md#selector-timeout). | `10000` From 03fa1d00ab99806438902cc52dece27750d26c07 Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Mon, 23 Jul 2018 16:38:45 +0300 Subject: [PATCH 027/184] [docs] describes -dev option (#2637) --- .../using-testcafe/command-line-interface.md | 9 +++++++++ .../programming-interface/createtestcafe.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 3c117a3d..279e6081 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -47,6 +47,7 @@ testcafe [options] * [--hostname \](#--hostname-name) * [--ssl \](#--ssl-options) * [--speed \](#--speed-factor) + * [--dev](#--dev) * [--qr-code](#--qr-code) * [--color](#--color) * [--no-color](#--no-color) @@ -571,6 +572,14 @@ If the speed is also specified for an [individual action](../test-api/actions/ac **Default value**: `1` +### --dev + +Enables mechanisms to log and diagnose errors. You should enable this option if you are going to contact TestCafe Support to report an issue. + +```sh +testcafe chrome my-tests --dev +``` + ### --qr-code Outputs a QR-code that represents URLs used to connect the [remote browsers](#remote-browsers). diff --git a/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md b/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md index c8bdaacf..43d88f5f 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md @@ -9,7 +9,7 @@ checked: true Creates a [TestCafe](testcafe.md) server instance. ```text -async createTestCafe([hostname], [port1], [port2], [sslOptions]) → Promise +async createTestCafe([hostname], [port1], [port2], [sslOptions], developmentMode) → Promise ``` Parameter | Type | Description | Default @@ -17,6 +17,7 @@ Parameter | Type | Description `hostname` *(optional)* | String | The hostname or IP you will use to address the TestCafe server. Must resolve to the current machine. To test on external devices, use the hostname that is visible in the network shared with these devices. | Hostname of the OS. If the hostname does not resolve to the current machine - its network IP address. `port1`, `port2` *(optional)* | Number | Ports that will be used to serve tested webpages. | Free ports selected automatically. `sslOptions` *(optional)* | Object | Options that allow you to establish HTTPS connection between the TestCafe server and the client browser. This object should contain options required to initialize [a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). The most commonly used SSL options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in Node.js documentation. See [Connect to the TestCafe Server over HTTPS](../common-concepts/connect-to-the-testcafe-server-over-https.md) for more information. +`developmentMode` *(optional)* | Boolean | Enables/disables mechanisms to log and diagnose errors. You should enable this option if you are going to contact TestCafe Support to report an issue. | `false` **Example** From 00f1d5cb7fe925a44b931f5f7d45eeb08a990575 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Tue, 24 Jul 2018 11:23:26 +0300 Subject: [PATCH 028/184] Fix client tests in Safari (#2652) * Fix client tests in Safari * Update Gulpfile.js * Fix client tests in Safari --- Gulpfile.js | 4 ++-- appveyor.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gulpfile.js b/Gulpfile.js index 6447d580..32d144f5 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -97,9 +97,9 @@ var CLIENT_TESTS_DESKTOP_BROWSERS = [ version: '11.0' }, { - platform: 'OS X 10.12', + platform: 'macOS 10.13', browserName: 'safari', - version: '11.0' + version: '11.1' }, { platform: 'OS X 10.11', diff --git a/appveyor.yml b/appveyor.yml index 4d3f88d9..dcd22768 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -46,8 +46,8 @@ for: test_script: - cmd: >- node node_modules/gulp/bin/gulp test-functional-local-ie - + node node_modules/gulp/bin/gulp test-functional-local-chrome-firefox - + node node_modules/gulp/bin/gulp test-functional-local-legacy From d20708c41ec7f569a73191849762fce4ade32c7b Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Tue, 24 Jul 2018 15:18:18 +0300 Subject: [PATCH 029/184] Update createtestcafe.md --- .../using-testcafe/programming-interface/createtestcafe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md b/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md index 43d88f5f..6e5d0c56 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md @@ -9,7 +9,7 @@ checked: true Creates a [TestCafe](testcafe.md) server instance. ```text -async createTestCafe([hostname], [port1], [port2], [sslOptions], developmentMode) → Promise +async createTestCafe([hostname], [port1], [port2], [sslOptions], [developmentMode]) → Promise ``` Parameter | Type | Description | Default @@ -65,4 +65,4 @@ createTestCafe('localhost', 1337, 1338, sslOptions) ## See Also -* [TestCafe Class](testcafe.md) \ No newline at end of file +* [TestCafe Class](testcafe.md) From 2475642d1433c731f1954410ab2ea20eb1deaab5 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Wed, 25 Jul 2018 17:39:11 +0300 Subject: [PATCH 030/184] [docs] Apply Dirk's corrections to the HTTPS topic (#2661) * Apply Dirk's corrections * Address Miher's remarks --- .../using-testcafe/command-line-interface.md | 4 ++-- .../connect-to-the-testcafe-server-over-https.md | 10 +++++----- .../programming-interface/createtestcafe.md | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 279e6081..c27767b3 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -536,11 +536,11 @@ TestCafe automatically selects ports if ports are not specified. Specifies your computer's hostname. It is used when running tests in [remote browsers](#remote-browsers). -If the hostname is not specified, TestCafe uses the operating system hostname or network IP address of the current machine. +If the hostname is not specified, TestCafe uses the operating system's hostname or the current machine's network IP address. ### --ssl \ -Provides options that allow you to establish HTTPS connection between the client browser and the TestCafe server. +Provides options that allow you to establish an HTTPS connection between the client browser and the TestCafe server. The `options` parameter contains options required to initialize [a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). diff --git a/docs/articles/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.md b/docs/articles/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.md index 1b809947..35c85fa0 100644 --- a/docs/articles/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.md +++ b/docs/articles/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.md @@ -14,11 +14,11 @@ Some browser features (like [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API), [ApplePaySession](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession), or [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto)) -require secure origin. This means that the website should be served over the HTTPS protocol. If you run tests against pages with this kind of browser API in a regular way, these tests fail with JavaScript errors. +require a secure origin. This means that the website should use the HTTPS protocol. If TestCafe proxies such websites through HTTP, tests fail because of JavaScript errors. -TestCafe can serve the proxied tested page over the HTTPS protocol. When this option is enabled, the client browser connects to the TestCafe proxy server over HTTPS. This allows you to test webpages that use browser features that require secure origin. +TestCafe can serve the proxied tested page over the HTTPS protocol. When this option is enabled, the client browser uses HTTPS to connect to the TestCafe proxy server. This allows you to test web pages with browser features that require a secure origin. -Use the [--ssl](../command-line-interface.md#--ssl-options) flag when you run tests from the command line to enable HTTPS. Specify options required to initialize +To enable HTTPS, use the [--ssl](../command-line-interface.md#--ssl-options) flag when you run tests from the command line. Specify options required to initialize [a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener) after this flag in a semicolon-separated string. The most commonly used SSL options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in Node.js documentation. The example below uses the PFX encoded private key and certificate chain to create an HTTPS server. @@ -27,9 +27,9 @@ The example below uses the PFX encoded private key and certificate chain to crea testcafe --ssl pfx=path/to/file.pfx;rejectUnauthorized=true;... ``` -When you use the programming interface, pass HTTPS server options to the [createTestCafe](../programming-interface/createtestcafe.md) method. +When you use the programming interface, pass the HTTPS server options to the [createTestCafe](../programming-interface/createtestcafe.md) method. -The following example uses the [openssl-self-signed-certificate](https://www.npmjs.com/package/openssl-self-signed-certificate) module to generate a self-signed certificate for development use. +The following example uses the [openssl-self-signed-certificate](https://www.npmjs.com/package/openssl-self-signed-certificate) module to generate a self-signed certificate: ```js 'use strict'; diff --git a/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md b/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md index 6e5d0c56..5bfff45e 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/createtestcafe.md @@ -14,9 +14,9 @@ async createTestCafe([hostname], [port1], [port2], [sslOptions], [developmentMod Parameter | Type | Description | Default ----------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- -`hostname` *(optional)* | String | The hostname or IP you will use to address the TestCafe server. Must resolve to the current machine. To test on external devices, use the hostname that is visible in the network shared with these devices. | Hostname of the OS. If the hostname does not resolve to the current machine - its network IP address. +`hostname` *(optional)* | String | The hostname or IP on which the TestCafe server is running. Must resolve to the current machine. To test on external devices, use the hostname that is visible in the network shared with these devices. | Hostname of the OS. If the hostname does not resolve to the current machine - its network IP address. `port1`, `port2` *(optional)* | Number | Ports that will be used to serve tested webpages. | Free ports selected automatically. -`sslOptions` *(optional)* | Object | Options that allow you to establish HTTPS connection between the TestCafe server and the client browser. This object should contain options required to initialize [a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). The most commonly used SSL options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in Node.js documentation. See [Connect to the TestCafe Server over HTTPS](../common-concepts/connect-to-the-testcafe-server-over-https.md) for more information. +`sslOptions` *(optional)* | Object | Options that allow you to establish an HTTPS connection between the TestCafe server and the client browser. This object should contain options required to initialize [a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). The most commonly used SSL options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in Node.js documentation. See [Connect to the TestCafe Server over HTTPS](../common-concepts/connect-to-the-testcafe-server-over-https.md) for more information. `developmentMode` *(optional)* | Boolean | Enables/disables mechanisms to log and diagnose errors. You should enable this option if you are going to contact TestCafe Support to report an issue. | `false` **Example** @@ -33,7 +33,7 @@ createTestCafe('localhost', 1337, 1338) }); ``` -Establish HTTPS connection with the TestCafe server. The [openssl-self-signed-certificate](https://www.npmjs.com/package/openssl-self-signed-certificate) module is used to generate a self-signed certificate for development use. +Establish an HTTPS connection with the TestCafe server. The [openssl-self-signed-certificate](https://www.npmjs.com/package/openssl-self-signed-certificate) module is used to generate a self-signed certificate for development use. ```js 'use strict'; From 66a112724e7a88f3273ac73bedc13bc9dd76b649 Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Thu, 26 Jul 2018 11:37:31 +0300 Subject: [PATCH 031/184] [docs] address Lena's remark about screenshot path patterns (#2662) --- .../using-testcafe/command-line-interface.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index c27767b3..c7ef963f 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -279,12 +279,15 @@ testcafe all tests/sample-fixture.js -s screenshots #### Path Patterns -The captured screenshots are organized into subdirectories within the base directory. The following path patterns are used to define screenshots' relative path and name: +The captured screenshots are organized into subdirectories within the base directory. The following path patterns are used to define a relative path and name for screenshots the [Take Screenshot](../test-api/actions/take-screenshot.md) actions take: * `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is disabled; * `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is enabled. -* `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\errors\{$FILE_INDEX}.png` if the [--screenshots-on-fails](#-s---screenshots-on-fails) option is specified. -* `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\errors\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) and [--screenshots-on-fails](#-s---screenshots-on-fails) option are enabled. + +If TestCafe takes screenshots when a test fails (see [--screenshots-on-fails](#-s---screenshots-on-fails) option), the following path patterns are used: + +* `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\errors\{$FILE_INDEX}.png`; +* `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\errors\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is enabled. You can also use the [--screenshot-path-pattern](#-p---screenshot-path-pattern) option to specify a custom pattern. @@ -315,7 +318,7 @@ Placeholder | Description `${QUARANTINE_ATTEMPT}` | The [quarantine](programming-interface/runner.md#quarantine-mode) attempt's number. If the quarantine mode is disabled, the `${QUARANTINE_ATTEMPT}` placeholder's value is 1. `${FIXTURE}` | The fixture's name. `${TEST}` | The test's name. -`${USERAGENT}` | The combination of `${BROWSER}`, `${BROWSER_VERSION}`, `${OS}`, and `${OS_VERSION}`. +`${USERAGENT}` | The combination of `${BROWSER}`, `${BROWSER_VERSION}`, `${OS}`, and `${OS_VERSION}` (separated by underscores). `${BROWSER}` | The browser's name. `${BROWSER_VERSION}` | The browser's version. `${OS}` | The operation system's name. From 17f869c9da742caec81b44cf348a250926d1e20e Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Thu, 26 Jul 2018 12:57:15 +0300 Subject: [PATCH 032/184] Correct docs according to #2555 (#2657) --- .../intercepting-http-requests/logging-http-requests.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/articles/documentation/test-api/intercepting-http-requests/logging-http-requests.md b/docs/articles/documentation/test-api/intercepting-http-requests/logging-http-requests.md index 63dea196..a1d2318e 100644 --- a/docs/articles/documentation/test-api/intercepting-http-requests/logging-http-requests.md +++ b/docs/articles/documentation/test-api/intercepting-http-requests/logging-http-requests.md @@ -32,10 +32,10 @@ Option | Type | Description | Default ------ | ---- | ------------- | --------- `logRequestHeaders` | Boolean | Specifies whether the request headers should be logged. | `false` `logRequestBody` | Boolean | Specifies whether the request body should be logged. | `false` -`stringifyRequestBody` | Boolean | Specifies whether the request body should be stored as a String or a [Buffer](https://nodejs.org/api/buffer.html). | `false` +`stringifyRequestBody` | Boolean | Specifies whether the request body should be stored as a String or a [Buffer](https://nodejs.org/api/buffer.html). When you set `stringifyRequestBody` to `true`, make sure that the request body is logged (`logRequestBody` is also `true`). Otherwise, an error is thrown. | `false` `logResponseHeaders` | Boolean | Specifies whether the response headers should be logged. | `false` `logResponseBody` | Boolean | Specifies whether the response body should be logged. | `false` -`stringifyResponseBody` | Boolean | Specifies whether the response body should be stored as a string or a [Buffer](https://nodejs.org/api/buffer.html). | `false` +`stringifyResponseBody` | Boolean | Specifies whether the response body should be stored as a string or a [Buffer](https://nodejs.org/api/buffer.html). When you set `stringifyResponseBody` to `true`, make sure that the response body is logged (`logResponseBody` is also `true`). Otherwise, an error is thrown. | `false` ```js import { RequestLogger } from 'testcafe'; From 7b9ea079722985e0ddb595c3ee00b5fb45d3505c Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 27 Jul 2018 09:36:34 +0300 Subject: [PATCH 033/184] Replace a long tweet with a shorter one (#2669) --- docs/tweets/tweets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tweets/tweets.json b/docs/tweets/tweets.json index dedb9ed7..9054457a 100644 --- a/docs/tweets/tweets.json +++ b/docs/tweets/tweets.json @@ -1,6 +1,6 @@ [ { - "url": "https://twitter.com/martin_hotell/status/971339016888029184" + "url": "https://twitter.com/martin_hotell/status/958079928574119941" }, { "url": "https://twitter.com/pantvivek28/status/973799993705410560" From 3177a9a5663732d64d4881d3eb2ef4d3ba3b5f88 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Mon, 30 Jul 2018 12:23:36 +0300 Subject: [PATCH 034/184] [docs] Changelog for v0.21.0 (#2656) * Changelog for v0.21.0 * Address Miher's remarks * Some corrections * Add a bug to changelog * Update CHANGELOG.md * Update Changelog's Bug Fixes section --- CHANGELOG.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7849fe8a..e2fb53fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,92 @@ # Changelog +## v0.21.0 (2018-7-26) + +### Enhancements + +#### :gear: Test Web Pages Served Over HTTPS ([#1985](https://github.com/DevExpress/testcafe/issues/1985)) + +Some browser features (like [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API), [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API), [ApplePaySession](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession), or [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto)) require a secure origin. This means that the website should use the HTTPS protocol. + +Starting with v0.21.0, TestCafe can serve proxied web pages over HTTPS. This allows you to test pages that require a secure origin. + +To enable HTTPS when you use TestCafe through the command line, specify the [--ssl](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--ssl-options) flag followed by the [HTTPS server options](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). The most commonly used options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in the Node.js documentation. + +```sh +testcafe --ssl pfx=path/to/file.pfx;rejectUnauthorized=true;... +``` + +When you use a programming API, pass the HTTPS server options to the [createTestCafe](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/createtestcafe.html) method. + +```js +'use strict'; + +const createTestCafe = require('testcafe'); +const selfSignedSertificate = require('openssl-self-signed-certificate'); +let runner = null; + +const sslOptions = { + key: selfSignedSertificate.key, + cert: selfSignedSertificate.cert +}; + +createTestCafe('localhost', 1337, 1338, sslOptions) + .then(testcafe => { + runner = testcafe.createRunner(); + }) + .then(() => { + return runner + .src('test.js') + + // Browsers restrict self-signed certificate usage unless you + // explicitly set a flag specific to each browser. + // For Chrome, this is '--allow-insecure-localhost'. + .browsers('chrome --allow-insecure-localhost') + .run(); + }); +``` + +See [Connect to TestCafe Server over HTTPS](https://devexpress.github.io/testcafe/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.html) for more information. + +#### :gear: Construct Screenshot Paths with Patterns ([#2152](https://github.com/DevExpress/testcafe/issues/2152)) + +You can now use patterns to construct paths to screenshots. TestCafe provides a number of placeholders you can include in the path, for example, `${DATE}`, `${TIME}`, `${USERAGENT}`, etc. For a complete list, refer to the command line [--screenshot-path-pattern flag description](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#-p---screenshot-path-pattern). + +You specify a screenshot path pattern when you run tests. Each time TestCafe takes a screenshot, it substitutes the placeholders with actual values and saves the screenshot to the resulting path. + +The following example shows how to specify a screenshot path pattern through the command line: + +```sh +testcafe all test.js -s screenshots -p "${DATE}_${TIME}/test-${TEST_INDEX}/${USERAGENT}/${FILE_INDEX}.png" +``` + +When you use a programming API, pass the screenshot path pattern to the [runner.screenshots method](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#screenshots). + +```js +runner.screenshots('reports/screenshots/', true, '${TEST_INDEX}/${OS}/${BROWSER}-v${BROWSER_VERSION}/${FILE_INDEX}.png'); +``` + +#### :gear: Add Info About Screenshots and Quarantine Attempts to Custom Reports ([#2216](https://github.com/DevExpress/testcafe/issues/2216)) + +Custom reporters can now access screenshots' data and the history of quarantine attempts (if the test run in the quarantine mode). + +The following information about screenshots is now available: + +* the path to the screenshot file, +* the path to the thumbnail image, +* the browser's user agent, +* the quarantine attempt number (if the screenshot was taken in the quarantine mode), +* whether the screenshot was taken because the test failed. + +If the test was run in the quarantine mode, you can also determine which attempts failed and passed. + +Refer to the [reportTestDone method description](https://devexpress.github.io/testcafe/documentation/extending-testcafe/reporter-plugin/reporter-methods.html#reporttestdone) for details on how to access this information. + +### Bug Fixes + +* HTML5 drag events are no longer simulated if `event.preventDefault` is called for the `mousedown` event ([#2529](https://github.com/DevExpress/testcafe/issues/2529)) +* The `load` event listener is no longer triggered when added to an image ([testcafe-hammerhead/#1688](https://github.com/DevExpress/testcafe-hammerhead/issues/1688)) + ## v0.20.5 (2018-7-18) ### Bug fixes From 8c8c403f24fb2bd8b3780d7500e7e5b313f45b0f Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Mon, 30 Jul 2018 15:09:29 +0300 Subject: [PATCH 035/184] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2fb53fa..14cd3bb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## v0.21.0 (2018-7-26) +## v0.21.0 (2018-8-1) ### Enhancements From 684f4a790ca500573b8f6933fd5deb75be7c3b2c Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Tue, 31 Jul 2018 15:39:34 +0300 Subject: [PATCH 036/184] Bump version (v0.21.0-alpha.1) (#2679) --- .publishrc | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.publishrc b/.publishrc index 5727c783..2414a453 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "latest", + "publishTag": "alpha", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index 53549d8e..eb0ac405 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.20.5", + "version": "0.21.0-alpha.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" @@ -106,7 +106,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.4", - "testcafe-hammerhead": "14.2.2", + "testcafe-hammerhead": "14.2.3", "testcafe-legacy-api": "3.1.7", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", From 6f20c41c750eb8028ec7fdac38ae22ad09e63c89 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Tue, 31 Jul 2018 18:13:14 +0300 Subject: [PATCH 037/184] Add two bugs to the changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14cd3bb5..49f6fbda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -85,6 +85,8 @@ Refer to the [reportTestDone method description](https://devexpress.github.io/te ### Bug Fixes * HTML5 drag events are no longer simulated if `event.preventDefault` is called for the `mousedown` event ([#2529](https://github.com/DevExpress/testcafe/issues/2529)) +* File upload no longer causes an exception when there are several file inputs on the page ([#2642](https://github.com/DevExpress/testcafe/issues/2642)) +* File upload now works with inputs that have the `required` attribute ([#2509](https://github.com/DevExpress/testcafe/issues/2509)) * The `load` event listener is no longer triggered when added to an image ([testcafe-hammerhead/#1688](https://github.com/DevExpress/testcafe-hammerhead/issues/1688)) ## v0.20.5 (2018-7-18) From 1e38a585e19d9ab118c6b0b42ba5558ec884a04f Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Thu, 2 Aug 2018 15:19:21 +0300 Subject: [PATCH 038/184] fix wrong 'hasScroll' result for some IE specific case (part of #2511) (#2683) * fix wrong 'hasScroll' result for some IE specific case * add message to the test assertions * fix tests * fix review issues --- src/client/core/utils/style.js | 32 ++++++++++++++----- test/client/fixtures/core/style-utils-test.js | 21 ++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 test/client/fixtures/core/style-utils-test.js diff --git a/src/client/core/utils/style.js b/src/client/core/utils/style.js index 1c24f89e..7286976b 100644 --- a/src/client/core/utils/style.js +++ b/src/client/core/utils/style.js @@ -3,7 +3,8 @@ import * as domUtils from './dom'; import { filter, some } from './array'; -var styleUtils = hammerhead.utils.style; +const styleUtils = hammerhead.utils.style; +const browserUtils = hammerhead.utils.browser; export var getBordersWidth = hammerhead.utils.style.getBordersWidth; export var getComputedStyle = hammerhead.utils.style.getComputedStyle; @@ -24,7 +25,25 @@ export var setScrollLeft = hammerhead.utils.style.setScrollLeft; export var setScrollTop = hammerhead.utils.style.setScrollTop; export var get = hammerhead.utils.style.get; -const SCROLLABLE_OVERFLOW_STYLE_RE = /auto|scroll/i; +const SCROLLABLE_OVERFLOW_STYLE_RE = /auto|scroll/i; +const DEFAULT_IE_SCROLLABLE_OVERFLOW_STYLE_VALUE = 'visible'; + +const getScrollable = function (el) { + const overflowX = get(el, 'overflowX'); + const overflowY = get(el, 'overflowY'); + let scrollableHorizontally = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowX); + let scrollableVertically = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowY); + + // IE11 and MS Edge bug: There are two properties: overflow-x and overflow-y. + // If one property is set so that the browser may show scrollbars (`auto` or `scroll`) and the second one is set to 'visible', + // then the second one will work as if it had the 'auto' value. + if (browserUtils.isIE) { + scrollableHorizontally = scrollableHorizontally || scrollableVertically && overflowX === DEFAULT_IE_SCROLLABLE_OVERFLOW_STYLE_VALUE; + scrollableVertically = scrollableVertically || scrollableHorizontally && overflowY === DEFAULT_IE_SCROLLABLE_OVERFLOW_STYLE_VALUE; + } + + return { scrollableHorizontally, scrollableVertically }; +}; var getAncestors = function (node) { var ancestors = []; @@ -115,10 +134,7 @@ function hasHTMLElementScroll (el) { } export function hasScroll (el) { - var overflowX = get(el, 'overflowX'); - var overflowY = get(el, 'overflowY'); - var scrollableHorizontally = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowX); - var scrollableVertically = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowY); + const { scrollableHorizontally, scrollableVertically } = getScrollable(el); if (domUtils.isBodyElement(el)) return hasBodyScroll(el); @@ -129,8 +145,8 @@ export function hasScroll (el) { if (!scrollableHorizontally && !scrollableVertically) return false; - var hasHorizontalScroll = scrollableVertically && el.scrollHeight > el.clientHeight; - var hasVerticalScroll = scrollableHorizontally && el.scrollWidth > el.clientWidth; + const hasVerticalScroll = scrollableVertically && el.scrollHeight > el.clientHeight; + const hasHorizontalScroll = scrollableHorizontally && el.scrollWidth > el.clientWidth; return hasHorizontalScroll || hasVerticalScroll; } diff --git a/test/client/fixtures/core/style-utils-test.js b/test/client/fixtures/core/style-utils-test.js new file mode 100644 index 00000000..64fe5728 --- /dev/null +++ b/test/client/fixtures/core/style-utils-test.js @@ -0,0 +1,21 @@ +var testCafeCore = window.getTestCafeModule('testCafeCore'); +var styleUtils = testCafeCore.get('./utils/style'); + +test('hasScroll (GH-2511)', function () { + var div = document.createElement('div'); + var innerDiv = document.createElement('div'); + + div.appendChild(innerDiv); + innerDiv.setAttribute('style', 'border: 1px solid red; width: 100px; height: 60px;'); + document.body.appendChild(div); + + // Vertical scroll + div.setAttribute('style', 'width: 200px; height: 20px; overflow-x: auto; border: 1px solid black;'); + ok(styleUtils.hasScroll(div), 'vertical scroll'); + + // Horizontal scroll + div.setAttribute('style', 'width: 50px; height: 150px; overflow-y: auto; border: 1px solid black;'); + ok(styleUtils.hasScroll(div), 'horizontal scroll'); + + div.parentNode.removeChild(div); +}); From d59984f0de773c17b4aa0f42e05629d419d105e5 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Thu, 2 Aug 2018 15:43:56 +0300 Subject: [PATCH 039/184] [docs] Add an announcement blog post for v0.21.0 (#2663) --- .../2018-08-02-testcafe-v0-21-0-released.md | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 docs/articles/blog/2018-08-02-testcafe-v0-21-0-released.md diff --git a/docs/articles/blog/2018-08-02-testcafe-v0-21-0-released.md b/docs/articles/blog/2018-08-02-testcafe-v0-21-0-released.md new file mode 100644 index 00000000..cce577ed --- /dev/null +++ b/docs/articles/blog/2018-08-02-testcafe-v0-21-0-released.md @@ -0,0 +1,97 @@ +--- +layout: post +title: TestCafe v0.21.0 Released +permalink: /blog/:title.html +--- +# TestCafe v0.21.0 Released + +Test web pages served over HTTPS, construct screenshot paths with patterns and use more info in custom reporters. + + + +## Enhancements + +### ⚙ Test Web Pages Served Over HTTPS ([#1985](https://github.com/DevExpress/testcafe/issues/1985)) + +Some browser features (like [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API), [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API), [ApplePaySession](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession), or [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto)) require a secure origin. This means that the website should use the HTTPS protocol. + +Starting with v0.21.0, TestCafe can serve proxied web pages over HTTPS. This allows you to test pages that require a secure origin. + +To enable HTTPS when you use TestCafe through the command line, specify the [--ssl](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--ssl-options) flag followed by the [HTTPS server options](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). The most commonly used options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in the Node.js documentation. + +```sh +testcafe --ssl pfx=path/to/file.pfx;rejectUnauthorized=true;... +``` + +When you use a programming API, pass the HTTPS server options to the [createTestCafe](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/createtestcafe.html) method. + +```js +'use strict'; + +const createTestCafe = require('testcafe'); +const selfSignedSertificate = require('openssl-self-signed-certificate'); +let runner = null; + +const sslOptions = { + key: selfSignedSertificate.key, + cert: selfSignedSertificate.cert +}; + +createTestCafe('localhost', 1337, 1338, sslOptions) + .then(testcafe => { + runner = testcafe.createRunner(); + }) + .then(() => { + return runner + .src('test.js') + + // Browsers restrict self-signed certificate usage unless you + // explicitly set a flag specific to each browser. + // For Chrome, this is '--allow-insecure-localhost'. + .browsers('chrome --allow-insecure-localhost') + .run(); + }); +``` + +See [Connect to TestCafe Server over HTTPS](https://devexpress.github.io/testcafe/documentation/using-testcafe/common-concepts/connect-to-the-testcafe-server-over-https.html) for more information. + +### ⚙ Construct Screenshot Paths with Patterns ([#2152](https://github.com/DevExpress/testcafe/issues/2152)) + +You can now use patterns to construct paths to screenshots. TestCafe provides a number of placeholders you can include in the path, for example, `${DATE}`, `${TIME}`, `${USERAGENT}`, etc. For a complete list, refer to the command line [--screenshot-path-pattern flag description](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#-p---screenshot-path-pattern). + +You specify a screenshot path pattern when you run tests. Each time TestCafe takes a screenshot, it substitutes the placeholders with actual values and saves the screenshot to the resulting path. + +The following example shows how to specify a screenshot path pattern through the command line: + +```sh +testcafe all test.js -s screenshots -p "${DATE}_${TIME}/test-${TEST_INDEX}/${USERAGENT}/${FILE_INDEX}.png" +``` + +When you use a programming API, pass the screenshot path pattern to the [runner.screenshots method](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#screenshots). + +```js +runner.screenshots('reports/screenshots/', true, '${TEST_INDEX}/${OS}/${BROWSER}-v${BROWSER_VERSION}/${FILE_INDEX}.png'); +``` + +### ⚙ Add Info About Screenshots and Quarantine Attempts to Custom Reports ([#2216](https://github.com/DevExpress/testcafe/issues/2216)) + +Custom reporters can now access screenshots' data and the history of quarantine attempts (if the test run in the quarantine mode). + +The following information about screenshots is now available: + +* the path to the screenshot file, +* the path to the thumbnail image, +* the user agent of the browser in which the screenshot was taken, +* the quarantine attempt number (if the screenshot was taken in the quarantine mode), +* whether the screenshot was taken because the test failed. + +If the test was run in the quarantine mode, you can also determine which attempts failed and passed. + +Refer to the [reportTestDone method description](https://devexpress.github.io/testcafe/documentation/extending-testcafe/reporter-plugin/reporter-methods.html#reporttestdone) for details on how to access this information. + +## Bug Fixes + +* HTML5 drag events are no longer simulated if `event.preventDefault` is called for the `mousedown` event ([#2529](https://github.com/DevExpress/testcafe/issues/2529)) +* File upload no longer causes an exception when there are several file inputs on the page ([#2642](https://github.com/DevExpress/testcafe/issues/2642)) +* File upload now works with inputs that have the `required` attribute ([#2509](https://github.com/DevExpress/testcafe/issues/2509)) +* The `load` event listener is no longer triggered when added to an image ([testcafe-hammerhead/#1688](https://github.com/DevExpress/testcafe-hammerhead/issues/1688)) From 4cd4a3b2f5c3dec3dbfd14e8e8f3147dddc45878 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Thu, 2 Aug 2018 16:30:55 +0300 Subject: [PATCH 040/184] Bump version (v0.21.0) (#2690) --- .publishrc | 2 +- CHANGELOG.md | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.publishrc b/.publishrc index 2414a453..5727c783 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "alpha", + "publishTag": "latest", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 49f6fbda..ed46c3fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## v0.21.0 (2018-8-1) +## v0.21.0 (2018-8-2) ### Enhancements diff --git a/package.json b/package.json index eb0ac405..3a1bb6b2 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.21.0-alpha.1", + "version": "0.21.0", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From f88438315afd0fcebcdb85bb2fc6fd9cdb291d0f Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Thu, 2 Aug 2018 17:04:17 +0300 Subject: [PATCH 041/184] [docs] Update the FAQ part about TestCafe versions (#2691) * Update the FAQ part about TestCafe versions * Add an article * Correct the text about Studio supporting OS features --- docs/articles/faq/README.md | 46 ++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/docs/articles/faq/README.md b/docs/articles/faq/README.md index 523fb071..14aeb26d 100644 --- a/docs/articles/faq/README.md +++ b/docs/articles/faq/README.md @@ -7,7 +7,7 @@ permalink: /faq/ * [General Questions](#general-questions) * [I have heard that TestCafe does not use Selenium. How does it operate?](#i-have-heard-that-testcafe-does-not-use-selenium-how-does-it-operate) - * [What is the difference between a paid and an open-source TestCafe version?](#what-is-the-difference-between-a-paid-and-an-open-source-testcafe-version) + * [What is the difference between a paid and an open-source TestCafe version? What is TestCafe Studio?](#what-is-the-difference-between-a-paid-and-an-open-source-testcafe-version-what-is-testcafe-studio) * [Which browsers does TestCafe support? What are the exact supported versions?](#which-browsers-does-testcafe-support-what-are-the-exact-supported-versions) * [Can I use third-party modules in tests?](#can-i-use-third-party-modules-in-tests) * [How do I work with configuration files and environment variables?](#how-do-i-work-with-configuration-files-and-environment-variables) @@ -32,32 +32,36 @@ This proxy injects the driver script that emulates user actions into the tested You can read about this in our [forum](https://testcafe-discuss.devexpress.com/t/why-not-use-selenium/47). Feel free to ask for more details. -### What is the difference between a [paid](https://testcafe.devexpress.com) and an [open-source](https://devexpress.github.io/testcafe) TestCafe version? +### What is the difference between a [paid](https://testcafe.devexpress.com) and an [open-source](https://devexpress.github.io/testcafe) TestCafe version? What is [TestCafe Studio](https://testcafe-studio.devexpress.com/)? -TestCafe first appeared as a paid, standalone tool. It had several features besides the test runner: the -[Control Panel](https://testcafe.devexpress.com/Documentation/Using_TestCafe/Control_Panel/), -a visual interface for creating, modifying and running your tests, and the -[Visual Test Recorder](https://testcafe.devexpress.com/Documentation/Using_TestCafe/Visual_Test_Recorder/) -for recording tests by pointing and clicking through the test scenario in the browser. +All three versions share the same core features: -In 2015 we decided to release the TestCafe core as an open-source project. -The last major paid version release (v15.1) was in summer 2015. -After that, it switched to a maintenance-only mode. -You can find the latest paid version at [https://testcafe.devexpress.com](https://testcafe.devexpress.com). +* No need for WebDriver, browser plugins or other tools. +* Cross-platform and cross-browser out of the box. -We released the open-source TestCafe in late 2016. -It has the same name but contains lots of new functionality and improvements: +[TestCafe](https://testcafe.devexpress.com) +*2013, commercial web application* -* a new API and offers a new approach to writing tests; -* no UI to manage and run tests. You can run tests from the CLI or node.js module; -* it is more convenient to integrate into node.js development workflow; -* es6 support, flexible selectors and smart assertions, authentication features, etc. +* Visual Test Recorder and web GUI to create, edit and run tests. +* You can record tests or edit them as JavaScript code. -You can learn more about the open-source version at [https://devexpress.github.io/testcafe](https://devexpress.github.io/testcafe). +[TestCafe](https://devexpress.github.io/testcafe) +*2016, free and open-source node.js application* -We have not abandoned our aspirations to create a competitive proprietary product. -We plan to release a new commercial version called ***TestCafe Studio***, based on the revised open-source TestCafe. -Follow us on [Twitter](https://twitter.com/DXTestCafe) for the news about TestCafe Studio. +* You can write tests in the latest JavaScript or TypeScript. +* Clearer and more flexible [API](https://devexpress.github.io/testcafe/documentation/test-api/) supports ES6 and [PageModel pattern](https://devexpress.github.io/testcafe/documentation/recipes/using-page-model.html). +* More stable tests due to the [Smart Assertion Query Mechanism](https://devexpress.github.io/testcafe/documentation/test-api/assertions/#smart-assertion-query-mechanism). +* Tests run faster due to improved [Automatic Waiting Mechanism](https://devexpress.github.io/testcafe/documentation/test-api/waiting-for-page-elements-to-appear.html) and [Concurrent Test Execution](https://devexpress.github.io/testcafe/documentation/using-testcafe/common-concepts/concurrent-test-execution.html). +* Easy integration: it is a node.js solution with CLI and reporters for popular CI systems. +* You can extend it with [plugins](https://github.com/DevExpress/testcafe#plugins) and other Node.js modules. + +[TestCafe Studio](https://testcafe-studio.devexpress.com) +*2018, commercial desktop application* + +* Based on the open-source TestCafe, and supports its major features. +* You can record tests or edit them as JavaScript or TypeScript code. +* New [Visual Test Recorder](https://testcafe-studio.devexpress.com/documentation/guides/record-tests/) and [IDE-like GUI](https://testcafe-studio.devexpress.com/documentation/guides/write-test-code.html) to record, edit, run and debug tests. +* Currently available as a free preview version. ### Which browsers does TestCafe support? What are the exact supported versions? From 49706bf0381310a0bc8343dfb3e0f58005d9e2b2 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 3 Aug 2018 16:01:44 +0300 Subject: [PATCH 042/184] FAQ - Add explanations about release years (#2698) --- docs/articles/faq/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/articles/faq/README.md b/docs/articles/faq/README.md index 14aeb26d..e69b2142 100644 --- a/docs/articles/faq/README.md +++ b/docs/articles/faq/README.md @@ -40,13 +40,13 @@ All three versions share the same core features: * Cross-platform and cross-browser out of the box. [TestCafe](https://testcafe.devexpress.com) -*2013, commercial web application* +*first released in 2013, commercial web application* * Visual Test Recorder and web GUI to create, edit and run tests. * You can record tests or edit them as JavaScript code. [TestCafe](https://devexpress.github.io/testcafe) -*2016, free and open-source node.js application* +*first released in 2016, free and open-source node.js application* * You can write tests in the latest JavaScript or TypeScript. * Clearer and more flexible [API](https://devexpress.github.io/testcafe/documentation/test-api/) supports ES6 and [PageModel pattern](https://devexpress.github.io/testcafe/documentation/recipes/using-page-model.html). @@ -56,7 +56,7 @@ All three versions share the same core features: * You can extend it with [plugins](https://github.com/DevExpress/testcafe#plugins) and other Node.js modules. [TestCafe Studio](https://testcafe-studio.devexpress.com) -*2018, commercial desktop application* +*first released in 2018, commercial desktop application* * Based on the open-source TestCafe, and supports its major features. * You can record tests or edit them as JavaScript or TypeScript code. From 00a263159ba28ba5cf6c7b4d1323a786b7f9039f Mon Sep 17 00:00:00 2001 From: Natu <11683678+Nuarat@users.noreply.github.com> Date: Fri, 3 Aug 2018 16:04:00 +0300 Subject: [PATCH 043/184] [docs] Add diffs between TestCafe versions (#2697) * [docs] Add diffs between TestCafe versions Added the part of FAQ about differences between the paid, open-source TestCafe and TestCafe Studio. * Added "first released in..." --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index 99c66443..42cb7fce 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ * [Badge](#badge) * [Contributing](#contributing) * [Plugins](#plugins) +* [Different versions of TestCafe](#different-versions-of-testcafe) * [License](#license) * [Creators](#creators) @@ -239,6 +240,35 @@ TestCafe developers and community members made these plugins: * **ESLint**
Use ESLint when writing and editing TestCafe tests. * [ESLint plugin](https://github.com/miherlosev/eslint-plugin-testcafe) (by [@miherlosev](https://github.com/miherlosev)) + +## Different versions of TestCafe + +There is a line of products called `TestCafe`. Below are the similarities and key differences between them. + +* All three versions share the same core features: + * No need for WebDriver, browser plugins or other tools. + * Cross-platform and cross-browser out of the box. + +* [**TestCafe**](https://testcafe.devexpress.com/)
+ *first released in 2013, commercial web application* + * Visual Test Recorder and web GUI to create, edit and run tests. + * You can record tests or edit them as JavaScript code. + +* [**TestCafe**](https://devexpress.github.io/testcafe) - you are here
+ *first released in 2016, free and open-source node.js application* + * You can write tests in the latest JavaScript or TypeScript. + * Clearer and more flexible [API](https://devexpress.github.io/testcafe/documentation/test-api/) supports ES6 and [PageModel pattern](https://devexpress.github.io/testcafe/documentation/recipes/using-page-model.html). + * More stable tests due to the [Smart Assertion Query Mechanism](https://devexpress.github.io/testcafe/documentation/test-api/assertions/#smart-assertion-query-mechanism). + * Tests run faster due to improved [Automatic Waiting Mechanism](https://devexpress.github.io/testcafe/documentation/test-api/waiting-for-page-elements-to-appear.html) and [Concurrent Test Execution](https://devexpress.github.io/testcafe/documentation/using-testcafe/common-concepts/concurrent-test-execution.html). + * Easy integration: it is a node.js solution with CLI and reporters for popular CI systems. + * You can extend it with [plugins](#plugins) and other Node.js modules. + +* [**TestCafe Studio**](https://testcafe-studio.devexpress.com/)
+ *first released in 2018, commercial desktop application* + * Based on the open-source TestCafe, and supports its major features. + * You can record tests or edit them as JavaScript or TypeScript code. + * New [Visual Test Recorder](https://testcafe-studio.devexpress.com/documentation/guides/record-tests/) and [IDE-like GUI](https://testcafe-studio.devexpress.com/documentation/guides/write-test-code.html) to record, edit, run and debug tests. + * Currently available as a free preview version. The release version will replace the 2013 version of TestCafe. ## Thanks to BrowserStack From 2bdfebfb3f8b818b70a02d0df586fec848bee4ab Mon Sep 17 00:00:00 2001 From: Andrey Churkin Date: Tue, 7 Aug 2018 11:20:20 +0300 Subject: [PATCH 044/184] Add ExecuteExpressionCommand to RAW API (#2632) --- src/api/test-controller/index.js | 2 +- .../client-function-builder.js | 8 +- src/compiler/test-file/formats/raw.js | 3 +- src/errors/test-run/index.js | 6 + src/errors/test-run/templates.js | 4 + src/errors/test-run/type.js | 1 + src/test-run/commands/actions.js | 272 ++++++------------ src/test-run/commands/assertion.js | 31 +- src/test-run/commands/base.js | 11 + src/test-run/commands/browser-manipulation.js | 80 ++---- src/test-run/commands/from-object.js | 76 ++--- src/test-run/commands/observation.js | 55 ++-- src/test-run/commands/type.js | 1 + .../commands/validations/initializers.js | 9 +- src/test-run/execute-js-expression.js | 36 ++- src/test-run/index.js | 22 +- src/utils/assignable.js | 9 +- .../raw/execute-expression/pages/index.html | 8 + .../api/raw/execute-expression/test.js | 17 ++ .../testcafe-fixtures/shared-context.testcafe | 90 ++++++ .../action-boolean-argument-error | 20 ++ test/server/test-run-commands-test.js | 137 ++++++++- test/server/test-run-error-formatting-test.js | 5 + 23 files changed, 550 insertions(+), 353 deletions(-) create mode 100644 src/test-run/commands/base.js create mode 100644 test/functional/fixtures/api/raw/execute-expression/pages/index.html create mode 100644 test/functional/fixtures/api/raw/execute-expression/test.js create mode 100644 test/functional/fixtures/api/raw/execute-expression/testcafe-fixtures/shared-context.testcafe create mode 100644 test/server/data/expected-test-run-errors/action-boolean-argument-error diff --git a/src/api/test-controller/index.js b/src/api/test-controller/index.js index dc864280..735e0c84 100644 --- a/src/api/test-controller/index.js +++ b/src/api/test-controller/index.js @@ -95,7 +95,7 @@ export default class TestController { var command = null; try { - command = new CmdCtor(cmdArgs); + command = new CmdCtor(cmdArgs, this.testRun); } catch (err) { err.callsite = callsite; diff --git a/src/client-functions/client-function-builder.js b/src/client-functions/client-function-builder.js index ab27a6e2..d505072e 100644 --- a/src/client-functions/client-function-builder.js +++ b/src/client-functions/client-function-builder.js @@ -59,11 +59,15 @@ export default class ClientFunctionBuilder { return null; } + _getTestRun () { + return this.getBoundTestRun() || testRunTracker.resolveContextTestRun(); + } + getFunction () { var builder = this; var clientFn = function __$$clientFunction$$ () { - var testRun = builder.getBoundTestRun() || testRunTracker.resolveContextTestRun(); + var testRun = builder._getTestRun(); var callsite = getCallsiteForMethod(builder.callsiteNames.execution); var args = []; @@ -98,7 +102,7 @@ export default class ClientFunctionBuilder { fnCode: this.compiledFnCode, args: encodedArgs, dependencies: encodedDependencies - }); + }, this._getTestRun()); } _getCompiledFnCode () { diff --git a/src/compiler/test-file/formats/raw.js b/src/compiler/test-file/formats/raw.js index a72962ce..fc6995b2 100644 --- a/src/compiler/test-file/formats/raw.js +++ b/src/compiler/test-file/formats/raw.js @@ -14,7 +14,8 @@ export default class RawTestFileCompiler extends TestFileCompilerBase { var command = null; try { - command = createCommandFromObject(commands[i]); + command = createCommandFromObject(commands[i], t.testRun); + await t.testRun.executeCommand(command, callsite); } catch (err) { diff --git a/src/errors/test-run/index.js b/src/errors/test-run/index.js index 6c741d25..c114f196 100644 --- a/src/errors/test-run/index.js +++ b/src/errors/test-run/index.js @@ -186,6 +186,12 @@ export class ActionBooleanOptionError extends ActionOptionErrorBase { } } +export class ActionBooleanArgumentError extends ActionArgumentErrorBase { + constructor (argumentName, actualValue) { + super(TYPE.actionBooleanArgumentError, argumentName, actualValue); + } +} + export class ActionSpeedOptionError extends ActionOptionErrorBase { constructor (optionName, actualValue) { super(TYPE.actionSpeedOptionError, optionName, actualValue); diff --git a/src/errors/test-run/templates.js b/src/errors/test-run/templates.js index e33fc4e8..7adb25f3 100644 --- a/src/errors/test-run/templates.js +++ b/src/errors/test-run/templates.js @@ -113,6 +113,10 @@ export default { The "${err.argumentName}" argument is expected to be a non-empty string, but it was ${err.actualValue}. `), + [TYPE.actionBooleanArgumentError]: err => markup(err, ` + The "${err.argumentName}" argument is expected to be a boolean value, but it was ${err.actualValue}. + `), + [TYPE.actionNullableStringArgumentError]: err => markup(err, ` The "${err.argumentName}" argument is expected to be a null or a string, but it was ${err.actualValue}. `), diff --git a/src/errors/test-run/type.js b/src/errors/test-run/type.js index 2186b5fb..e10a7ff6 100644 --- a/src/errors/test-run/type.js +++ b/src/errors/test-run/type.js @@ -15,6 +15,7 @@ export default { actionBooleanOptionError: 'actionBooleanOptionError', actionSpeedOptionError: 'actionSpeedOptionError', actionOptionsTypeError: 'actionOptionsTypeError', + actionBooleanArgumentError: 'actionBooleanArgumentError', actionStringArgumentError: 'actionStringArgumentError', actionNullableStringArgumentError: 'actionNullableStringArgumentError', actionStringOrStringArrayArgumentError: 'actionStringOrStringArrayArgumentError', diff --git a/src/test-run/commands/actions.js b/src/test-run/commands/actions.js index ec567035..3ef70a46 100644 --- a/src/test-run/commands/actions.js +++ b/src/test-run/commands/actions.js @@ -2,9 +2,9 @@ import TYPE from './type'; import SelectorBuilder from '../../client-functions/selectors/selector-builder'; import ClientFunctionBuilder from '../../client-functions/client-function-builder'; import functionBuilderSymbol from '../../client-functions/builder-symbol'; -import Assignable from '../../utils/assignable'; +import CommandBase from './base'; import { ActionOptions, ClickOptions, MouseOptions, TypeOptions, DragToElementOptions } from './options'; -import { initSelector } from './validations/initializers'; +import { initSelector, initUploadSelector } from './validations/initializers'; import { actionOptions, @@ -15,7 +15,8 @@ import { urlArgument, stringOrStringArrayArgument, setSpeedArgument, - actionRoleArgument + actionRoleArgument, + booleanArgument } from './validations/argument'; import { SetNativeDialogHandlerCodeWrongTypeError } from '../../errors/test-run'; @@ -67,15 +68,9 @@ function initDialogHandler (name, val) { } // Commands -export class ClickCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.click; - this.selector = null; - this.options = null; - - this._assignFrom(obj, true); +export class ClickCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.click); } _getAssignableProperties () { @@ -86,15 +81,9 @@ export class ClickCommand extends Assignable { } } -export class RightClickCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.rightClick; - this.selector = null; - this.options = null; - - this._assignFrom(obj, true); +export class RightClickCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.rightClick); } _getAssignableProperties () { @@ -105,15 +94,23 @@ export class RightClickCommand extends Assignable { } } -export class DoubleClickCommand extends Assignable { - constructor (obj) { - super(obj); +export class ExecuteExpressionCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.executeExpression); + } - this.type = TYPE.doubleClick; - this.selector = null; - this.options = null; + _getAssignableProperties () { + return [ + { name: 'expression', type: nonEmptyStringArgument, required: true }, + { name: 'resultVariableName', type: nonEmptyStringArgument, defaultValue: null }, + { name: 'isAsyncExpression', type: booleanArgument, defaultValue: false } + ]; + } +} - this._assignFrom(obj, true); +export class DoubleClickCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.doubleClick); } _getAssignableProperties () { @@ -124,15 +121,9 @@ export class DoubleClickCommand extends Assignable { } } -export class HoverCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.hover; - this.selector = null; - this.options = null; - - this._assignFrom(obj, true); +export class HoverCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.hover); } _getAssignableProperties () { @@ -143,16 +134,9 @@ export class HoverCommand extends Assignable { } } -export class TypeTextCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.typeText; - this.selector = null; - this.text = null; - this.options = null; - - this._assignFrom(obj, true); +export class TypeTextCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.typeText); } _getAssignableProperties () { @@ -164,17 +148,9 @@ export class TypeTextCommand extends Assignable { } } -export class DragCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.drag; - this.selector = null; - this.dragOffsetX = null; - this.dragOffsetY = null; - this.options = null; - - this._assignFrom(obj, true); +export class DragCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.drag); } _getAssignableProperties () { @@ -187,17 +163,9 @@ export class DragCommand extends Assignable { } } -export class DragToElementCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.dragToElement; - - this.selector = null; - this.destinationSelector = null; - this.options = null; - - this._assignFrom(obj, true); +export class DragToElementCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.dragToElement); } _getAssignableProperties () { @@ -209,86 +177,55 @@ export class DragToElementCommand extends Assignable { } } -export class SelectTextCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.selectText; - this.selector = null; - this.startPos = null; - this.endPos = null; - this.options = null; - - this._assignFrom(obj, true); +export class SelectTextCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.selectText); } _getAssignableProperties () { return [ { name: 'selector', init: initSelector, required: true }, - { name: 'startPos', type: positiveIntegerArgument }, - { name: 'endPos', type: positiveIntegerArgument }, + { name: 'startPos', type: positiveIntegerArgument, defaultValue: null }, + { name: 'endPos', type: positiveIntegerArgument, defaultValue: null }, { name: 'options', type: actionOptions, init: initActionOptions, required: true } ]; } } -export class SelectEditableContentCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.selectEditableContent; - this.startSelector = null; - this.endSelector = null; - this.options = null; - - this._assignFrom(obj, true); +export class SelectEditableContentCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.selectEditableContent); } _getAssignableProperties () { return [ { name: 'startSelector', init: initSelector, required: true }, - { name: 'endSelector', init: initSelector }, + { name: 'endSelector', init: initSelector, defaultValue: null }, { name: 'options', type: actionOptions, init: initActionOptions, required: true } ]; } } -export class SelectTextAreaContentCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.selectTextAreaContent; - this.selector = null; - this.startLine = null; - this.startPos = null; - this.endLine = null; - this.endPos = null; - this.options = null; - - this._assignFrom(obj, true); +export class SelectTextAreaContentCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.selectTextAreaContent); } _getAssignableProperties () { return [ { name: 'selector', init: initSelector, required: true }, - { name: 'startLine', type: positiveIntegerArgument }, - { name: 'startPos', type: positiveIntegerArgument }, - { name: 'endLine', type: positiveIntegerArgument }, - { name: 'endPos', type: positiveIntegerArgument }, + { name: 'startLine', type: positiveIntegerArgument, defaultValue: null }, + { name: 'startPos', type: positiveIntegerArgument, defaultValue: null }, + { name: 'endLine', type: positiveIntegerArgument, defaultValue: null }, + { name: 'endPos', type: positiveIntegerArgument, defaultValue: null }, { name: 'options', type: actionOptions, init: initActionOptions, required: true } ]; } } -export class PressKeyCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.pressKey; - this.keys = ''; - this.options = null; - - this._assignFrom(obj, true); +export class PressKeyCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.pressKey); } _getAssignableProperties () { @@ -299,70 +236,47 @@ export class PressKeyCommand extends Assignable { } } -export class NavigateToCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.navigateTo; - this.url = null; - this.stateSnapshot = null; - - this._assignFrom(obj, true); +export class NavigateToCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.navigateTo); } _getAssignableProperties () { return [ { name: 'url', type: urlArgument, required: true }, - { name: 'stateSnapshot', type: nullableStringArgument } + { name: 'stateSnapshot', type: nullableStringArgument, defaultValue: null } ]; } } -export class SetFilesToUploadCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.setFilesToUpload; - - this.selector = null; - this.filePath = ''; - - this._assignFrom(obj, true); +export class SetFilesToUploadCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.setFilesToUpload); } _getAssignableProperties () { return [ - { name: 'selector', init: (name, val) => initSelector(name, val, true), required: true }, + { name: 'selector', init: initUploadSelector, required: true }, { name: 'filePath', type: stringOrStringArrayArgument, required: true } ]; } } -export class ClearUploadCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.clearUpload; - - this.selector = null; - - this._assignFrom(obj, true); +export class ClearUploadCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.clearUpload); } _getAssignableProperties () { return [ - { name: 'selector', init: (name, val) => initSelector(name, val, true), required: true } + { name: 'selector', init: initUploadSelector, required: true } ]; } } -export class SwitchToIframeCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.switchToIframe; - this.selector = null; - this._assignFrom(obj, true); +export class SwitchToIframeCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.switchToIframe); } _getAssignableProperties () { @@ -378,14 +292,9 @@ export class SwitchToMainWindowCommand { } } -export class SetNativeDialogHandlerCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.setNativeDialogHandler; - this.dialogHandler = {}; - - this._assignFrom(obj, true); +export class SetNativeDialogHandlerCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.setNativeDialogHandler); } _getAssignableProperties () { @@ -407,14 +316,9 @@ export class GetBrowserConsoleMessagesCommand { } } -export class SetTestSpeedCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.setTestSpeed; - this.speed = null; - - this._assignFrom(obj, true); +export class SetTestSpeedCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.setTestSpeed); } _getAssignableProperties () { @@ -424,14 +328,9 @@ export class SetTestSpeedCommand extends Assignable { } } -export class SetPageLoadTimeoutCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.setPageLoadTimeout; - this.duration = null; - - this._assignFrom(obj, true); +export class SetPageLoadTimeoutCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.setPageLoadTimeout); } _getAssignableProperties () { @@ -441,14 +340,9 @@ export class SetPageLoadTimeoutCommand extends Assignable { } } -export class UseRoleCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.useRole; - this.role = null; - - this._assignFrom(obj, true); +export class UseRoleCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.useRole); } _getAssignableProperties () { diff --git a/src/test-run/commands/assertion.js b/src/test-run/commands/assertion.js index 2c3c1cbb..38315637 100644 --- a/src/test-run/commands/assertion.js +++ b/src/test-run/commands/assertion.js @@ -1,5 +1,5 @@ import TYPE from './type'; -import Assignable from '../../utils/assignable'; +import CommandBase from './base'; import { AssertionOptions } from './options'; import { APIError } from '../../errors/runtime'; import { AssertionExecutableArgumentError } from '../../errors/test-run'; @@ -14,10 +14,10 @@ function initAssertionOptions (name, val) { } //Initializers -function initAssertionParameter (name, val, skipVisibilityCheck) { +function initAssertionParameter (name, val, { skipVisibilityCheck, testRun }) { try { if (isJSExpression(val)) - val = executeJsExpression(val.value, skipVisibilityCheck); + val = executeJsExpression(val.value, testRun, skipVisibilityCheck); return val; } @@ -29,29 +29,18 @@ function initAssertionParameter (name, val, skipVisibilityCheck) { } // Commands -export default class AssertionCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.assertion; - - this.assertionType = null; - this.actual = void 0; - this.expected = void 0; - this.expected2 = void 0; - this.message = null; - this.options = null; - - this._assignFrom(obj, true); +export default class AssertionCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.assertion); } _getAssignableProperties () { return [ { name: 'assertionType', type: nonEmptyStringArgument, required: true }, - { name: 'actual', init: initAssertionParameter }, - { name: 'expected', init: initAssertionParameter }, - { name: 'expected2', init: initAssertionParameter }, - { name: 'message', type: stringArgument }, + { name: 'actual', init: initAssertionParameter, defaultValue: void 0 }, + { name: 'expected', init: initAssertionParameter, defaultValue: void 0 }, + { name: 'expected2', init: initAssertionParameter, defaultValue: void 0 }, + { name: 'message', type: stringArgument, defaultValue: null }, { name: 'options', type: actionOptions, init: initAssertionOptions, required: true } ]; } diff --git a/src/test-run/commands/base.js b/src/test-run/commands/base.js new file mode 100644 index 00000000..7affea3c --- /dev/null +++ b/src/test-run/commands/base.js @@ -0,0 +1,11 @@ +import Assignable from '../../utils/assignable'; + +export default class CommandBase extends Assignable { + constructor (obj, testRun, type, validateProperties = true) { + super(); + + this.type = type; + + this._assignFrom(obj, validateProperties, { testRun }); + } +} diff --git a/src/test-run/commands/browser-manipulation.js b/src/test-run/commands/browser-manipulation.js index 5491920a..5a8a60d3 100644 --- a/src/test-run/commands/browser-manipulation.js +++ b/src/test-run/commands/browser-manipulation.js @@ -1,5 +1,5 @@ import TYPE from './type'; -import Assignable from '../../utils/assignable'; +import CommandBase from './base'; import { ElementScreenshotOptions, ResizeToFitDeviceOptions } from './options'; import { initSelector } from './validations/initializers'; @@ -22,18 +22,12 @@ function initElementScreenshotOptions (name, val) { } // Commands -class TakeScreenshotBaseCommand extends Assignable { - constructor (obj) { - super(obj); +class TakeScreenshotBaseCommand extends CommandBase { + constructor (obj, testRun, type) { + super(obj, testRun, type); this.markSeed = null; this.markData = ''; - - this._assignFrom(obj, true); - } - - _getAssignableProperties () { - return []; } generateScreenshotMark () { @@ -42,58 +36,44 @@ class TakeScreenshotBaseCommand extends Assignable { } export class TakeScreenshotCommand extends TakeScreenshotBaseCommand { - constructor (obj) { - super(obj); - - this.type = TYPE.takeScreenshot; - this.path = ''; - - this._assignFrom(obj, true); + constructor (obj, testRun) { + super(obj, testRun, TYPE.takeScreenshot); } _getAssignableProperties () { - return super._getAssignableProperties().concat([ - { name: 'path', type: nonEmptyStringArgument } - ]); + return [ + { name: 'path', type: nonEmptyStringArgument, defaultValue: '' } + ]; } } -export class TakeElementScreenshotCommand extends TakeScreenshotCommand { - constructor (obj) { - super(obj); - - this.type = TYPE.takeElementScreenshot; - this.selector = null; - this.options = null; - - this._assignFrom(obj, true); +export class TakeElementScreenshotCommand extends TakeScreenshotBaseCommand { + constructor (obj, testRun) { + super(obj, testRun, TYPE.takeElementScreenshot); } _getAssignableProperties () { - return super._getAssignableProperties().concat([ + return [ { name: 'selector', init: initSelector, required: true }, - { name: 'options', init: initElementScreenshotOptions, required: true } - ]); + { name: 'options', init: initElementScreenshotOptions, required: true }, + { name: 'path', type: nonEmptyStringArgument, defaultValue: '' } + ]; } } export class TakeScreenshotOnFailCommand extends TakeScreenshotBaseCommand { - constructor () { - super(); + constructor (obj, testRun) { + super(obj, testRun, TYPE.takeScreenshotOnFail); + } - this.type = TYPE.takeScreenshotOnFail; + _getAssignableProperties () { + return []; } } -export class ResizeWindowCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.resizeWindow; - this.width = 0; - this.height = 0; - - this._assignFrom(obj, true); +export class ResizeWindowCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.resizeWindow); } _getAssignableProperties () { @@ -104,15 +84,9 @@ export class ResizeWindowCommand extends Assignable { } } -export class ResizeWindowToFitDeviceCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.resizeWindowToFitDevice; - this.device = null; - this.options = null; - - this._assignFrom(obj, true); +export class ResizeWindowToFitDeviceCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.resizeWindowToFitDevice); } _getAssignableProperties () { diff --git a/src/test-run/commands/from-object.js b/src/test-run/commands/from-object.js index 25d6bc30..7c005e8c 100644 --- a/src/test-run/commands/from-object.js +++ b/src/test-run/commands/from-object.js @@ -19,7 +19,8 @@ import { SwitchToMainWindowCommand, SetNativeDialogHandlerCommand, SetTestSpeedCommand, - SetPageLoadTimeoutCommand + SetPageLoadTimeoutCommand, + ExecuteExpressionCommand } from './actions'; import AssertionCommand from './assertion'; @@ -34,91 +35,100 @@ import { import { WaitCommand, DebugCommand } from './observation'; - -// Create command from object -export default function createCommandFromObject (obj) { - switch (obj.type) { +function getCmdCtor (type) { + switch (type) { case TYPE.click: - return new ClickCommand(obj); + return ClickCommand; case TYPE.rightClick: - return new RightClickCommand(obj); + return RightClickCommand; case TYPE.doubleClick: - return new DoubleClickCommand(obj); + return DoubleClickCommand; case TYPE.hover: - return new HoverCommand(obj); + return HoverCommand; case TYPE.drag: - return new DragCommand(obj); + return DragCommand; case TYPE.dragToElement: - return new DragToElementCommand(obj); + return DragToElementCommand; case TYPE.typeText: - return new TypeTextCommand(obj); + return TypeTextCommand; case TYPE.selectText: - return new SelectTextCommand(obj); + return SelectTextCommand; case TYPE.selectTextAreaContent: - return new SelectTextAreaContentCommand(obj); + return SelectTextAreaContentCommand; case TYPE.selectEditableContent: - return new SelectEditableContentCommand(obj); + return SelectEditableContentCommand; case TYPE.pressKey: - return new PressKeyCommand(obj); + return PressKeyCommand; case TYPE.wait: - return new WaitCommand(obj); + return WaitCommand; case TYPE.navigateTo: - return new NavigateToCommand(obj); + return NavigateToCommand; case TYPE.setFilesToUpload: - return new SetFilesToUploadCommand(obj); + return SetFilesToUploadCommand; case TYPE.clearUpload: - return new ClearUploadCommand(obj); + return ClearUploadCommand; case TYPE.takeScreenshot: - return new TakeScreenshotCommand(obj); + return TakeScreenshotCommand; case TYPE.takeElementScreenshot: - return new TakeElementScreenshotCommand(obj); + return TakeElementScreenshotCommand; case TYPE.resizeWindow: - return new ResizeWindowCommand(obj); + return ResizeWindowCommand; case TYPE.resizeWindowToFitDevice: - return new ResizeWindowToFitDeviceCommand(obj); + return ResizeWindowToFitDeviceCommand; case TYPE.maximizeWindow: - return new MaximizeWindowCommand(obj); + return MaximizeWindowCommand; case TYPE.switchToIframe: - return new SwitchToIframeCommand(obj); + return SwitchToIframeCommand; case TYPE.switchToMainWindow: - return new SwitchToMainWindowCommand(); + return SwitchToMainWindowCommand; case TYPE.setNativeDialogHandler: - return new SetNativeDialogHandlerCommand(obj); + return SetNativeDialogHandlerCommand; case TYPE.setTestSpeed: - return new SetTestSpeedCommand(obj); + return SetTestSpeedCommand; case TYPE.setPageLoadTimeout: - return new SetPageLoadTimeoutCommand(obj); + return SetPageLoadTimeoutCommand; case TYPE.assertion: - return new AssertionCommand(obj); + return AssertionCommand; case TYPE.debug: - return new DebugCommand(obj); + return DebugCommand; + + case TYPE.executeExpression: + return ExecuteExpressionCommand; + + default: + return null; } +} + +// Create command from object +export default function createCommandFromObject (obj, testRun) { + const CmdCtor = getCmdCtor(obj.type); - return null; + return CmdCtor && new CmdCtor(obj, testRun); } diff --git a/src/test-run/commands/observation.js b/src/test-run/commands/observation.js index 484f234a..ea7f469d 100644 --- a/src/test-run/commands/observation.js +++ b/src/test-run/commands/observation.js @@ -1,15 +1,11 @@ import TYPE from './type'; -import Assignable from '../../utils/assignable'; +import CommandBase from './base'; import { positiveIntegerArgument } from './validations/argument'; // Commands -export class WaitCommand extends Assignable { - constructor (obj) { - super(obj); - - this.type = TYPE.wait; - this.timeout = null; - this._assignFrom(obj, true); +export class WaitCommand extends CommandBase { + constructor (obj, testRun) { + super(obj, testRun, TYPE.wait); } _getAssignableProperties () { @@ -19,52 +15,37 @@ export class WaitCommand extends Assignable { } } -class ExecuteClientFunctionCommandBase extends Assignable { - constructor (type, obj) { - super(); - - this.type = type; - - this.instantiationCallsiteName = ''; - this.fnCode = ''; - this.args = []; - this.dependencies = []; - - this._assignFrom(obj, false); +class ExecuteClientFunctionCommandBase extends CommandBase { + constructor (obj, testRun, type) { + super(obj, testRun, type, false); } _getAssignableProperties () { return [ - { name: 'instantiationCallsiteName' }, - { name: 'fnCode' }, - { name: 'args' }, - { name: 'dependencies' } + { name: 'instantiationCallsiteName', defaultValue: '' }, + { name: 'fnCode', defaultValue: '' }, + { name: 'args', defaultValue: [] }, + { name: 'dependencies', defaultValue: [] } ]; } } export class ExecuteClientFunctionCommand extends ExecuteClientFunctionCommandBase { - constructor (obj) { - super(TYPE.executeClientFunction, obj); + constructor (obj, testRun) { + super(obj, testRun, TYPE.executeClientFunction); } } export class ExecuteSelectorCommand extends ExecuteClientFunctionCommandBase { - constructor (obj) { - super(TYPE.executeSelector); - - this.visibilityCheck = false; - this.timeout = null; - this.index = 0; - - this._assignFrom(obj, false); + constructor (obj, testRun) { + super(obj, testRun, TYPE.executeSelector); } _getAssignableProperties () { return super._getAssignableProperties().concat([ - { name: 'visibilityCheck' }, - { name: 'timeout' }, - { name: 'index' } + { name: 'visibilityCheck', defaultValue: false }, + { name: 'timeout', defaultValue: null }, + { name: 'index', defaultValue: 0 } ]); } } diff --git a/src/test-run/commands/type.js b/src/test-run/commands/type.js index edfa6119..1b371c72 100644 --- a/src/test-run/commands/type.js +++ b/src/test-run/commands/type.js @@ -43,4 +43,5 @@ export default { useRole: 'useRole', testDone: 'test-done', backupStorages: 'backup-storages', + executeExpression: 'execute-expression' }; diff --git a/src/test-run/commands/validations/initializers.js b/src/test-run/commands/validations/initializers.js index 453ad772..1c791474 100644 --- a/src/test-run/commands/validations/initializers.js +++ b/src/test-run/commands/validations/initializers.js @@ -5,14 +5,19 @@ import { ExecuteSelectorCommand } from '../observation'; import { executeJsExpression } from '../../execute-js-expression'; import { isJSExpression } from '../utils'; +export function initUploadSelector (name, val, initOptions) { + initOptions.skipVisibilityCheck = true; -export function initSelector (name, val, skipVisibilityCheck) { + return initSelector(name, val, initOptions); +} + +export function initSelector (name, val, { skipVisibilityCheck, testRun }) { if (val instanceof ExecuteSelectorCommand) return val; try { if (isJSExpression(val)) - val = executeJsExpression(val.value, skipVisibilityCheck); + val = executeJsExpression(val.value, testRun, skipVisibilityCheck); var builder = new SelectorBuilder(val, { visibilityCheck: !skipVisibilityCheck }, { instantiation: 'Selector' }); diff --git a/src/test-run/execute-js-expression.js b/src/test-run/execute-js-expression.js index 45c944db..a86d03fa 100644 --- a/src/test-run/execute-js-expression.js +++ b/src/test-run/execute-js-expression.js @@ -2,13 +2,37 @@ import { createContext, runInContext } from 'vm'; import SelectorBuilder from '../client-functions/selectors/selector-builder'; import ClientFunctionBuilder from '../client-functions/client-function-builder'; -export function executeJsExpression (expression, skipVisibilityCheck, testRun) { +var contextsInfo = []; + +function getContextInfo (testRun) { + var contextInfo = contextsInfo.find(info => info.testRun === testRun); + + if (!contextInfo) { + contextInfo = { testRun, context: createExecutionContext(testRun), options: {} }; + + contextsInfo.push(contextInfo); + } + + return contextInfo; +} + +function getContext (testRun, options = {}) { + var contextInfo = getContextInfo(testRun); + + contextInfo.options = options; + + return contextInfo.context; +} + +function createExecutionContext (testRun) { var sandbox = { Selector: (fn, options = {}) => { + var skipVisibilityCheck = getContextInfo(testRun).options.skipVisibilityCheck; + if (skipVisibilityCheck) options.visibilityCheck = false; - if (testRun) + if (testRun && testRun.id) options.boundTestRun = testRun; var builder = new SelectorBuilder(fn, options, { instantiation: 'Selector' }); @@ -17,7 +41,7 @@ export function executeJsExpression (expression, skipVisibilityCheck, testRun) { }, ClientFunction: (fn, options = {}) => { - if (testRun) + if (testRun && testRun.id) options.boundTestRun = testRun; var builder = new ClientFunctionBuilder(fn, options, { instantiation: 'ClientFunction' }); @@ -26,7 +50,11 @@ export function executeJsExpression (expression, skipVisibilityCheck, testRun) { } }; - var context = createContext(sandbox); + return createContext(sandbox); +} + +export function executeJsExpression (expression, testRun, skipVisibilityCheck) { + const context = getContext(testRun, { skipVisibilityCheck }); return runInContext(expression, context, { displayErrors: false }); } diff --git a/src/test-run/index.js b/src/test-run/index.js index 73bed7ea..5bf33fb3 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -293,7 +293,7 @@ export default class TestRun extends EventEmitter { _evaluate (code) { try { - return executeJsExpression(code, false, this); + return executeJsExpression(code, this, false); } catch (err) { return { err }; @@ -457,6 +457,23 @@ export default class TestRun extends EventEmitter { command.type !== COMMAND_TYPE.debug && command.type !== COMMAND_TYPE.useRole && command.type !== COMMAND_TYPE.assertion; } + async _executeExpression (command) { + var { expression, resultVariableName, isAsyncExpression } = command; + + if (isAsyncExpression) + expression = `await ${expression}`; + + if (resultVariableName) + expression = `${resultVariableName} = ${expression}, ${resultVariableName}`; + + if (isAsyncExpression) + expression = `(async () => { return ${expression}; }).apply(this);`; + + var result = this._evaluate(expression); + + return isAsyncExpression ? await result : result; + } + async _executeAssertion (command, callsite) { var assertionTimeout = command.options.timeout === void 0 ? this.opts.assertionTimeout : command.options.timeout; var executor = new AssertionExecutor(command, assertionTimeout, callsite); @@ -539,6 +556,9 @@ export default class TestRun extends EventEmitter { if (command.type === COMMAND_TYPE.assertion) return this._executeAssertion(command, callsite); + if (command.type === COMMAND_TYPE.executeExpression) + return await this._executeExpression(command, callsite); + if (command.type === COMMAND_TYPE.getBrowserConsoleMessages) return await this._enqueueBrowserConsoleMessagesCommand(command, callsite); diff --git a/src/utils/assignable.js b/src/utils/assignable.js index c3fc9883..7e5f6110 100644 --- a/src/utils/assignable.js +++ b/src/utils/assignable.js @@ -8,14 +8,14 @@ export default class Assignable { throw new Error('Not implemented'); } - _assignFrom (obj, validate) { + _assignFrom (obj, validate, initOptions = {}) { if (!obj) return; var props = this._getAssignableProperties(); for (var i = 0; i < props.length; i++) { - var { name, type, required, init } = props[i]; + var { name, type, required, init, defaultValue } = props[i]; var path = name.split('.'); var lastIdx = path.length - 1; @@ -28,6 +28,9 @@ export default class Assignable { destObj = destObj[path[j]]; } + if (destObj && 'defaultValue' in props[i]) + destObj[name] = defaultValue; + if (srcObj && destObj) { var srcVal = srcObj[last]; @@ -35,7 +38,7 @@ export default class Assignable { if (validate && type) type(name, srcVal); - destObj[last] = init ? init(name, srcVal) : srcVal; + destObj[last] = init ? init(name, srcVal, initOptions) : srcVal; } } } diff --git a/test/functional/fixtures/api/raw/execute-expression/pages/index.html b/test/functional/fixtures/api/raw/execute-expression/pages/index.html new file mode 100644 index 00000000..f640b380 --- /dev/null +++ b/test/functional/fixtures/api/raw/execute-expression/pages/index.html @@ -0,0 +1,8 @@ + + + + Execute expression + + + + diff --git a/test/functional/fixtures/api/raw/execute-expression/test.js b/test/functional/fixtures/api/raw/execute-expression/test.js new file mode 100644 index 00000000..cc1e8aa4 --- /dev/null +++ b/test/functional/fixtures/api/raw/execute-expression/test.js @@ -0,0 +1,17 @@ +describe('[Raw API] Execute expression action', function () { + it('Should execute async expressions', function () { + return runTests('./testcafe-fixtures/shared-context.testcafe', 'Execute async expression'); + }); + + it('Should execute simple sync expressions', function () { + return runTests('./testcafe-fixtures/shared-context.testcafe', 'Execute sync expression and save to a variable'); + }); + + it('Should share global variables between different command calls', function () { + return runTests('./testcafe-fixtures/shared-context.testcafe', 'Share variables between commands'); + }); + + it('Should store async property value to a variable', function () { + return runTests('./testcafe-fixtures/shared-context.testcafe', 'Store execution result to a variable'); + }); +}); diff --git a/test/functional/fixtures/api/raw/execute-expression/testcafe-fixtures/shared-context.testcafe b/test/functional/fixtures/api/raw/execute-expression/testcafe-fixtures/shared-context.testcafe new file mode 100644 index 00000000..58206f7b --- /dev/null +++ b/test/functional/fixtures/api/raw/execute-expression/testcafe-fixtures/shared-context.testcafe @@ -0,0 +1,90 @@ +{ + "fixtures": [ + { + "name": "RAW API Shared context", + "pageUrl": "http://localhost:3000/fixtures/api/raw/execute-expression/pages/index.html", + "tests": [ + { + "name": "Execute async expression", + "commands": [ + { + "type": "execute-expression", + "expression": "ClientFunction(() => window.testData = 'test')()", + "isAsyncExpression": true + }, + { + "type": "assertion", + "assertionType": "eql", + "actual": { "type" : "js-expr", "value" : "ClientFunction(() => window.testData)()" }, + "expected": "test" + } + ] + }, + { + "name": "Execute sync expression and save to a variable", + "commands": [ + { + "type": "execute-expression", + "expression": "Selector('body').count", + "resultVariableName": "bodyCount" + }, + { + "type": "assertion", + "assertionType": "eql", + "actual": { "type" : "js-expr", "value" : "bodyCount" }, + "expected": 1 + } + ] + }, + { + "name": "Share variables between commands", + "commands": [ + { + "type": "execute-expression", + "expression": "shared = 'initial value';" + }, + { + "type": "execute-expression", + "expression": "ClientFunction(new Function('window.testData =\"' + shared + '\"'))()", + "isAsyncExpression": true + }, + { + "type": "assertion", + "assertionType": "eql", + "actual": { "type" : "js-expr", "value" : "ClientFunction(() => window.testData)()" }, + "expected": "initial value" + }, + { + "type": "assertion", + "assertionType": "eql", + "actual": { "type" : "js-expr", "value" : "shared" }, + "expected": "initial value" + } + ] + }, + { + "name": "Store execution result to a variable", + "commands": [ + { + "type": "execute-expression", + "expression": "Selector('body').count", + "isAsyncExpression": true, + "resultVariableName": "bodyCount" + }, + { + "type": "execute-expression", + "expression": "1+1", + "resultVariableName": "simpleValue" + }, + { + "type": "assertion", + "assertionType": "eql", + "actual": { "type" : "js-expr", "value" : "simpleValue + bodyCount" }, + "expected": 3 + } + ] + } + ] + } + ] +} diff --git a/test/server/data/expected-test-run-errors/action-boolean-argument-error b/test/server/data/expected-test-run-errors/action-boolean-argument-error new file mode 100644 index 00000000..e5689f6d --- /dev/null +++ b/test/server/data/expected-test-run-errors/action-boolean-argument-error @@ -0,0 +1,20 @@ +The "isAsyncExpression" argument is expected to be a boolean value, but it +was object. + +Browser: Chrome 15.0.874 / Mac OS X 10.8.1 +Screenshot: /unix/path/with/ + + 18 |function func1 () { + 19 | record = createCallsiteRecord({ byFunctionName: 'func1' }); + 20 |} + 21 | + 22 |(function func2 () { + > 23 | func1(); + 24 |})(); + 25 | + 26 |stackTrace.filter.deattach(stackFilter); + 27 | + 28 |module.exports = record; + + at func2 (testfile.js:23:5) + at Object. (testfile.js:24:3) diff --git a/test/server/test-run-commands-test.js b/test/server/test-run-commands-test.js index 1f3326be..ce34c7d2 100644 --- a/test/server/test-run-commands-test.js +++ b/test/server/test-run-commands-test.js @@ -1,9 +1,13 @@ -var expect = require('chai').expect; -var TYPE = require('../../lib/test-run/commands/type'); -var createCommand = require('../../lib/test-run/commands/from-object'); -var ERROR_TYPE = require('../../lib/errors/test-run/type'); -var SelectorBuilder = require('../../lib/client-functions/selectors/selector-builder'); -var assertThrow = require('./helpers/assert-error').assertThrow; +var expect = require('chai').expect; +var TYPE = require('../../lib/test-run/commands/type'); +var createCommandFromObject = require('../../lib/test-run/commands/from-object'); +var ERROR_TYPE = require('../../lib/errors/test-run/type'); +var SelectorBuilder = require('../../lib/client-functions/selectors/selector-builder'); +var assertThrow = require('./helpers/assert-error').assertThrow; + +function createCommand (obj) { + return createCommandFromObject(obj, {}); +} function assertErrorMessage (fn, expectedErrMessage) { var actualErr = null; @@ -1063,6 +1067,41 @@ describe('Test run commands', function () { }); }); + it('Should create ExecuteExpressionCommand from object', function () { + var commandObj = { + type: TYPE.executeExpression, + + expression: 'js-expression', + isAsyncExpression: true, + resultVariableName: 'variable' + }; + + var command = createCommand(commandObj); + + expect(JSON.parse(JSON.stringify(command))).eql({ + type: TYPE.executeExpression, + + expression: 'js-expression', + isAsyncExpression: true, + resultVariableName: 'variable' + }); + + commandObj = { + type: TYPE.executeExpression, + expression: 'js-expression' + }; + + command = createCommand(commandObj); + + expect(JSON.parse(JSON.stringify(command))).eql({ + type: TYPE.executeExpression, + + expression: 'js-expression', + isAsyncExpression: false, + resultVariableName: null + }); + }); + it('Should process js expression as a Selector', function () { var commandObj = { type: TYPE.click, @@ -2803,6 +2842,92 @@ describe('Test run commands', function () { ); }); + it('Should validate ExecuteExpressionСommand', function () { + assertThrow( + function () { + return createCommand({ + type: TYPE.executeExpression + }); + }, + { + isTestCafeError: true, + type: ERROR_TYPE.actionStringArgumentError, + argumentName: 'expression', + actualValue: 'undefined', + callsite: null + } + ); + + assertThrow( + function () { + return createCommand({ + type: TYPE.executeExpression, + expression: 123 + }); + }, + { + isTestCafeError: true, + type: ERROR_TYPE.actionStringArgumentError, + argumentName: 'expression', + actualValue: 'number', + callsite: null + } + ); + + assertThrow( + function () { + return createCommand({ + type: TYPE.executeExpression, + expression: 'js-expression', + isAsyncExpression: 123 + }); + }, + { + isTestCafeError: true, + type: ERROR_TYPE.actionBooleanArgumentError, + actualValue: 'number', + argumentName: 'isAsyncExpression', + callsite: null + } + ); + + assertThrow( + function () { + return createCommand({ + type: TYPE.executeExpression, + expression: 'js-expression', + isAsyncExpression: true, + resultVariableName: 123 + }); + }, + { + isTestCafeError: true, + type: ERROR_TYPE.actionStringArgumentError, + argumentName: 'resultVariableName', + actualValue: 'number', + callsite: null + } + ); + + assertThrow( + function () { + return createCommand({ + type: TYPE.executeExpression, + expression: 'js-expression', + isAsyncExpression: true, + resultVariableName: '' + }); + }, + { + isTestCafeError: true, + type: ERROR_TYPE.actionStringArgumentError, + argumentName: 'resultVariableName', + actualValue: '""', + callsite: null + } + ); + }); + it('Should validate js expression as Selector', function () { assertThrow( function () { diff --git a/test/server/test-run-error-formatting-test.js b/test/server/test-run-error-formatting-test.js index 49aea84b..02525707 100644 --- a/test/server/test-run-error-formatting-test.js +++ b/test/server/test-run-error-formatting-test.js @@ -14,6 +14,7 @@ var ActionPositiveIntegerOptionError = require('../../lib/error var ActionIntegerArgumentError = require('../../lib/errors/test-run').ActionIntegerArgumentError; var ActionPositiveIntegerArgumentError = require('../../lib/errors/test-run').ActionPositiveIntegerArgumentError; var ActionBooleanOptionError = require('../../lib/errors/test-run').ActionBooleanOptionError; +var ActionBooleanArgumentError = require('../../lib/errors/test-run').ActionBooleanArgumentError; var ActionSpeedOptionError = require('../../lib/errors/test-run').ActionSpeedOptionError; var ActionSelectorError = require('../../lib/errors/test-run').ActionSelectorError; var ActionOptionsTypeError = require('../../lib/errors/test-run').ActionOptionsTypeError; @@ -144,6 +145,10 @@ describe('Error formatting', function () { assertErrorMessage('action-boolean-option-error', new ActionBooleanOptionError('modifier.ctrl', 'object')); }); + it('Should format "actionBooleanArgumentError" message', function () { + assertErrorMessage('action-boolean-argument-error', new ActionBooleanArgumentError('isAsyncExpression', 'object')); + }); + it('Should format "actionSpeedOptionError" message', function () { assertErrorMessage('action-speed-option-error', new ActionSpeedOptionError('speed', 'object')); }); From 45e884f82711535f9ad046deb966a72b69d5ea95 Mon Sep 17 00:00:00 2001 From: Vladimir Airikh Date: Tue, 7 Aug 2018 16:33:55 +0300 Subject: [PATCH 045/184] fix `Update babel-preset-env target to node 6` (#2695) --- src/.babelrc | 5 ++++- src/api/exportable-lib/index.js | 25 ++++++++++++++----------- src/errors/stack-cleaning-hook.js | 2 ++ src/utils/delegated-api.js | 2 +- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/.babelrc b/src/.babelrc index 9310dde9..a7d3d6c9 100644 --- a/src/.babelrc +++ b/src/.babelrc @@ -1,7 +1,10 @@ { "compact": false, "presets": [ - ["env", { "loose": true }], + ["env", { + "targets": { "node": "6" }, + "loose": true + }], "babel-preset-stage-2" ], "plugins": [ diff --git a/src/api/exportable-lib/index.js b/src/api/exportable-lib/index.js index b3d67ea4..f69e433f 100644 --- a/src/api/exportable-lib/index.js +++ b/src/api/exportable-lib/index.js @@ -18,22 +18,26 @@ function RequestLogger (requestFilterRuleInit, logOptions) { return createRequestLogger(requestFilterRuleInit, logOptions); } +function ClientFunction (fn, options) { + const builder = new ClientFunctionBuilder(fn, options, { instantiation: 'ClientFunction' }); + + return builder.getFunction(); +} + +function Selector (fn, options) { + const builder = new SelectorBuilder(fn, options, { instantiation: 'Selector' }); + + return builder.getFunction(); +} + Role.anonymous = createAnonymousRole; export default { Role, - ClientFunction (fn, options) { - var builder = new ClientFunctionBuilder(fn, options, { instantiation: 'ClientFunction' }); - - return builder.getFunction(); - }, + ClientFunction, - Selector (fn, options) { - var builder = new SelectorBuilder(fn, options, { instantiation: 'Selector' }); - - return builder.getFunction(); - }, + Selector, RequestLogger, @@ -43,4 +47,3 @@ export default { t: testControllerProxy }; - diff --git a/src/errors/stack-cleaning-hook.js b/src/errors/stack-cleaning-hook.js index 0588f81b..6b11c562 100644 --- a/src/errors/stack-cleaning-hook.js +++ b/src/errors/stack-cleaning-hook.js @@ -5,6 +5,7 @@ import createStackFilter from './create-stack-filter'; const ORIGINAL_STACK_TRACE_LIMIT = Error.stackTraceLimit; const STACK_TRACE_LIMIT = 200; const TOP_ANONYMOUS_FRAME_RE = /\s+at\s$/; +const GENERATOR_NEXT_FRAME_RE = /\s+at\sgenerator.next\s\(\)$/im; export default { @@ -43,6 +44,7 @@ export default { cleanError (error) { error.stack = error.stack.replace(TOP_ANONYMOUS_FRAME_RE, ''); + error.stack = error.stack.replace(GENERATOR_NEXT_FRAME_RE, ''); let frames = this._getFrames(error); diff --git a/src/utils/delegated-api.js b/src/utils/delegated-api.js index 0688475d..764217c4 100644 --- a/src/utils/delegated-api.js +++ b/src/utils/delegated-api.js @@ -2,7 +2,7 @@ const API_IMPLEMENTATION_METHOD_RE = /^_(\S+)\$(getter|setter)?$/; export function getDelegatedAPIList (src) { return Object - .keys(src) + .getOwnPropertyNames(src) .map(prop => { var match = prop.match(API_IMPLEMENTATION_METHOD_RE); From 7dd6e5441acfdcde58159966cd4e2d16e0deb6ce Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Tue, 7 Aug 2018 16:35:20 +0300 Subject: [PATCH 046/184] fix 'Should not raise an error if during a long running request the "clear" method will be called' (close #2688) (#2694) --- src/api/request-hooks/request-logger.js | 4 +++- test/server/request-hooks-test.js | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/api/request-hooks/request-logger.js b/src/api/request-hooks/request-logger.js index 324e7d73..f08c55dd 100644 --- a/src/api/request-hooks/request-logger.js +++ b/src/api/request-hooks/request-logger.js @@ -62,8 +62,10 @@ class RequestLoggerImplementation extends RequestHook { onResponse (event) { const loggerReq = this._internalRequests[event.requestId]; + // NOTE: If the 'clear' method is called during a long running request, + // we should not save a response part - request part has been already removed. if (!loggerReq) - throw new TypeError(`Cannot find a recorded request with id=${event.id}. This is an internal TestCafe problem. Please contact the TestCafe team and provide an example to reproduce the problem.`); + return; loggerReq.response = {}; loggerReq.response.statusCode = event.statusCode; diff --git a/test/server/request-hooks-test.js b/test/server/request-hooks-test.js index da940298..513c9c8a 100644 --- a/test/server/request-hooks-test.js +++ b/test/server/request-hooks-test.js @@ -174,6 +174,16 @@ describe('RequestLogger', () => { expect(data[2]).eql(false); }); }); + + it('Should not raise an error if during a long running request the ".clear" method will be called (GH-2688)', () => { + const logger = new RequestLogger(); + + logger.onRequest(requestEventMock); + logger.clear(); + logger.onResponse(responseEventMock); + + expect(logger.requests.length).eql(0); + }); }); describe('RequestMock', () => { From 024d23bd6bc9e92d84a557d92e3e8ad0898b4d06 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Wed, 8 Aug 2018 10:07:04 +0300 Subject: [PATCH 047/184] modify scrolling behavior is target is hidden by fixed (closes #2450) (#2673) * modify scrolling behavior is target is hidden by fixed (closes #2450) * minor changes after review * fix review * fix round issues --- src/client/automation/playback/scroll.js | 163 ++++++++++-------- .../fixtures/regression/gh-2450/index.js | 5 + .../regression/gh-2450/pages/index.html | 61 +++++++ .../gh-2450/testcafe-fixtures/index.js | 33 ++++ 4 files changed, 191 insertions(+), 71 deletions(-) create mode 100644 test/functional/fixtures/regression/gh-2450/index.js create mode 100644 test/functional/fixtures/regression/gh-2450/pages/index.html create mode 100644 test/functional/fixtures/regression/gh-2450/testcafe-fixtures/index.js diff --git a/src/client/automation/playback/scroll.js b/src/client/automation/playback/scroll.js index f7e6e243..646206fb 100644 --- a/src/client/automation/playback/scroll.js +++ b/src/client/automation/playback/scroll.js @@ -2,9 +2,8 @@ import hammerhead from '../deps/hammerhead'; import { domUtils, styleUtils, positionUtils, promiseUtils, scrollController, sendRequestToFrame } from '../deps/testcafe-core'; -var Promise = hammerhead.Promise; -var messageSandbox = hammerhead.eventSandbox.message; - +const Promise = hammerhead.Promise; +const messageSandbox = hammerhead.eventSandbox.message; const DEFAULT_MAX_SCROLL_MARGIN = 50; const SCROLL_MARGIN_INCREASE_STEP = 20; @@ -16,12 +15,9 @@ const SCROLL_RESPONSE_CMD = 'automation|scroll|response'; // Setup cross-iframe interaction messageSandbox.on(messageSandbox.SERVICE_MSG_RECEIVED_EVENT, e => { if (e.message.cmd === SCROLL_REQUEST_CMD) { - var element = domUtils.findIframeByWindow(e.source); - var offsetX = e.message.offsetX; - var offsetY = e.message.offsetY; - var maxScrollMargin = e.message.maxScrollMargin; - - var scroll = new ScrollAutomation(element, { offsetX, offsetY }); + const { offsetX, offsetY, maxScrollMargin } = e.message; + const element = domUtils.findIframeByWindow(e.source); + const scroll = new ScrollAutomation(element, { offsetX, offsetY }); scroll.maxScrollMargin = maxScrollMargin; @@ -39,7 +35,7 @@ export default class ScrollAutomation { this.scrollToCenter = scrollOptions.scrollToCenter; this.skipParentFrames = scrollOptions.skipParentFrames; - this.maxScrollMargin = DEFAULT_MAX_SCROLL_MARGIN; + this.maxScrollMargin = { left: DEFAULT_MAX_SCROLL_MARGIN, top: DEFAULT_MAX_SCROLL_MARGIN }; } _isScrollValuesChanged (scrollElement, originalScroll) { @@ -48,9 +44,9 @@ export default class ScrollAutomation { } _setScroll (element, { left, top }) { - var scrollElement = domUtils.isHtmlElement(element) ? domUtils.findDocument(element) : element; + const scrollElement = domUtils.isHtmlElement(element) ? domUtils.findDocument(element) : element; - var originalScroll = { + const originalScroll = { left: styleUtils.getScrollLeft(scrollElement), top: styleUtils.getScrollTop(scrollElement) }; @@ -58,7 +54,7 @@ export default class ScrollAutomation { left = Math.max(left, 0); top = Math.max(top, 0); - var scrollPromise = scrollController.waitForScroll(); + const scrollPromise = scrollController.waitForScroll(); styleUtils.setScrollLeft(scrollElement, left); styleUtils.setScrollTop(scrollElement, top); @@ -73,19 +69,19 @@ export default class ScrollAutomation { } _getScrollToPoint (elementDimensions, { x, y }) { - var horizontalCenter = Math.floor(elementDimensions.width / 2); - var verticalCenter = Math.floor(Math.floor(elementDimensions.height / 2)); - var leftScrollMargin = this.scrollToCenter ? horizontalCenter : Math.min(this.maxScrollMargin, horizontalCenter); - var topScrollMargin = this.scrollToCenter ? verticalCenter : Math.min(this.maxScrollMargin, verticalCenter); + const horizontalCenter = Math.floor(elementDimensions.width / 2); + const verticalCenter = Math.floor(Math.floor(elementDimensions.height / 2)); + const leftScrollMargin = this.scrollToCenter ? horizontalCenter : Math.min(this.maxScrollMargin.left, horizontalCenter); + const topScrollMargin = this.scrollToCenter ? verticalCenter : Math.min(this.maxScrollMargin.top, verticalCenter); - var needForwardScrollLeft = x >= elementDimensions.scroll.left + elementDimensions.width - leftScrollMargin; - var needBackwardScrollLeft = x <= elementDimensions.scroll.left + leftScrollMargin; + const needForwardScrollLeft = x >= elementDimensions.scroll.left + elementDimensions.width - leftScrollMargin; + const needBackwardScrollLeft = x <= elementDimensions.scroll.left + leftScrollMargin; - var needForwardScrollTop = y >= elementDimensions.scroll.top + elementDimensions.height - topScrollMargin; - var needBackwardScrollTop = y <= elementDimensions.scroll.top + topScrollMargin; + const needForwardScrollTop = y >= elementDimensions.scroll.top + elementDimensions.height - topScrollMargin; + const needBackwardScrollTop = y <= elementDimensions.scroll.top + topScrollMargin; - var left = elementDimensions.scroll.left; - var top = elementDimensions.scroll.top; + let left = elementDimensions.scroll.left; + let top = elementDimensions.scroll.top; if (needForwardScrollLeft) left = x - elementDimensions.width + leftScrollMargin; @@ -101,17 +97,20 @@ export default class ScrollAutomation { } _getScrollToFullChildView (parentDimensions, childDimensions) { - var fullViewScrollLeft = null; - var fullViewScrollTop = null; + let fullViewScrollLeft = null; + let fullViewScrollTop = null; - var canShowFullElementWidth = parentDimensions.width >= childDimensions.width; - var canShowFullElementHeight = parentDimensions.height >= childDimensions.height; + const canShowFullElementWidth = parentDimensions.width >= childDimensions.width; + const canShowFullElementHeight = parentDimensions.height >= childDimensions.height; - var relativePosition = positionUtils.calcRelativePosition(childDimensions, parentDimensions); + const relativePosition = positionUtils.calcRelativePosition(childDimensions, parentDimensions); if (canShowFullElementWidth) { - var availableLeftScrollMargin = Math.floor((parentDimensions.width - childDimensions.width) / 2); - var leftScrollMargin = this.scrollToCenter ? availableLeftScrollMargin : Math.min(this.maxScrollMargin, availableLeftScrollMargin); + const availableLeftScrollMargin = parentDimensions.width - childDimensions.width; + let leftScrollMargin = Math.min(this.maxScrollMargin.left, availableLeftScrollMargin); + + if (this.scrollToCenter) + leftScrollMargin = availableLeftScrollMargin / 2; if (relativePosition.left < leftScrollMargin) { fullViewScrollLeft = Math.round(parentDimensions.scroll.left + relativePosition.left - @@ -125,8 +124,11 @@ export default class ScrollAutomation { } if (canShowFullElementHeight) { - var availableTopScrollMargin = Math.floor((parentDimensions.height - childDimensions.height) / 2); - var topScrollMargin = this.scrollToCenter ? availableTopScrollMargin : Math.min(this.maxScrollMargin, availableTopScrollMargin); + const availableTopScrollMargin = parentDimensions.height - childDimensions.height; + let topScrollMargin = Math.min(this.maxScrollMargin.top, availableTopScrollMargin); + + if (this.scrollToCenter) + topScrollMargin = availableTopScrollMargin / 2; if (relativePosition.top < topScrollMargin) fullViewScrollTop = Math.round(parentDimensions.scroll.top + relativePosition.top - topScrollMargin); @@ -143,32 +145,66 @@ export default class ScrollAutomation { }; } - _scrollToChild (parent, child, { offsetX, offsetY }) { - var parentDimensions = positionUtils.getClientDimensions(parent); - var childDimensions = positionUtils.getClientDimensions(child); - - var childPoint = { + _getScrollPosition (parentDimensions, childDimensions, offsetX, offsetY) { + const childPoint = { x: childDimensions.left - parentDimensions.left + parentDimensions.scroll.left + childDimensions.border.left + offsetX, y: childDimensions.top - parentDimensions.top + parentDimensions.scroll.top + childDimensions.border.top + offsetY }; - var scrollToFullView = this._getScrollToFullChildView(parentDimensions, childDimensions); - var scrollToPoint = this._getScrollToPoint(parentDimensions, childPoint); + const scrollToPoint = this._getScrollToPoint(parentDimensions, childPoint); + const scrollToFullView = this._getScrollToFullChildView(parentDimensions, childDimensions); - var left = scrollToFullView.left === null ? scrollToPoint.left : scrollToFullView.left; - var top = scrollToFullView.top === null ? scrollToPoint.top : scrollToFullView.top; + const left = Math.max(scrollToFullView.left === null ? scrollToPoint.left : scrollToFullView.left, 0); + const top = Math.max(scrollToFullView.top === null ? scrollToPoint.top : scrollToFullView.top, 0); - return this._setScroll(parent, { left, top }); + return { left, top }; + } + + _getChildPointAfterScroll (parentDimensions, childDimensions, left, top) { + const x = Math.round(childDimensions.left + parentDimensions.scroll.left - left + childDimensions.width / 2); + const y = Math.round(childDimensions.top + parentDimensions.scroll.top - top + childDimensions.height / 2); + + return { x, y }; + } + + _scrollToChild (parent, child, { offsetX, offsetY }) { + const parentDimensions = positionUtils.getClientDimensions(parent); + const childDimensions = positionUtils.getClientDimensions(child); + const windowWidth = styleUtils.getInnerWidth(window); + const windowHeight = styleUtils.getInnerHeight(window); + let scrollPos = {}; + let needScroll = true; + + while (needScroll) { + scrollPos = this._getScrollPosition(parentDimensions, childDimensions, offsetX, offsetY); + + const { x, y } = this._getChildPointAfterScroll(parentDimensions, childDimensions, scrollPos.left, scrollPos.top); + const isTargetObscured = this._isTargetElementObscuredInPoint(x, y); + + this.maxScrollMargin.left += SCROLL_MARGIN_INCREASE_STEP; + + if (this.maxScrollMargin.left >= windowWidth) { + this.maxScrollMargin.left = DEFAULT_MAX_SCROLL_MARGIN; + + this.maxScrollMargin.top += SCROLL_MARGIN_INCREASE_STEP; + } + + needScroll = isTargetObscured && this.maxScrollMargin.top < windowHeight; + } + + this.maxScrollMargin = { left: DEFAULT_MAX_SCROLL_MARGIN, top: DEFAULT_MAX_SCROLL_MARGIN }; + + return this._setScroll(parent, scrollPos); } _scrollElement () { if (!styleUtils.hasScroll(this.element)) return Promise.resolve(); - var elementDimensions = positionUtils.getClientDimensions(this.element); - var scroll = this._getScrollToPoint(elementDimensions, { + const elementDimensions = positionUtils.getClientDimensions(this.element); + const scroll = this._getScrollToPoint(elementDimensions, { x: this.offsetX, y: this.offsetY }); @@ -177,16 +213,15 @@ export default class ScrollAutomation { } _scrollParents () { - var parents = styleUtils.getScrollableParents(this.element); - - var currentChild = this.element; - var currentOffsetX = this.offsetX - Math.round(styleUtils.getScrollLeft(currentChild)); - var currentOffsetY = this.offsetY - Math.round(styleUtils.getScrollTop(currentChild)); + const parents = styleUtils.getScrollableParents(this.element); - var childDimensions = null; - var parentDimensions = null; + let currentChild = this.element; + let currentOffsetX = this.offsetX - Math.round(styleUtils.getScrollLeft(currentChild)); + let currentOffsetY = this.offsetY - Math.round(styleUtils.getScrollTop(currentChild)); + let childDimensions = null; + let parentDimensions = null; - var scrollParentsPromise = promiseUtils.times(parents.length, i => { + const scrollParentsPromise = promiseUtils.times(parents.length, i => { return this ._scrollToChild(parents[i], currentChild, { offsetX: currentOffsetX, @@ -218,13 +253,10 @@ export default class ScrollAutomation { }); } - _isElementHiddenByFixed () { - var clientDimensions = positionUtils.getClientDimensions(this.element); - var elementInPoint = positionUtils.getElementFromPoint(clientDimensions.left + - this.offsetX, clientDimensions.top + this.offsetY); - - let el = elementInPoint; - let fixedElement = null; + _isTargetElementObscuredInPoint (x, y) { + const elementInPoint = positionUtils.getElementFromPoint(x, y); + let el = elementInPoint; + let fixedElement = null; while (el && !fixedElement) { if (styleUtils.isFixedElement(el)) @@ -236,20 +268,9 @@ export default class ScrollAutomation { return elementInPoint && fixedElement && !fixedElement.contains(this.element); } - _isScrollMarginTooBig () { - var minWindowDimension = Math.min(styleUtils.getInnerWidth(window), styleUtils.getInnerHeight(window)); - - return this.maxScrollMargin >= minWindowDimension / 2; - } - run () { return this ._scrollElement() - .then(() => this._scrollParents()) - .then(() => promiseUtils.whilst(() => !this._isScrollMarginTooBig() && this._isElementHiddenByFixed(), () => { - this.maxScrollMargin += SCROLL_MARGIN_INCREASE_STEP; - - return this._scrollParents(); - })); + .then(() => this._scrollParents()); } } diff --git a/test/functional/fixtures/regression/gh-2450/index.js b/test/functional/fixtures/regression/gh-2450/index.js new file mode 100644 index 00000000..d7de2c0e --- /dev/null +++ b/test/functional/fixtures/regression/gh-2450/index.js @@ -0,0 +1,5 @@ +describe('[Regression](GH-2450)', function () { + it('Should scroll to element which is hidden by fixed', function () { + return runTests('testcafe-fixtures/index.js'); + }); +}); diff --git a/test/functional/fixtures/regression/gh-2450/pages/index.html b/test/functional/fixtures/regression/gh-2450/pages/index.html new file mode 100644 index 00000000..a7eb71e4 --- /dev/null +++ b/test/functional/fixtures/regression/gh-2450/pages/index.html @@ -0,0 +1,61 @@ + + + + + Title + + + +
+ +
+
+
+
+ + + \ No newline at end of file diff --git a/test/functional/fixtures/regression/gh-2450/testcafe-fixtures/index.js b/test/functional/fixtures/regression/gh-2450/testcafe-fixtures/index.js new file mode 100644 index 00000000..d208663a --- /dev/null +++ b/test/functional/fixtures/regression/gh-2450/testcafe-fixtures/index.js @@ -0,0 +1,33 @@ +import { Selector, ClientFunction } from 'testcafe'; + +fixture `GH-2450 - Scroll to element which is hidden by fixed` + .page `http://localhost:3000/fixtures/regression/gh-2450/pages/index.html`; + +const button1 = Selector('#button1'); +const result = Selector('#result'); + +const doScroll = ClientFunction(() => { + window.scrollTo(5000, 5000); +}); + +const changeFixed = ClientFunction(() => { + var inversed = 'inversed'; + + document.getElementById('fixedTop').className = inversed; + document.getElementById('fixedLeft').className = inversed; +}); + +test('Scroll to right bottom corner', async t => { + await doScroll(); + await t + .click(button1) + .expect(result.innerText).eql('button1'); +}); + +test('Scroll to left upper corner', async t => { + await changeFixed(); + await t + .click(button1) + .expect(result.innerText).eql('button1'); +}); + From 76d13712b1f45b5204a65f8f9a611ac1a6302e5d Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Wed, 8 Aug 2018 15:53:01 +0300 Subject: [PATCH 048/184] Implemented glob pattern support for 'runner.src' method (close #980) (#2687) * Implemented glob pattern support for runner.src method * move real path calculation to Bootstrapper class * minor change * small refactoring --- src/cli/argument-parser.js | 65 +---------- src/runner/bootstrapper.js | 8 +- src/runner/index.js | 7 +- src/utils/parse-file-list.js | 52 +++++++++ test/server/cli-argument-parser-test.js | 51 +-------- test/server/runner-test.js | 146 ++++++++++++------------ test/server/util-test.js | 49 ++++++++ 7 files changed, 191 insertions(+), 187 deletions(-) create mode 100644 src/utils/parse-file-list.js diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index afcf451f..e2b4ce9e 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -1,22 +1,17 @@ -import { resolve, join as pathJoin, dirname } from 'path'; +import { resolve, dirname } from 'path'; import { Command } from 'commander'; import Promise from 'pinkie'; import dedent from 'dedent'; -import isGlob from 'is-glob'; -import globby from 'globby'; import { readSync as read } from 'read-file-relative'; import { GeneralError } from '../errors/runtime'; import MESSAGE from '../errors/runtime/message'; -import Compiler from '../compiler'; import { assertType, is } from '../errors/runtime/type-assertions'; import getViewPortWidth from '../utils/get-viewport-width'; import { wordWrap, splitQuotedText } from '../utils/string'; -import { stat, ensureDir } from '../utils/promisified-functions'; +import { ensureDir } from '../utils/promisified-functions'; import parseSslOptions from './parse-ssl-options'; -const REMOTE_ALIAS_RE = /^remote(?::(\d*))?$/; -const DEFAULT_TEST_LOOKUP_DIRS = ['test/', 'tests/']; -const TEST_FILE_GLOB_PATTERN = `./**/*@(${Compiler.getSupportedTestFileExtensions().join('|')})`; +const REMOTE_ALIAS_RE = /^remote(?::(\d*))?$/; const DESCRIPTION = dedent(` In the browser list, you can use browser names (e.g. "ie", "chrome", etc.) as well as paths to executables. @@ -48,10 +43,6 @@ export default class CLIArgumentParser { this._describeProgram(); } - static _isInteger (value) { - return !isNaN(value) && isFinite(value); - } - static _parsePortNumber (value) { assertType(is.nonNegativeNumberString, null, 'Port number', value); @@ -245,52 +236,8 @@ export default class CLIArgumentParser { } } - async _convertDirsToGlobs (fileList) { - fileList = await Promise.all(fileList.map(async file => { - if (!isGlob(file)) { - var absPath = resolve(this.cwd, file); - var fileStat = null; - - try { - fileStat = await stat(absPath); - } - catch (err) { - return null; - } - - if (fileStat.isDirectory()) - return pathJoin(file, TEST_FILE_GLOB_PATTERN); - } - - return file; - })); - - return fileList.filter(file => !!file); - } - - async _getDefaultDirs () { - return await globby(DEFAULT_TEST_LOOKUP_DIRS, { - cwd: this.cwd, - silent: true, - nocase: true - }); - } - - async _parseFileList () { - var fileList = this.program.args.slice(1); - - if (!fileList.length) - fileList = await this._getDefaultDirs(); - - fileList = await this._convertDirsToGlobs(fileList); - - this.src = await globby(fileList, { - cwd: this.cwd, - silent: true, - nodir: true - }); - - this.src = this.src.map(file => resolve(this.cwd, file)); + _parseFileList () { + this.src = this.program.args.slice(1); } async _parseScreenshotsPath () { @@ -327,10 +274,10 @@ export default class CLIArgumentParser { this._parseBrowserList(); this._parseConcurrency(); this._parseSslOptions(); + this._parseFileList(); await Promise.all([ this._parseScreenshotsPath(), - this._parseFileList(), this._parseReporters() ]); } diff --git a/src/runner/bootstrapper.js b/src/runner/bootstrapper.js index 12dfb87c..365c0779 100644 --- a/src/runner/bootstrapper.js +++ b/src/runner/bootstrapper.js @@ -7,6 +7,7 @@ import browserProviderPool from '../browser/provider/pool'; import MESSAGE from '../errors/runtime/message'; import BrowserSet from './browser-set'; import TestedApp from './tested-app'; +import parseFileList from '../utils/parse-file-list'; const DEFAULT_APP_INIT_DELAY = 1000; @@ -71,10 +72,11 @@ export default class Bootstrapper { if (!this.sources.length) throw new GeneralError(MESSAGE.testSourcesNotSet); - var compiler = new Compiler(this.sources); - var tests = await compiler.getTests(); + const parsedFileList = await parseFileList(this.sources, process.cwd()); + const compiler = new Compiler(parsedFileList); + let tests = await compiler.getTests(); - var testsWithOnlyFlag = tests.filter(test => test.only); + const testsWithOnlyFlag = tests.filter(test => test.only); if (testsWithOnlyFlag.length) tests = testsWithOnlyFlag; diff --git a/src/runner/index.js b/src/runner/index.js index b9c7f484..035b47ed 100644 --- a/src/runner/index.js +++ b/src/runner/index.js @@ -1,7 +1,6 @@ import Promise from 'pinkie'; import promisifyEvent from 'promisify-event'; import mapReverse from 'map-reverse'; -import { resolve as resolvePath } from 'path'; import { EventEmitter } from 'events'; import { flattenDeep as flatten, pull as remove } from 'lodash'; import Bootstrapper from './bootstrapper'; @@ -146,7 +145,6 @@ export default class Runner extends EventEmitter { } } - // API embeddingOptions (opts) { this._registerAssets(opts.assets); @@ -156,9 +154,7 @@ export default class Runner extends EventEmitter { } src (...sources) { - sources = flatten(sources).map(path => resolvePath(path)); - - this.bootstrapper.sources = this.bootstrapper.sources.concat(sources); + this.bootstrapper.sources = this.bootstrapper.sources.concat(flatten(sources)); return this; } @@ -227,6 +223,7 @@ export default class Runner extends EventEmitter { var runTaskPromise = Promise.resolve() .then(() => { this._validateRunOptions(); + return this.bootstrapper.createRunnableConfiguration(); }) .then(({ reporterPlugins, browserSet, tests, testedApp }) => { diff --git a/src/utils/parse-file-list.js b/src/utils/parse-file-list.js new file mode 100644 index 00000000..925d82ca --- /dev/null +++ b/src/utils/parse-file-list.js @@ -0,0 +1,52 @@ +import path from 'path'; +import Promise from 'pinkie'; +import globby from 'globby'; +import isGlob from 'is-glob'; +import Compiler from '../compiler'; +import { isEmpty } from 'lodash'; +import { stat } from '../utils/promisified-functions'; + +const DEFAULT_TEST_LOOKUP_DIRS = ['test/', 'tests/']; +const TEST_FILE_GLOB_PATTERN = `./**/*@(${Compiler.getSupportedTestFileExtensions().join('|')})`; + +async function getDefaultDirs (baseDir) { + return await globby(DEFAULT_TEST_LOOKUP_DIRS, { + cwd: baseDir, + nocase: true, + onlyDirectories: true, + onlyFiles: false + }); +} + +async function convertDirsToGlobs (fileList, baseDir) { + fileList = await Promise.all(fileList.map(async file => { + if (!isGlob(file)) { + const absPath = path.resolve(baseDir, file); + let fileStat = null; + + try { + fileStat = await stat(absPath); + } + catch (err) { + return null; + } + + if (fileStat.isDirectory()) + return path.join(file, TEST_FILE_GLOB_PATTERN); + } + + return file; + })); + + return fileList.filter(file => !!file); +} + +export default async function parseFileList (fileList, baseDir) { + if (isEmpty(fileList)) + fileList = await getDefaultDirs(baseDir); + + fileList = await convertDirsToGlobs(fileList, baseDir); + fileList = await globby(fileList, { cwd: baseDir }); + + return fileList.map(file => path.resolve(baseDir, file)); +} diff --git a/test/server/cli-argument-parser-test.js b/test/server/cli-argument-parser-test.js index 03d3dba4..76a69008 100644 --- a/test/server/cli-argument-parser-test.js +++ b/test/server/cli-argument-parser-test.js @@ -313,55 +313,6 @@ describe('CLI argument parser', function () { }); }); - it('Should accept globs and paths as source files', function () { - var cwd = process.cwd(); - - var expected = [ - 'test/server/data/file-list/file-1.js', - 'test/server/data/file-list/file-2.js', - 'test/server/data/file-list/dir1/dir1-1/file-1-1-1.js', - 'test/server/data/file-list/dir1/file-1-1.js', - 'test/server/data/file-list/dir1/file-1-2.js', - 'test/server/data/file-list/dir1/file-1-3.testcafe', - 'test/server/data/file-list/dir1/file-1-4.ts', - 'test/server/data/file-list/dir2/file-2-2.js', - 'test/server/data/file-list/dir2/file-2-3.js' - ]; - - expected = expected.map(function (file) { - return path.resolve(cwd, file); - }); - - return parse('chrome ' + - 'test/server/data/file-list/file-1.js ' + - path.join(cwd, 'test/server/data/file-list/file-2.js') + ' ' + - 'test/server/data/file-list/dir1 ' + - 'test/server/data/file-list/dir2/*.js ' + - '!test/server/data/file-list/dir2/file-2-1.js ' + - 'test/server/data/file-list/dir3') - .then(function (parser) { - expect(parser.src).eql(expected); - }); - }); - - it('Should use "test" and "tests" dirs if source files are not specified', function () { - var workingDir = path.join(__dirname, './data/file-list'); - - var expected = [ - 'test/test-dir-file.js', - 'tests/tests-dir-file.js' - ]; - - expected = expected.map(function (file) { - return path.resolve(workingDir, file); - }); - - return parse('chrome', workingDir) - .then(function (parser) { - expect(parser.src).eql(expected); - }); - }); - it('Should parse the screenshot path and ensure it exists', function () { var dir = path.join(tmp.dirSync().name, 'my/screenshots'); @@ -389,7 +340,7 @@ describe('CLI argument parser', function () { return parse('-r list -S -q -e --hostname myhost --proxy localhost:1234 --proxy-bypass localhost:5678 --qr-code --app run-app --speed 0.5 --debug-on-fail --disable-page-reloads --dev ie test/server/data/file-list/file-1.js') .then(function (parser) { expect(parser.browsers).eql(['ie']); - expect(parser.src).eql([path.resolve(process.cwd(), 'test/server/data/file-list/file-1.js')]); + expect(parser.src).eql(['test/server/data/file-list/file-1.js']); expect(parser.opts.reporters[0].name).eql('list'); expect(parser.opts.hostname).eql('myhost'); expect(parser.opts.app).eql('run-app'); diff --git a/test/server/runner-test.js b/test/server/runner-test.js index 446879f2..5b606d0e 100644 --- a/test/server/runner-test.js +++ b/test/server/runner-test.js @@ -1,17 +1,17 @@ -var path = require('path'); -var expect = require('chai').expect; -var request = require('request'); -var Promise = require('pinkie'); -var noop = require('lodash').noop; -var times = require('lodash').times; -var createTestCafe = require('../../lib/'); -var COMMAND = require('../../lib/browser/connection/command'); -var Task = require('../../lib/runner/task'); -var BrowserConnection = require('../../lib/browser/connection'); -var BrowserSet = require('../../lib/runner/browser-set'); -var browserProviderPool = require('../../lib/browser/provider/pool'); -var delay = require('../../lib/utils/delay'); - +const path = require('path'); +const expect = require('chai').expect; +const request = require('request'); +const Promise = require('pinkie'); +const noop = require('lodash').noop; +const times = require('lodash').times; +const uniqBy = require('lodash').uniqBy; +const createTestCafe = require('../../lib/'); +const COMMAND = require('../../lib/browser/connection/command'); +const Task = require('../../lib/runner/task'); +const BrowserConnection = require('../../lib/browser/connection'); +const BrowserSet = require('../../lib/runner/browser-set'); +const browserProviderPool = require('../../lib/browser/provider/pool'); +const delay = require('../../lib/utils/delay'); describe('Runner', function () { var testCafe = null; @@ -19,7 +19,7 @@ describe('Runner', function () { var connection = null; var origRemoteBrowserProvider = null; - var remoteBrowserProviderMock = { + const remoteBrowserProviderMock = { openBrowser: function () { return Promise.resolve(); }, @@ -28,9 +28,9 @@ describe('Runner', function () { return Promise.resolve(); } }; + const browserMock = { path: '/non/exist' }; - // Fixture setup/teardown - before(function () { + before(() => { return createTestCafe('127.0.0.1', 1335, 1336) .then(function (tc) { testCafe = tc; @@ -52,20 +52,17 @@ describe('Runner', function () { }); }); - after(function () { + after(() => { browserProviderPool.addProvider('remote', origRemoteBrowserProvider); connection.close(); return testCafe.close(); }); - - // Test setup/teardown - beforeEach(function () { + beforeEach(() => { runner = testCafe.createRunner(); }); - describe('.browsers()', function () { it('Should accept target browsers in different forms', function () { return Promise @@ -175,14 +172,18 @@ describe('Runner', function () { }); it('Should fallback to the default reporter if reporter was not set', function () { - runner._runTask = function (reporters) { - var reporterPlugin = reporters[0].plugin; + const storedRunTaskFn = runner._runTask; + + runner._runTask = reporters => { + const reporterPlugin = reporters[0].plugin; expect(reporterPlugin.reportFixtureStart).to.be.a('function'); expect(reporterPlugin.reportTestDone).to.be.a('function'); expect(reporterPlugin.reportTaskStart).to.be.a('function'); expect(reporterPlugin.reportTaskDone).to.be.a('function'); + runner._runTask = storedRunTaskFn; + return Promise.resolve({}); }; @@ -194,31 +195,44 @@ describe('Runner', function () { }); describe('.src()', function () { - it('Should accept source files in different forms', function () { - var cwd = process.cwd(); - - var expected = [ - './test1.js', - './test2.js', - './dir/test3.js', - '../test4.js', - './test5.js', - './test6.js', - './test7.js' - ]; + it('Should accept source files in different forms', () => { + const cwd = process.cwd(); + const storedRunTaskFn = runner._runTask; + const storedGetBrowserConnectionsFn = runner.bootstrapper._getBrowserConnections; - expected = expected.map(function (filePath) { - return path.resolve(cwd, filePath); - }); + const expectedFiles = [ + 'test/server/data/test-suites/basic/testfile1.js', + 'test/server/data/test-suites/basic/testfile2.js', + ].map(file => path.resolve(cwd, file)); + + runner.bootstrapper._getBrowserConnections = () => { + runner.bootstrapper._getBrowserConnections = storedGetBrowserConnectionsFn; + + return Promise.resolve(); + }; + + runner._runTask = (reporterPlugin, browserSet, tests) => { + const actualFiles = uniqBy(tests.map(test => test.testFile.filename)); + + expect(actualFiles).eql(expectedFiles); - runner.src('./test1.js', './test2.js'); - runner.src('./dir/test3.js'); - runner.src('../test4.js', ['./test5.js'], ['./test6.js', './test7.js']); + runner._runTask = storedRunTaskFn; - expect(runner.bootstrapper.sources).eql(expected); + return Promise.resolve({}); + }; + + return runner + .browsers(browserMock) + .src('test/server/data/test-suites/basic/testfile1.js', + [ + 'test/server/data/test-suites/basic/*.js', + 'test/server/data/test-suites/basic' + ] + ) + .run(); }); - it('Should raise an error if the source was not set', function () { + it('Should raise an error if the source was not set', () => { return runner .browsers(connection) .reporter('list') @@ -233,9 +247,7 @@ describe('Runner', function () { }); describe('.filter()', function () { - - // Test setup - beforeEach(function () { + beforeEach(() => { runner .browsers(connection) .reporter('list') @@ -246,19 +258,19 @@ describe('Runner', function () { }); function testFilter (filterFn, expectedTestNames) { + const storedRunTaskFn = runner._runTask; + runner.filter(filterFn); - runner._runTask = function (reporterPlugin, browserSet, tests) { - var actualTestNames = tests - .map(function (test) { - return test.name; - }) - .sort(); + runner._runTask = (reporterPlugin, browserSet, tests) => { + const actualTestNames = tests.map(test =>test.name).sort(); expectedTestNames = expectedTestNames.sort(); expect(actualTestNames).eql(expectedTestNames); + runner._runTask = storedRunTaskFn; + return Promise.resolve({}); }; @@ -266,12 +278,10 @@ describe('Runner', function () { } - it('Should filter by test name', function () { - var filter = function (testName) { - return testName.indexOf('Fixture2') < 0; - }; + it('Should filter by test name', () => { + const filter = testName => !testName.includes('Fixture2'); - var expectedTestNames = [ + const expectedTestNames = [ 'Fixture1Test1', 'Fixture1Test2', 'Fixture3Test1' @@ -280,12 +290,10 @@ describe('Runner', function () { return testFilter(filter, expectedTestNames); }); - it('Should filter by fixture name', function () { - var filter = function (testName, fixtureName) { - return fixtureName === 'Fixture1'; - }; + it('Should filter by fixture name', () => { + const filter = (testName, fixtureName) => fixtureName === 'Fixture1'; - var expectedTestNames = [ + const expectedTestNames = [ 'Fixture1Test1', 'Fixture1Test2' ]; @@ -293,12 +301,10 @@ describe('Runner', function () { return testFilter(filter, expectedTestNames); }); - it('Should filter by fixture path', function () { - var filter = function (testName, fixtureName, fixturePath) { - return fixturePath.indexOf('testfile2.js') > -1; - }; + it('Should filter by fixture path', () => { + const filter = (testName, fixtureName, fixturePath) => fixturePath.includes('testfile2.js'); - var expectedTestNames = ['Fixture3Test1']; + const expectedTestNames = ['Fixture3Test1']; return testFilter(filter, expectedTestNames); }); @@ -330,7 +336,7 @@ describe('Runner', function () { }; return runner - .browsers({ path: '/non/exist' }) + .browsers(browserMock) .reporter('list') .src([]) .run() @@ -559,7 +565,7 @@ describe('Runner', function () { }); return runner - .browsers({ path: '/non/exist' }) + .browsers(browserMock) .src([]) .run() .then(function () { diff --git a/test/server/util-test.js b/test/server/util-test.js index a27d8886..66138f4f 100644 --- a/test/server/util-test.js +++ b/test/server/util-test.js @@ -1,6 +1,8 @@ +const path = require('path'); const expect = require('chai').expect; const correctFilePath = require('../../lib/utils/correct-file-path'); const escapeUserAgent = require('../../lib/utils/escape-user-agent'); +const parseFileList = require('../../lib/utils/parse-file-list'); describe('Utils', () => { it('Correct File Path', () => { @@ -13,4 +15,51 @@ describe('Utils', () => { it('Escape user agent', () => { expect(escapeUserAgent('Chrome 67.0.3396 / Windows 8.1.0.0')).eql('Chrome_67.0.3396_Windows_8.1.0.0'); }); + + describe('Parse file list', () => { + it('Default directories', () => { + const workingDir = path.join(__dirname, './data/file-list'); + + const expectedFiles = [ + 'test/test-dir-file.js', + 'tests/tests-dir-file.js' + ].map(file => { + return path.resolve(workingDir, file); + }); + + return parseFileList(void 0, workingDir) + .then(actualFiles => { + expect(actualFiles).eql(expectedFiles); + }); + }); + + it('File, directory and glob pattern', () => { + const cwd = process.cwd(); + + const expectedFiles = [ + 'test/server/data/file-list/file-1.js', + 'test/server/data/file-list/file-2.js', + 'test/server/data/file-list/dir1/dir1-1/file-1-1-1.js', + 'test/server/data/file-list/dir1/file-1-1.js', + 'test/server/data/file-list/dir1/file-1-2.js', + 'test/server/data/file-list/dir1/file-1-3.testcafe', + 'test/server/data/file-list/dir1/file-1-4.ts', + 'test/server/data/file-list/dir2/file-2-2.js', + 'test/server/data/file-list/dir2/file-2-3.js' + ].map(file => { + return path.resolve(cwd, file); + }); + + return parseFileList([ + 'test/server/data/file-list/file-1.js', + path.join(cwd, 'test/server/data/file-list/file-2.js'), + 'test/server/data/file-list/dir1', + 'test/server/data/file-list/dir2/*.js', + '!test/server/data/file-list/dir2/file-2-1.js', + 'test/server/data/file-list/dir3' + ], cwd).then(actualFiles => { + expect(actualFiles).eql(expectedFiles); + }); + }); + }); }); From 7effa556828575574082e73443a1b14469758ca2 Mon Sep 17 00:00:00 2001 From: Artem Lavrov Date: Wed, 8 Aug 2018 17:50:08 +0300 Subject: [PATCH 049/184] Bump version (v0.21.1) (#2708) --- CHANGELOG.md | 10 ++++++++++ package.json | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed46c3fb..4a308236 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## v0.21.1 (2018-8-8) + +### Bug fixes + +* The `RequestLogger.clear` method no longer raises an error if it is called during a long running request ([#2688](https://github.com/DevExpress/testcafe/issues/2688)) +* TestCafe now uses native methods to work with the `fetch` request ([#2686](https://github.com/DevExpress/testcafe/issues/2686)) +* A URL now resolves correctly for elements in a `document.implementation` instance ([testcafe-hammerhead/#1673](https://github.com/DevExpress/testcafe-hammerhead/issues/1673)) +* Response header names specified via the `respond` function are lower-cased now ([testcafe-hammerhead/#1704](https://github.com/DevExpress/testcafe-hammerhead/issues/1704)) +* The cookie domain validation rule on the client side has been fixed ([testcafe-hammerhead/#1702](https://github.com/DevExpress/testcafe-hammerhead/issues/1702)) + ## v0.21.0 (2018-8-2) ### Enhancements diff --git a/package.json b/package.json index 3a1bb6b2..168a5818 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.21.0", + "version": "0.21.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" @@ -106,7 +106,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.4", - "testcafe-hammerhead": "14.2.3", + "testcafe-hammerhead": "14.2.4", "testcafe-legacy-api": "3.1.7", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", From 749f7bd01f160abc9ccbcefd9af84aa423d959d9 Mon Sep 17 00:00:00 2001 From: Arseniy Rubtsov Date: Fri, 10 Aug 2018 11:13:52 +0300 Subject: [PATCH 050/184] SelectorExecutor class has been added into client driver's embedding utils (#2666) * SelectorExecutor class has been added into client driver's embedding utils * collectionMode option has been added to initSelector method * parameters passing has been refactored for executeJsExpression --- src/client/driver/embedding-utils.js | 4 +++- src/test-run/commands/assertion.js | 2 +- src/test-run/commands/validations/initializers.js | 13 +++++++++---- src/test-run/execute-js-expression.js | 13 ++++++++----- src/test-run/index.js | 2 +- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/client/driver/embedding-utils.js b/src/client/driver/embedding-utils.js index e466d864..9744fd40 100644 --- a/src/client/driver/embedding-utils.js +++ b/src/client/driver/embedding-utils.js @@ -1,6 +1,8 @@ import { ElementSnapshot, NodeSnapshot } from './command-executors/client-functions/selector-executor/node-snapshots'; +import SelectorExecutor from './command-executors/client-functions/selector-executor'; export default { NodeSnapshot, - ElementSnapshot + ElementSnapshot, + SelectorExecutor }; diff --git a/src/test-run/commands/assertion.js b/src/test-run/commands/assertion.js index 38315637..9ab16bf8 100644 --- a/src/test-run/commands/assertion.js +++ b/src/test-run/commands/assertion.js @@ -17,7 +17,7 @@ function initAssertionOptions (name, val) { function initAssertionParameter (name, val, { skipVisibilityCheck, testRun }) { try { if (isJSExpression(val)) - val = executeJsExpression(val.value, testRun, skipVisibilityCheck); + val = executeJsExpression(val.value, testRun, { skipVisibilityCheck }); return val; } diff --git a/src/test-run/commands/validations/initializers.js b/src/test-run/commands/validations/initializers.js index 1c791474..367fb0fa 100644 --- a/src/test-run/commands/validations/initializers.js +++ b/src/test-run/commands/validations/initializers.js @@ -11,20 +11,25 @@ export function initUploadSelector (name, val, initOptions) { return initSelector(name, val, initOptions); } -export function initSelector (name, val, { skipVisibilityCheck, testRun }) { +export function initSelector (name, val, { testRun, ...options }) { if (val instanceof ExecuteSelectorCommand) return val; try { if (isJSExpression(val)) - val = executeJsExpression(val.value, testRun, skipVisibilityCheck); + val = executeJsExpression(val.value, testRun, options); - var builder = new SelectorBuilder(val, { visibilityCheck: !skipVisibilityCheck }, { instantiation: 'Selector' }); + const { skipVisibilityCheck, ...builderOptions } = options; + + const builder = new SelectorBuilder(val, { + visibilityCheck: !skipVisibilityCheck, + ...builderOptions + }, { instantiation: 'Selector' }); return builder.getCommand([]); } catch (err) { - var msg = err.constructor === APIError ? err.rawMessage : err.message; + const msg = err.constructor === APIError ? err.rawMessage : err.message; throw new ActionSelectorError(name, msg); } diff --git a/src/test-run/execute-js-expression.js b/src/test-run/execute-js-expression.js index a86d03fa..e13fcb37 100644 --- a/src/test-run/execute-js-expression.js +++ b/src/test-run/execute-js-expression.js @@ -27,7 +27,7 @@ function getContext (testRun, options = {}) { function createExecutionContext (testRun) { var sandbox = { Selector: (fn, options = {}) => { - var skipVisibilityCheck = getContextInfo(testRun).options.skipVisibilityCheck; + const { skipVisibilityCheck, collectionMode } = getContextInfo(testRun).options; if (skipVisibilityCheck) options.visibilityCheck = false; @@ -35,7 +35,10 @@ function createExecutionContext (testRun) { if (testRun && testRun.id) options.boundTestRun = testRun; - var builder = new SelectorBuilder(fn, options, { instantiation: 'Selector' }); + if (collectionMode) + options.collectionMode = collectionMode; + + const builder = new SelectorBuilder(fn, options, { instantiation: 'Selector' }); return builder.getFunction(); }, @@ -44,7 +47,7 @@ function createExecutionContext (testRun) { if (testRun && testRun.id) options.boundTestRun = testRun; - var builder = new ClientFunctionBuilder(fn, options, { instantiation: 'ClientFunction' }); + const builder = new ClientFunctionBuilder(fn, options, { instantiation: 'ClientFunction' }); return builder.getFunction(); } @@ -53,8 +56,8 @@ function createExecutionContext (testRun) { return createContext(sandbox); } -export function executeJsExpression (expression, testRun, skipVisibilityCheck) { - const context = getContext(testRun, { skipVisibilityCheck }); +export function executeJsExpression (expression, testRun, options) { + const context = getContext(testRun, options); return runInContext(expression, context, { displayErrors: false }); } diff --git a/src/test-run/index.js b/src/test-run/index.js index 5bf33fb3..a895f97a 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -293,7 +293,7 @@ export default class TestRun extends EventEmitter { _evaluate (code) { try { - return executeJsExpression(code, this, false); + return executeJsExpression(code, this, { skipVisibilityCheck: false }); } catch (err) { return { err }; From b00671b24e09bce17fab5b6c67a0e8dd0aa2f967 Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Fri, 10 Aug 2018 04:19:18 -0700 Subject: [PATCH 051/184] CoffeeScript support (close #1556) (#2651) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * CoffeeScript compiler first pass * Tests for CoffeeScript compiler * Don’t use CoffeeScript’s internal Babel to compile, use the same Babel and method as ESNextTestFileCompiler * CoffeeScript functional tests that mirror TypeScript’s * Don’t crash on variable declaration lines like `var foo;` (this apparently was a bug for regular JS/TypeScript too, not just for CoffeeScript) * Don’t use CoffeeScript safety wrapper, so that the AST nodes we’re looking for are top-level * CoffeeScript parser smoke tests; allow returns of `test` calls --- package.json | 1 + src/compiler/index.js | 2 + .../formats/coffeescript/compiler.js | 41 +++++++++++++ .../formats/coffeescript/get-test-list.js | 29 +++++++++ .../formats/es-next/get-test-list.js | 3 +- .../test-file/test-file-parser-base.js | 10 +++- src/embedding-utils.js | 3 + .../fixtures/api/coffeescript/smoke/test.js | 15 +++++ .../testcafe-fixtures/callsite-test.coffee | 8 +++ .../testcafe-fixtures/non-trivial-test.coffee | 59 +++++++++++++++++++ test/server/compiler-test.js | 58 ++++++++++++++++++ .../coffeescript-basic/dep1.coffee | 2 + .../coffeescript-basic/dep2.coffee | 4 ++ .../coffeescript-basic/testfile1.coffee | 21 +++++++ .../coffeescript-basic/testfile2.coffee | 13 ++++ .../testfile1.coffee | 15 +++++ .../testfile2.coffee | 5 ++ test/server/parse-fixture-test.js | 59 +++++++++++++++---- 18 files changed, 333 insertions(+), 15 deletions(-) create mode 100644 src/compiler/test-file/formats/coffeescript/compiler.js create mode 100644 src/compiler/test-file/formats/coffeescript/get-test-list.js create mode 100644 test/functional/fixtures/api/coffeescript/smoke/test.js create mode 100644 test/functional/fixtures/api/coffeescript/smoke/testcafe-fixtures/callsite-test.coffee create mode 100644 test/functional/fixtures/api/coffeescript/smoke/testcafe-fixtures/non-trivial-test.coffee create mode 100644 test/server/data/test-suites/coffeescript-basic/dep1.coffee create mode 100644 test/server/data/test-suites/coffeescript-basic/dep2.coffee create mode 100644 test/server/data/test-suites/coffeescript-basic/testfile1.coffee create mode 100644 test/server/data/test-suites/coffeescript-basic/testfile2.coffee create mode 100644 test/server/data/test-suites/coffeescript-parser-smoke/testfile1.coffee create mode 100644 test/server/data/test-suites/coffeescript-parser-smoke/testfile2.coffee diff --git a/package.json b/package.json index 168a5818..69733838 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "chalk": "^1.1.0", "chrome-emulated-devices-list": "^0.1.0", "chrome-remote-interface": "^0.25.3", + "coffeescript": "^2.3.1", "commander": "^2.8.1", "debug": "^2.2.0", "dedent": "^0.4.0", diff --git a/src/compiler/index.js b/src/compiler/index.js index bedbdd7c..2a0cebe8 100644 --- a/src/compiler/index.js +++ b/src/compiler/index.js @@ -6,6 +6,7 @@ import { Compiler as LegacyTestFileCompiler } from 'testcafe-legacy-api'; import hammerhead from 'testcafe-hammerhead'; import EsNextTestFileCompiler from './test-file/formats/es-next/compiler'; import TypeScriptTestFileCompiler from './test-file/formats/typescript/compiler'; +import CoffeeScriptTestFileCompiler from './test-file/formats/coffeescript/compiler'; import RawTestFileCompiler from './test-file/formats/raw'; import { readFile } from '../utils/promisified-functions'; import { GeneralError } from '../errors/runtime'; @@ -18,6 +19,7 @@ var testFileCompilers = [ new LegacyTestFileCompiler(hammerhead.processScript), new EsNextTestFileCompiler(), new TypeScriptTestFileCompiler(), + new CoffeeScriptTestFileCompiler(), new RawTestFileCompiler() ]; diff --git a/src/compiler/test-file/formats/coffeescript/compiler.js b/src/compiler/test-file/formats/coffeescript/compiler.js new file mode 100644 index 00000000..f0abc510 --- /dev/null +++ b/src/compiler/test-file/formats/coffeescript/compiler.js @@ -0,0 +1,41 @@ +import CoffeeScript from 'coffeescript'; +import loadBabelLibs from '../../../load-babel-libs'; +import ESNextTestFileCompiler from '../es-next/compiler.js'; + +const FIXTURE_RE = /(^|;|\s+)fixture\s*(\.|\(|'|")/; +const TEST_RE = /(^|;|\s+)test\s*/; + +export default class CoffeeScriptTestFileCompiler extends ESNextTestFileCompiler { + _hasTests (code) { + return FIXTURE_RE.test(code) && TEST_RE.test(code); + } + + _compileCode (code, filename) { + if (this.cache[filename]) + return this.cache[filename]; + + var transpiled = CoffeeScript.compile(code, { + filename, + bare: true, + sourceMap: true, + inlineMap: true, + header: false + }); + + var { babel } = loadBabelLibs(); + var babelOptions = ESNextTestFileCompiler.getBabelOptions(filename, code); + var compiled = babel.transform(transpiled.js, babelOptions); + + this.cache[filename] = compiled.code; + + return compiled.code; + } + + _getRequireCompilers () { + return { '.coffee': (code, filename) => this._compileCode(code, filename) }; + } + + getSupportedExtension () { + return '.coffee'; + } +} diff --git a/src/compiler/test-file/formats/coffeescript/get-test-list.js b/src/compiler/test-file/formats/coffeescript/get-test-list.js new file mode 100644 index 00000000..9a7a1caa --- /dev/null +++ b/src/compiler/test-file/formats/coffeescript/get-test-list.js @@ -0,0 +1,29 @@ +import CoffeeScript from 'coffeescript'; +import { transform } from 'babel-core'; +import ESNextTestFileCompiler from '../es-next/compiler.js'; +import { EsNextTestFileParser } from '../es-next/get-test-list'; + +export class CoffeeScriptTestFileParser extends EsNextTestFileParser { + parse (code) { + const babelOptions = ESNextTestFileCompiler.getBabelOptions(null, code); + + delete babelOptions.filename; + babelOptions.ast = true; + + code = CoffeeScript.compile(code, { + bare: true, + sourceMap: false, + inlineMap: false, + header: false + }); + + const ast = transform(code, babelOptions).ast; + + return this.analyze(ast.program.body); + } +} + +const parser = new CoffeeScriptTestFileParser(); + +export const getCoffeeScriptTestList = parser.getTestList.bind(parser); +export const getCoffeeScriptTestListFromCode = parser.getTestListFromCode.bind(parser); diff --git a/src/compiler/test-file/formats/es-next/get-test-list.js b/src/compiler/test-file/formats/es-next/get-test-list.js index 6fdbb691..c89ef29f 100644 --- a/src/compiler/test-file/formats/es-next/get-test-list.js +++ b/src/compiler/test-file/formats/es-next/get-test-list.js @@ -13,11 +13,12 @@ const TOKEN_TYPE = { ArrowFunctionExpression: 'ArrowFunctionExpression', FunctionExpression: 'FunctionExpression', ExpressionStatement: 'ExpressionStatement', + ReturnStatement: 'ReturnStatement', FunctionDeclaration: 'FunctionDeclaration', VariableDeclaration: 'VariableDeclaration' }; -class EsNextTestFileParser extends TestFileParserBase { +export class EsNextTestFileParser extends TestFileParserBase { constructor () { super(TOKEN_TYPE); } diff --git a/src/compiler/test-file/test-file-parser-base.js b/src/compiler/test-file/test-file-parser-base.js index 57f9ef89..2a97ddc6 100644 --- a/src/compiler/test-file/test-file-parser-base.js +++ b/src/compiler/test-file/test-file-parser-base.js @@ -112,13 +112,19 @@ export class TestFileParserBase { return this.getFunctionBody(token).map(this.analyzeToken, this); - case tokenType.VariableDeclaration: - return this.analyzeToken(this.getRValue(token)); + case tokenType.VariableDeclaration: { + const variableValue = this.getRValue(token); // Skip variable declarations like `var foo;` + + return variableValue ? this.analyzeToken(variableValue) : null; + } case tokenType.CallExpression: case tokenType.PropertyAccessExpression: case tokenType.TaggedTemplateExpression: return this.analyzeFnCall(token); + + case tokenType.ReturnStatement: + return token.argument ? this.analyzeToken(token.argument) : null; } return null; diff --git a/src/embedding-utils.js b/src/embedding-utils.js index 59c5fd01..c8532b0e 100644 --- a/src/embedding-utils.js +++ b/src/embedding-utils.js @@ -6,13 +6,16 @@ import COMMAND_TYPE from './test-run/commands/type'; import Assignable from './utils/assignable'; import { getTestList, getTestListFromCode } from './compiler/test-file/formats/es-next/get-test-list'; import { getTypeScriptTestList, getTypeScriptTestListFromCode } from './compiler/test-file/formats/typescript/get-test-list'; +import { getCoffeeScriptTestList, getCoffeeScriptTestListFromCode } from './compiler/test-file/formats/coffeescript/get-test-list'; import { initSelector } from './test-run/commands/validations/initializers'; export default { getTestList, getTypeScriptTestList, + getCoffeeScriptTestList, getTestListFromCode, getTypeScriptTestListFromCode, + getCoffeeScriptTestListFromCode, TestRunErrorFormattableAdapter, TestRun, testRunErrors, diff --git a/test/functional/fixtures/api/coffeescript/smoke/test.js b/test/functional/fixtures/api/coffeescript/smoke/test.js new file mode 100644 index 00000000..fde40afb --- /dev/null +++ b/test/functional/fixtures/api/coffeescript/smoke/test.js @@ -0,0 +1,15 @@ +var expect = require('chai').expect; + +describe('[CoffeeScript] Smoke tests', function () { + it('Should run non-trivial tests', function () { + return runTests('./testcafe-fixtures/non-trivial-test.coffee', null, { selectorTimeout: 5000 }); + }); + + it('Should produce correct callsites on error', function () { + return runTests('./testcafe-fixtures/callsite-test.coffee', null, { shouldFail: true }) + .catch(function (errs) { + expect(errs[0]).contains('The specified selector does not match any element in the DOM tree.'); + expect(errs[0]).contains('> 5 |doSmthg = (selector, t) -> await t.click selector'); + }); + }); +}); diff --git a/test/functional/fixtures/api/coffeescript/smoke/testcafe-fixtures/callsite-test.coffee b/test/functional/fixtures/api/coffeescript/smoke/testcafe-fixtures/callsite-test.coffee new file mode 100644 index 00000000..d235477b --- /dev/null +++ b/test/functional/fixtures/api/coffeescript/smoke/testcafe-fixtures/callsite-test.coffee @@ -0,0 +1,8 @@ +import 'testcafe' + +fixture 'CoffeeScript callsites' + +doSmthg = (selector, t) -> await t.click selector + +test 'Test', (t) => + await doSmthg '#heyheyhey', t diff --git a/test/functional/fixtures/api/coffeescript/smoke/testcafe-fixtures/non-trivial-test.coffee b/test/functional/fixtures/api/coffeescript/smoke/testcafe-fixtures/non-trivial-test.coffee new file mode 100644 index 00000000..cfbf783d --- /dev/null +++ b/test/functional/fixtures/api/coffeescript/smoke/testcafe-fixtures/non-trivial-test.coffee @@ -0,0 +1,59 @@ +import { Selector, Role, t } from 'testcafe' + +iframeElement = Selector '#element-in-iframe' +pageElement = Selector '#element-on-page' +showAlertBtn = Selector '#show-alert' + +initConfiguration = -> + await t + .setNativeDialogHandler => on + .click showAlertBtn + + history = await t.getNativeDialogHistory() + + await t + .expect(history[0].text).eql 'Hey!' + .switchToIframe '#iframe' + .expect(iframeElement.exists).ok() + .setTestSpeed 0.95 + .setPageLoadTimeout 95 + + t.ctx['someVal'] = 'ctxVal' + t.fixtureCtx['someVal'] = 'fixtureCtxVal' + +role1 = Role 'http://localhost:3000/fixtures/api/es-next/roles/pages/index.html', => + await t + .setNativeDialogHandler => on + + await t + .expect(pageElement.exists).ok() + .expect(t.ctx['someVal']).notOk() + .expect(t.fixtureCtx['someVal']).notOk() + + await t.click showAlertBtn + +role2 = Role 'http://localhost:3000/fixtures/api/es-next/roles/pages/index.html', => + +fixture 'CoffeeScript smoke tests' + .page 'http://localhost:3000/fixtures/api/es-next/roles/pages/index.html' + +test 'Clear configuration', => + await initConfiguration() + await t.useRole role1 + +test 'Restore configuration', => + await initConfiguration() + + await t + .useRole role2 + .expect(iframeElement.exists).ok() + .expect(t.ctx['someVal']).eql 'ctxVal' + .expect(t.fixtureCtx['someVal']).eql 'fixtureCtxVal' + + await t + .switchToMainWindow() + .click showAlertBtn + + history = await t.getNativeDialogHistory() + + await t.expect(history[0].text).eql 'Hey!' diff --git a/test/server/compiler-test.js b/test/server/compiler-test.js index 4b1a8eda..247c7cf5 100644 --- a/test/server/compiler-test.js +++ b/test/server/compiler-test.js @@ -241,6 +241,64 @@ describe('Compiler', function () { }); + describe('CoffeeScript', function () { + it('Should compile test files and their dependencies', function () { + var sources = [ + 'test/server/data/test-suites/coffeescript-basic/testfile1.coffee', + 'test/server/data/test-suites/coffeescript-basic/testfile2.coffee' + ]; + + return compile(sources) + .then(function (compiled) { + var testfile1 = path.resolve('test/server/data/test-suites/coffeescript-basic/testfile1.coffee'); + var testfile2 = path.resolve('test/server/data/test-suites/coffeescript-basic/testfile2.coffee'); + + var tests = compiled.tests; + var fixtures = compiled.fixtures; + + expect(tests.length).eql(4); + expect(fixtures.length).eql(3); + + expect(fixtures[0].name).eql('Fixture1'); + expect(fixtures[0].path).eql(testfile1); + expect(fixtures[0].pageUrl).eql('about:blank'); + + expect(fixtures[1].name).eql('Fixture2'); + expect(fixtures[1].path).eql(testfile1); + expect(fixtures[1].pageUrl).eql('http://example.org'); + + expect(fixtures[2].name).eql('Fixture3'); + expect(fixtures[2].path).eql(testfile2); + expect(fixtures[2].pageUrl).eql('https://example.com'); + + expect(tests[0].name).eql('Fixture1Test1'); + expect(tests[0].fixture).eql(fixtures[0]); + + expect(tests[1].name).eql('Fixture1Test2'); + expect(tests[1].fixture).eql(fixtures[0]); + + expect(tests[2].name).eql('Fixture2Test1'); + expect(tests[2].fixture).eql(fixtures[1]); + + expect(tests[3].name).eql('Fixture3Test1'); + expect(tests[3].fixture).eql(fixtures[2]); + + return Promise.all(tests.map(function (test) { + return test.fn(testRunMock); + })); + }) + .then(function (results) { + expect(results).eql([ + 'F1T1: Hey from dep1', + 'F1T2', + 'F2T1', + 'F3T1: Hey from dep1 and dep2' + ]); + }); + }); + }); + + describe('RAW file', function () { it('Should compile test files', function () { var sources = ['test/server/data/test-suites/raw/test.testcafe']; diff --git a/test/server/data/test-suites/coffeescript-basic/dep1.coffee b/test/server/data/test-suites/coffeescript-basic/dep1.coffee new file mode 100644 index 00000000..fa5e9f90 --- /dev/null +++ b/test/server/data/test-suites/coffeescript-basic/dep1.coffee @@ -0,0 +1,2 @@ +export default -> + 'Hey from dep1' diff --git a/test/server/data/test-suites/coffeescript-basic/dep2.coffee b/test/server/data/test-suites/coffeescript-basic/dep2.coffee new file mode 100644 index 00000000..98b666b8 --- /dev/null +++ b/test/server/data/test-suites/coffeescript-basic/dep2.coffee @@ -0,0 +1,4 @@ +import dep1Fn from './dep1' + +export default -> + "#{await dep1Fn()} and dep2" diff --git a/test/server/data/test-suites/coffeescript-basic/testfile1.coffee b/test/server/data/test-suites/coffeescript-basic/testfile1.coffee new file mode 100644 index 00000000..845dfbf2 --- /dev/null +++ b/test/server/data/test-suites/coffeescript-basic/testfile1.coffee @@ -0,0 +1,21 @@ +import 'testcafe' +import dep1Fn from './dep1' + +fixture 'Fixture1' + +test 'Fixture1Test1', => + res = await dep1Fn() + "F1T1: #{res}" + +test2Name = 'Fixture1Test2' + +test test2Name, => + 'F1T2' + +fixture "Fixture#{1 + 1}" + .page 'http://example.org' + .beforeEach => 'yo' + .afterEach => 'yo' + +test 'Fixture2Test1', => + 'F2T1' diff --git a/test/server/data/test-suites/coffeescript-basic/testfile2.coffee b/test/server/data/test-suites/coffeescript-basic/testfile2.coffee new file mode 100644 index 00000000..5eb41bc8 --- /dev/null +++ b/test/server/data/test-suites/coffeescript-basic/testfile2.coffee @@ -0,0 +1,13 @@ +import 'testcafe' +import dep2Fn from './dep2' + +fixture 'Fixture3' + .page 'https://example.com' + .afterEach => 'yo' + .beforeEach => 'yo' + +fixture3Name = 'Fixture3Test1' + +test fixture3Name, => + res = await dep2Fn() + "F3T1: #{res}" diff --git a/test/server/data/test-suites/coffeescript-parser-smoke/testfile1.coffee b/test/server/data/test-suites/coffeescript-parser-smoke/testfile1.coffee new file mode 100644 index 00000000..e9634046 --- /dev/null +++ b/test/server/data/test-suites/coffeescript-parser-smoke/testfile1.coffee @@ -0,0 +1,15 @@ +getPageUrl = (index) -> + "http://page/#{index}" + +fixture('fixture 1').page getFixtureName(1) + +doSmthg = (selector, t) -> + await t.click selector + +test 'test 1', (t) => + await doSmthg '#my-el', t + +((fixtureName, testName) -> + fixture(fixtureName).page 'http://myPage' + test testName, (t) => +) 'fixture 2', 'test 2' diff --git a/test/server/data/test-suites/coffeescript-parser-smoke/testfile2.coffee b/test/server/data/test-suites/coffeescript-parser-smoke/testfile2.coffee new file mode 100644 index 00000000..ae69b49a --- /dev/null +++ b/test/server/data/test-suites/coffeescript-parser-smoke/testfile2.coffee @@ -0,0 +1,5 @@ +fixture('fixture 1').page 'https://page' + +test.before((t) => + await t.wait 1 +) 'test 1' diff --git a/test/server/parse-fixture-test.js b/test/server/parse-fixture-test.js index 58c85468..97d3a383 100644 --- a/test/server/parse-fixture-test.js +++ b/test/server/parse-fixture-test.js @@ -1,13 +1,15 @@ -var expect = require('chai').expect; -var fs = require('fs'); -var path = require('path'); -var assign = require('lodash').assign; -var getTestList = require('../../lib/embedding-utils').getTestList; -var getTypeScriptTestList = require('../../lib/embedding-utils').getTypeScriptTestList; -var getTestListFromCode = require('../../lib/embedding-utils').getTestListFromCode; -var getTypeScriptTestListFromCode = require('../../lib/embedding-utils').getTypeScriptTestListFromCode; -var Promise = require('pinkie'); -var parserBase = require('../../lib/compiler/test-file/test-file-parser-base'); +var expect = require('chai').expect; +var fs = require('fs'); +var path = require('path'); +var assign = require('lodash').assign; +var getTestList = require('../../lib/embedding-utils').getTestList; +var getTypeScriptTestList = require('../../lib/embedding-utils').getTypeScriptTestList; +var getCoffeeScriptTestList = require('../../lib/embedding-utils').getCoffeeScriptTestList; +var getTestListFromCode = require('../../lib/embedding-utils').getTestListFromCode; +var getTypeScriptTestListFromCode = require('../../lib/embedding-utils').getTypeScriptTestListFromCode; +var getCoffeeScriptTestListFromCode = require('../../lib/embedding-utils').getCoffeeScriptTestListFromCode; +var Promise = require('pinkie'); +var parserBase = require('../../lib/compiler/test-file/test-file-parser-base'); var Test = parserBase.Test; var Fixture = function (name, start, end, loc, tests) { @@ -52,6 +54,10 @@ function testTypeScriptFilesParser (dir, expectedStructure) { return testFixtureParser(dir, expectedStructure, getTypeScriptTestList, getTypeScriptTestListFromCode); } +function testCoffeeScriptFilesParser (dir, expectedStructure) { + return testFixtureParser(dir, expectedStructure, getCoffeeScriptTestList, getCoffeeScriptTestListFromCode); +} + describe('Should get structure of files (esnext and typescript common cases)', function () { it('Base', function () { var expectedStructure = [ @@ -200,8 +206,7 @@ describe('Should get structure of files (esnext and typescript common cases)', f }); }); - -describe('Should get structure of typescript files', function () { +describe('Should get structure of TypeScript files', function () { it('Smoke test', () => { var expectedStructure = [ [ @@ -231,6 +236,36 @@ describe('Should get structure of typescript files', function () { }); }); +describe('Should get structure of CoffeeScript files', function () { + it('Smoke test', () => { + var expectedStructure = [ + [ + new Fixture('fixture 1', 94, 138, new Loc(7, 0, 7, 44), + [ + new Test('test 1', 221, 291, new Loc(13, 0, 15, 2)) + ] + ), + + new Fixture('(line: 18)', 331, 373, new Loc(18, 2, 18, 44), + [ + new Test('(line: 19)', 384, 409, new Loc(19, 9, 19, 34)) + ] + ) + ], + + [ + new Fixture('fixture 1', 0, 41, new Loc(1, 0, 1, 41), + [ + new Test('test 1', 44, 110, new Loc(3, 0, 5, 12)) + ] + ) + ] + ]; + + return testCoffeeScriptFilesParser('./data/test-suites/coffeescript-parser-smoke', expectedStructure); + }); +}); + describe('Regression', function () { it('Parser fails with "JS allocation failed" error (GH-1771)', function () { var expectedStructure = [[ From c08baf6aa22b7e1852c1c2cc93d642fd56b019b5 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 10 Aug 2018 15:07:11 +0300 Subject: [PATCH 052/184] [docs] [WIP] Describe using globs in runner.src (#1805) * Describe using globs in runner.src * add link to glob patterns' description --- .../using-testcafe/programming-interface/runner.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index 291dfd78..8ea35944 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -65,16 +65,20 @@ src(source) → this Parameter | Type | Description --------- | ------------------- | ---------------------------------------------------------------------------- -`source` | String | Array | The relative or absolute path to a test fixture file, or several such paths. +`source` | String | Array | The relative or absolute path to a test fixture file, or several such paths. You can use [glob patterns](https://github.com/isaacs/node-glob#glob-primer) to include (or exclude) multiple files. If you call the method several times, all the specified sources are added to the test runner. -**Example** +**Examples** ```js runner.src(['/home/user/tests/fixture1.js', 'fixture5.js']); ``` +```js +runner.src(['/home/user/tests/**/*.js', '!/home/user/tests/foo.js']); +``` + ### filter Allows you to select which tests should be run. From 7e66e24bae126a01c654ed918d8d1592bf94bc1a Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Fri, 10 Aug 2018 16:54:22 +0300 Subject: [PATCH 053/184] Remove 'test-client-old-browsers-travis' task (#2716) --- Gulpfile.js | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/Gulpfile.js b/Gulpfile.js index 32d144f5..5692011a 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -111,19 +111,6 @@ var CLIENT_TESTS_DESKTOP_BROWSERS = [ } ]; -var CLIENT_TESTS_OLD_BROWSERS = [ - { - platform: 'Windows 8', - browserName: 'internet explorer', - version: '10.0' - }, - { - platform: 'Windows 7', - browserName: 'internet explorer', - version: '9.0' - } -]; - var CLIENT_TESTS_MOBILE_BROWSERS = [ { platform: 'Linux', @@ -372,16 +359,6 @@ gulp.step('test-client-travis-run', function () { gulp.task('test-client-travis', gulp.series('build', 'test-client-travis-run')); -gulp.step('test-client-old-browsers-travis-run', function () { - var saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; - - saucelabsSettings.browsers = CLIENT_TESTS_OLD_BROWSERS; - - return testClient('test/client/fixtures/**/*-test.js', CLIENT_TESTS_SETTINGS, saucelabsSettings); -}); - -gulp.task('test-client-old-browsers-travis', gulp.series('build', 'test-client-old-browsers-travis-run')); - gulp.step('test-client-travis-mobile-run', function () { var saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; From e8c47f5fd6b4f3996f0e44e366f9bec1fb931a0c Mon Sep 17 00:00:00 2001 From: Andrey Churkin Date: Mon, 13 Aug 2018 09:47:23 +0300 Subject: [PATCH 054/184] add missed articles (#2715) * add missed articles * Another one --- .../fixtures/api/raw/execute-expression/test.js | 8 ++++---- .../testcafe-fixtures/shared-context.testcafe | 6 +++--- test/server/test-run-error-formatting-test.js | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/functional/fixtures/api/raw/execute-expression/test.js b/test/functional/fixtures/api/raw/execute-expression/test.js index cc1e8aa4..3e893c52 100644 --- a/test/functional/fixtures/api/raw/execute-expression/test.js +++ b/test/functional/fixtures/api/raw/execute-expression/test.js @@ -1,17 +1,17 @@ describe('[Raw API] Execute expression action', function () { it('Should execute async expressions', function () { - return runTests('./testcafe-fixtures/shared-context.testcafe', 'Execute async expression'); + return runTests('./testcafe-fixtures/shared-context.testcafe', 'Execute an async expression'); }); it('Should execute simple sync expressions', function () { - return runTests('./testcafe-fixtures/shared-context.testcafe', 'Execute sync expression and save to a variable'); + return runTests('./testcafe-fixtures/shared-context.testcafe', 'Execute a sync expression and save to a variable'); }); it('Should share global variables between different command calls', function () { return runTests('./testcafe-fixtures/shared-context.testcafe', 'Share variables between commands'); }); - it('Should store async property value to a variable', function () { - return runTests('./testcafe-fixtures/shared-context.testcafe', 'Store execution result to a variable'); + it('Should store an async property value to a variable', function () { + return runTests('./testcafe-fixtures/shared-context.testcafe', 'Store an execution result to a variable'); }); }); diff --git a/test/functional/fixtures/api/raw/execute-expression/testcafe-fixtures/shared-context.testcafe b/test/functional/fixtures/api/raw/execute-expression/testcafe-fixtures/shared-context.testcafe index 58206f7b..5876252b 100644 --- a/test/functional/fixtures/api/raw/execute-expression/testcafe-fixtures/shared-context.testcafe +++ b/test/functional/fixtures/api/raw/execute-expression/testcafe-fixtures/shared-context.testcafe @@ -5,7 +5,7 @@ "pageUrl": "http://localhost:3000/fixtures/api/raw/execute-expression/pages/index.html", "tests": [ { - "name": "Execute async expression", + "name": "Execute an async expression", "commands": [ { "type": "execute-expression", @@ -21,7 +21,7 @@ ] }, { - "name": "Execute sync expression and save to a variable", + "name": "Execute a sync expression and save to a variable", "commands": [ { "type": "execute-expression", @@ -63,7 +63,7 @@ ] }, { - "name": "Store execution result to a variable", + "name": "Store an execution result to a variable", "commands": [ { "type": "execute-expression", diff --git a/test/server/test-run-error-formatting-test.js b/test/server/test-run-error-formatting-test.js index 02525707..095aaa72 100644 --- a/test/server/test-run-error-formatting-test.js +++ b/test/server/test-run-error-formatting-test.js @@ -145,7 +145,7 @@ describe('Error formatting', function () { assertErrorMessage('action-boolean-option-error', new ActionBooleanOptionError('modifier.ctrl', 'object')); }); - it('Should format "actionBooleanArgumentError" message', function () { + it('Should format the "actionBooleanArgumentError" message', function () { assertErrorMessage('action-boolean-argument-error', new ActionBooleanArgumentError('isAsyncExpression', 'object')); }); From 26aeffdd5ccd989a472abe1b62f4e0ae73566f18 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Tue, 14 Aug 2018 18:34:43 +0300 Subject: [PATCH 055/184] Bump version (v0.21.2-alpha.1) (#2730) --- .publishrc | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.publishrc b/.publishrc index 5727c783..2414a453 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "latest", + "publishTag": "alpha", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index 69733838..d89f113d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.21.1", + "version": "0.21.2-alpha.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" @@ -106,7 +106,7 @@ "sanitize-filename": "^1.6.0", "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", - "testcafe-browser-tools": "1.6.4", + "testcafe-browser-tools": "1.6.5", "testcafe-hammerhead": "14.2.4", "testcafe-legacy-api": "3.1.7", "testcafe-reporter-json": "^2.1.0", From ce3c4d8edfaed1df6edfd1a1633f8aa1760cd7c2 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Wed, 15 Aug 2018 15:44:51 +0300 Subject: [PATCH 056/184] fix 'Should not fail when logger logs and stringifies a response body and it equals null' (close #2718) (#2723) --- src/api/request-hooks/request-logger.js | 7 +++++-- test/server/request-hooks-test.js | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/api/request-hooks/request-logger.js b/src/api/request-hooks/request-logger.js index f08c55dd..69f9fee9 100644 --- a/src/api/request-hooks/request-logger.js +++ b/src/api/request-hooks/request-logger.js @@ -73,8 +73,11 @@ class RequestLoggerImplementation extends RequestHook { if (this.options.logResponseHeaders) loggerReq.response.headers = Object.assign({}, event.headers); - if (this.options.logResponseBody) - loggerReq.response.body = this.options.stringifyResponseBody ? event.body.toString() : event.body; + if (this.options.logResponseBody) { + loggerReq.response.body = this.options.stringifyResponseBody && event.body + ? event.body.toString() + : event.body; + } } _prepareInternalRequestInfo () { diff --git a/test/server/request-hooks-test.js b/test/server/request-hooks-test.js index 513c9c8a..117c12c4 100644 --- a/test/server/request-hooks-test.js +++ b/test/server/request-hooks-test.js @@ -184,6 +184,16 @@ describe('RequestLogger', () => { expect(logger.requests.length).eql(0); }); + + it('Should not fail when logger logs and stringifies a response body and it equals null (GH-2718)', () => { + const logger = new RequestLogger('http://example.com/', { logResponseBody: true, stringifyResponseBody: true }); + const clonedResponseEventMock = Object.assign({}, responseEventMock, { body: null }); + + logger.onRequest(requestEventMock); + logger.onResponse(clonedResponseEventMock); + + expect(logger.requests[0].response.body).eql(null); + }); }); describe('RequestMock', () => { From 4bb7c6633f199fde655d29e16c079394e3305f96 Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Wed, 15 Aug 2018 15:46:45 +0300 Subject: [PATCH 057/184] [docs] coffeescript support (#2731) --- .../articles/documentation/test-api/README.md | 3 +- .../test-api/coffeescript-support.md | 28 +++++++++++++++++++ .../test-api/test-code-structure.md | 2 +- docs/nav/nav-menu.yml | 6 ++-- 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 docs/articles/documentation/test-api/coffeescript-support.md diff --git a/docs/articles/documentation/test-api/README.md b/docs/articles/documentation/test-api/README.md index 8e0f20dd..52ebe3f0 100644 --- a/docs/articles/documentation/test-api/README.md +++ b/docs/articles/documentation/test-api/README.md @@ -6,12 +6,11 @@ checked: true --- # Test API -TestCafe allows you to write tests using JavaScript and TypeScript (see [TypeScript Support](typescript-support.md) for more information about writing tests in TypeScript). +TestCafe allows you to write tests using JavaScript, [TypeScript](typescript-support.md) and [CoffeeScript](coffeescript-support.md). The following topics demonstrate how to organize test code: * [Test Code Structure](test-code-structure.md) -* [TypeScript Support](typescript-support.md) The following topics describe the API used to manipulate the webpage and check its state: diff --git a/docs/articles/documentation/test-api/coffeescript-support.md b/docs/articles/documentation/test-api/coffeescript-support.md new file mode 100644 index 00000000..14accc44 --- /dev/null +++ b/docs/articles/documentation/test-api/coffeescript-support.md @@ -0,0 +1,28 @@ +--- +layout: docs +title: CoffeeScript Support +permalink: /documentation/test-api/coffeescript-support.html +--- +# CoffeeScript Support + +TestCafe allows you to write tests with [CoffeeScript](https://coffeescript.org/). + +**Example** + +```coffee +import { Selector } from 'testcafe' + +fixture 'CoffeeScript Example' + .page 'https://devexpress.github.io/testcafe/example/' + +nameInput = Selector '#developer-name' + +test 'Test', (t) => + await t + .typeText(nameInput, 'Peter') + .typeText(nameInput, 'Paker', { replace: true }) + .typeText(nameInput, 'r', { caretPos: 2 }) + .expect(nameInput.value).eql 'Parker'; +``` + +You can run CoffeeScript tests in the same manner as JavaScript tests. TestCafe automatically compiles the CoffeeScript code, so you do not need to compile it manually. \ No newline at end of file diff --git a/docs/articles/documentation/test-api/test-code-structure.md b/docs/articles/documentation/test-api/test-code-structure.md index db8acfc0..1dff3156 100644 --- a/docs/articles/documentation/test-api/test-code-structure.md +++ b/docs/articles/documentation/test-api/test-code-structure.md @@ -29,7 +29,7 @@ to avoid the `'fixture' is not defined` and `'test' is not defined` errors. ## Fixtures TestCafe tests must be organized into categories called *fixtures*. -A JavaScript or TypeScript file with TestCafe tests can contain one or more fixtures. +A JavaScript, TypeScript or CoffeeScript file with TestCafe tests can contain one or more fixtures. To declare a test fixture, use the `fixture` function. diff --git a/docs/nav/nav-menu.yml b/docs/nav/nav-menu.yml index 522c1e5b..ad927fea 100644 --- a/docs/nav/nav-menu.yml +++ b/docs/nav/nav-menu.yml @@ -43,8 +43,6 @@ - name: TEST API url: /documentation/test-api/README.md content: - - name: TypeScript Support - url: /documentation/test-api/typescript-support.md - name: Test Code Structure url: /documentation/test-api/test-code-structure.md content: @@ -171,6 +169,10 @@ url: /documentation/test-api/debugging.md - name: Accessing Console Messages url: /documentation/test-api/accessing-console-messages.md + - name: TypeScript Support + url: /documentation/test-api/typescript-support.md + - name: CoffeeScript Support + url: /documentation/test-api/coffeescript-support.md - name: A-Z Index url: /documentation/test-api/a-z.md - name: EXTENDING TESTCAFE From ac21fdb27f9f87fd8761884635d9d80d9db3d8a6 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Thu, 16 Aug 2018 19:20:46 +0300 Subject: [PATCH 058/184] Add uncaught exception and unhandled rejection handlers to server code (closes #2546) (#2606) --- Gulpfile.js | 148 ++++++++-------- package.json | 1 + src/cli/argument-parser.js | 1 + src/compiler/index.js | 11 -- src/errors/test-run/index.js | 16 ++ src/errors/test-run/templates.js | 12 ++ src/errors/test-run/type.js | 2 + src/runner/index.js | 32 ++-- src/test-run/index.js | 3 +- src/testcafe.js | 13 ++ src/utils/handle-errors.js | 70 ++++++++ .../regression/gh-2546/pages/index.html | 9 + .../fixtures/regression/gh-2546/test.js | 82 +++++++++ .../gh-2546/testcafe-fixtures/index.js | 12 ++ .../testcafe-fixtures/uncaughtException.js | 8 + test/functional/setup.js | 3 +- test/server/cli-argument-parser-test.js | 1 + test/server/compiler-test.js | 141 +++++++++------ .../uncaught-exception-error | 7 + .../unhandled-promise-rejection-error | 7 + test/server/error-handle-test.js | 72 ++++++++ test/server/test-run-error-formatting-test.js | 160 ++++++++++-------- 22 files changed, 585 insertions(+), 226 deletions(-) create mode 100644 src/utils/handle-errors.js create mode 100644 test/functional/fixtures/regression/gh-2546/pages/index.html create mode 100644 test/functional/fixtures/regression/gh-2546/test.js create mode 100644 test/functional/fixtures/regression/gh-2546/testcafe-fixtures/index.js create mode 100644 test/functional/fixtures/regression/gh-2546/testcafe-fixtures/uncaughtException.js create mode 100644 test/server/data/expected-test-run-errors/uncaught-exception-error create mode 100644 test/server/data/expected-test-run-errors/unhandled-promise-rejection-error create mode 100644 test/server/error-handle-test.js diff --git a/Gulpfile.js b/Gulpfile.js index 5692011a..cca9ad70 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -1,39 +1,40 @@ -var babel = require('babel-core'); -var gulp = require('gulp'); -var gulpStep = require('gulp-step'); -var gulpBabel = require('gulp-babel'); -var data = require('gulp-data'); -var less = require('gulp-less'); -var qunitHarness = require('gulp-qunit-harness'); -var git = require('gulp-git'); -var ghpages = require('gulp-gh-pages'); -var mocha = require('gulp-mocha-simple'); -var mustache = require('gulp-mustache'); -var rename = require('gulp-rename'); -var webmake = require('gulp-webmake'); -var uglify = require('gulp-uglify'); -var ll = require('gulp-ll-next'); +const babel = require('babel-core'); +const gulp = require('gulp'); +const gulpStep = require('gulp-step'); +const gulpBabel = require('gulp-babel'); +const data = require('gulp-data'); +const less = require('gulp-less'); +const qunitHarness = require('gulp-qunit-harness'); +const git = require('gulp-git'); +const ghpages = require('gulp-gh-pages'); +const mocha = require('gulp-mocha-simple'); +const mustache = require('gulp-mustache'); +const rename = require('gulp-rename'); +const webmake = require('gulp-webmake'); +const uglify = require('gulp-uglify'); +const ll = require('gulp-ll-next'); const clone = require('gulp-clone'); const mergeStreams = require('merge-stream'); -var del = require('del'); -var fs = require('fs'); -var path = require('path'); -var globby = require('globby'); -var opn = require('opn'); -var connect = require('connect'); -var spawn = require('cross-spawn'); -var serveStatic = require('serve-static'); -var Promise = require('pinkie'); -var markdownlint = require('markdownlint'); -var minimist = require('minimist'); -var prompt = require('gulp-prompt'); -var functionalTestConfig = require('./test/functional/config'); -var assignIn = require('lodash').assignIn; -var yaml = require('js-yaml'); -var childProcess = require('child_process'); -var listBrowsers = require('testcafe-browser-tools').getInstallations; -var npmAuditor = require('npm-auditor'); -var checkLicenses = require('./test/dependency-licenses-checker'); +const del = require('del'); +const fs = require('fs'); +const path = require('path'); +const globby = require('globby'); +const opn = require('opn'); +const connect = require('connect'); +const spawn = require('cross-spawn'); +const serveStatic = require('serve-static'); +const Promise = require('pinkie'); +const markdownlint = require('markdownlint'); +const minimist = require('minimist'); +const prompt = require('gulp-prompt'); +const functionalTestConfig = require('./test/functional/config'); +const assignIn = require('lodash').assignIn; +const yaml = require('js-yaml'); +const childProcess = require('child_process'); +const listBrowsers = require('testcafe-browser-tools').getInstallations; +const npmAuditor = require('npm-auditor'); +const checkLicenses = require('./test/dependency-licenses-checker'); +const sourcemaps = require('gulp-sourcemaps'); gulpStep.install(); @@ -50,13 +51,13 @@ ll 'client-scripts-bundle' ]); -var ARGS = minimist(process.argv.slice(2)); -var DEV_MODE = 'dev' in ARGS; +const ARGS = minimist(process.argv.slice(2)); +const DEV_MODE = 'dev' in ARGS; -var CLIENT_TESTS_PATH = 'test/client/fixtures'; -var CLIENT_TESTS_LEGACY_PATH = 'test/client/legacy-fixtures'; +const CLIENT_TESTS_PATH = 'test/client/fixtures'; +const CLIENT_TESTS_LEGACY_PATH = 'test/client/legacy-fixtures'; -var CLIENT_TESTS_SETTINGS_BASE = { +const CLIENT_TESTS_SETTINGS_BASE = { port: 2000, crossDomainPort: 2001, @@ -74,11 +75,11 @@ var CLIENT_TESTS_SETTINGS_BASE = { configApp: require('./test/client/config-qunit-server-app') }; -var CLIENT_TESTS_SETTINGS = assignIn({}, CLIENT_TESTS_SETTINGS_BASE, { basePath: CLIENT_TESTS_PATH }); -var CLIENT_TESTS_LOCAL_SETTINGS = assignIn({}, CLIENT_TESTS_SETTINGS); -var CLIENT_TESTS_LEGACY_SETTINGS = assignIn({}, CLIENT_TESTS_SETTINGS_BASE, { basePath: CLIENT_TESTS_LEGACY_PATH }); +const CLIENT_TESTS_SETTINGS = assignIn({}, CLIENT_TESTS_SETTINGS_BASE, { basePath: CLIENT_TESTS_PATH }); +const CLIENT_TESTS_LOCAL_SETTINGS = assignIn({}, CLIENT_TESTS_SETTINGS); +const CLIENT_TESTS_LEGACY_SETTINGS = assignIn({}, CLIENT_TESTS_SETTINGS_BASE, { basePath: CLIENT_TESTS_LEGACY_PATH }); -var CLIENT_TESTS_DESKTOP_BROWSERS = [ +const CLIENT_TESTS_DESKTOP_BROWSERS = [ { platform: 'Windows 10', browserName: 'microsoftedge' @@ -111,7 +112,7 @@ var CLIENT_TESTS_DESKTOP_BROWSERS = [ } ]; -var CLIENT_TESTS_MOBILE_BROWSERS = [ +const CLIENT_TESTS_MOBILE_BROWSERS = [ { platform: 'Linux', browserName: 'android', @@ -129,7 +130,7 @@ var CLIENT_TESTS_MOBILE_BROWSERS = [ } ]; -var CLIENT_TESTS_SAUCELABS_SETTINGS = { +const CLIENT_TESTS_SAUCELABS_SETTINGS = { username: process.env.SAUCE_USERNAME, accessKey: process.env.SAUCE_ACCESS_KEY, build: process.env.TRAVIS_BUILD_ID || '', @@ -138,11 +139,11 @@ var CLIENT_TESTS_SAUCELABS_SETTINGS = { timeout: 720 }; -var CLIENT_TEST_LOCAL_BROWSERS_ALIASES = ['ie', 'edge', 'chrome', 'firefox', 'safari']; +const CLIENT_TEST_LOCAL_BROWSERS_ALIASES = ['ie', 'edge', 'chrome', 'firefox', 'safari']; -var PUBLISH_TAG = JSON.parse(fs.readFileSync(path.join(__dirname, '.publishrc')).toString()).publishTag; +const PUBLISH_TAG = JSON.parse(fs.readFileSync(path.join(__dirname, '.publishrc')).toString()).publishTag; -var websiteServer = null; +let websiteServer = null; gulp.task('audit', function () { return npmAuditor() @@ -162,7 +163,7 @@ gulp.task('clean', function () { // Lint gulp.task('lint', function () { - var eslint = require('gulp-eslint'); + const eslint = require('gulp-eslint'); return gulp .src([ @@ -196,7 +197,7 @@ gulp.step('client-scripts-bundle', function () { .pipe(webmake({ sourceMap: false, transform: function (filename, code) { - var transformed = babel.transform(code, { + const transformed = babel.transform(code, { sourceMap: false, ast: false, filename: filename, @@ -259,7 +260,12 @@ gulp.step('server-scripts', function () { 'src/**/*.js', '!src/client/**/*.js' ]) + .pipe(sourcemaps.init()) .pipe(gulpBabel()) + .pipe(sourcemaps.mapSources(function (sourcePath, file) { + return file.path; + })) + .pipe(sourcemaps.write()) .pipe(gulp.dest('lib')); }); @@ -350,7 +356,7 @@ gulp.step('test-client-legacy-run', function () { gulp.task('test-client-legacy', gulp.series('build', 'test-client-legacy-run')); gulp.step('test-client-travis-run', function () { - var saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; + const saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; saucelabsSettings.browsers = CLIENT_TESTS_DESKTOP_BROWSERS; @@ -360,7 +366,7 @@ gulp.step('test-client-travis-run', function () { gulp.task('test-client-travis', gulp.series('build', 'test-client-travis-run')); gulp.step('test-client-travis-mobile-run', function () { - var saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; + const saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; saucelabsSettings.browsers = CLIENT_TESTS_MOBILE_BROWSERS; @@ -370,7 +376,7 @@ gulp.step('test-client-travis-mobile-run', function () { gulp.task('test-client-travis-mobile', gulp.series('build', 'test-client-travis-mobile-run')); gulp.step('test-client-legacy-travis-run', function () { - var saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; + const saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; saucelabsSettings.browsers = CLIENT_TESTS_DESKTOP_BROWSERS; @@ -380,7 +386,7 @@ gulp.step('test-client-legacy-travis-run', function () { gulp.task('test-client-legacy-travis', gulp.series('build', 'test-client-legacy-travis-run')); gulp.step('test-client-legacy-travis-mobile-run', function () { - var saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; + const saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; saucelabsSettings.browsers = CLIENT_TESTS_MOBILE_BROWSERS; @@ -396,7 +402,7 @@ gulp.task('generate-docs-readme', function (done) { } function generateDirectory (tocItems, level) { - var res = ''; + let res = ''; tocItems.forEach(function (item) { res += generateItem(item.name ? item.name : item.url, item.url, level); @@ -409,7 +415,7 @@ gulp.task('generate-docs-readme', function (done) { } function generateReadme (toc) { - var tocList = generateDirectory(toc, 0); + const tocList = generateDirectory(toc, 0); return '# Documentation\n\n> This is the documentation\'s development version. ' + 'The functionality described here may not be included in the current release version. ' + @@ -418,8 +424,8 @@ gulp.task('generate-docs-readme', function (done) { tocList; } - var toc = yaml.safeLoad(fs.readFileSync('docs/nav/nav-menu.yml', 'utf8')); - var readme = generateReadme(toc); + const toc = yaml.safeLoad(fs.readFileSync('docs/nav/nav-menu.yml', 'utf8')); + const readme = generateReadme(toc); fs.writeFileSync('docs/README.md', readme); @@ -430,7 +436,7 @@ gulp.task('lint-docs', function () { function lintFiles (files, config) { return new Promise(function (resolve, reject) { markdownlint({ files: files, config: config }, function (err, result) { - var lintErr = err || result && result.toString(); + const lintErr = err || result && result.toString(); if (lintErr) reject(lintErr); @@ -440,7 +446,7 @@ gulp.task('lint-docs', function () { }); } - var lintDocsAndExamples = globby([ + const lintDocsAndExamples = globby([ 'docs/articles/**/*.md', '!docs/articles/faq/**/*.md', '!docs/articles/documentation/recipes/**/*.md', @@ -449,20 +455,20 @@ gulp.task('lint-docs', function () { return lintFiles(files, require('./.md-lint/docs.json')); }); - var lintFaq = globby([ + const lintFaq = globby([ 'docs/articles/faq/**/*.md' ]).then(function (files) { return lintFiles(files, require('./.md-lint/faq.json')); }); - var lintRecipes = globby([ + const lintRecipes = globby([ 'docs/articles/documentation/recipes/**/*.md' ]).then(function (files) { return lintFiles(files, require('./.md-lint/recipes.json')); }); - var lintReadme = lintFiles('README.md', require('./.md-lint/readme.json')); - var lintChangelog = lintFiles('CHANGELOG.md', require('./.md-lint/changelog.json')); + const lintReadme = lintFiles('README.md', require('./.md-lint/readme.json')); + const lintChangelog = lintFiles('CHANGELOG.md', require('./.md-lint/changelog.json')); return Promise.all([lintDocsAndExamples, lintReadme, lintChangelog, lintRecipes, lintFaq]); }); @@ -511,7 +517,7 @@ gulp.step('prepare-website-content', gulp.series('clean-website', 'fetch-assets- gulp.step('prepare-website', gulp.parallel('lint-docs', 'prepare-website-content')); function buildWebsite (mode, cb) { - var options = mode ? { stdio: 'inherit', env: { JEKYLL_ENV: mode } } : { stdio: 'inherit' }; + const options = mode ? { stdio: 'inherit', env: { JEKYLL_ENV: mode } } : { stdio: 'inherit' }; spawn('jekyll', ['build', '--source', 'site/src/', '--destination', 'site/deploy'], options) .on('exit', cb); @@ -556,7 +562,7 @@ gulp.step('build-website-run', function (cb) { gulp.task('build-website', gulp.series('prepare-website', 'build-website-run')); gulp.task('serve-website', function (cb) { - var app = connect() + const app = connect() .use('/testcafe', serveStatic('site/deploy')); websiteServer = app.listen(8080, cb); @@ -569,8 +575,8 @@ gulp.step('preview-website-open', function () { gulp.task('preview-website', gulp.series('build-website-development', 'serve-website', 'preview-website-open')); gulp.step('test-website-run', function () { - var WebsiteTester = require('./test/website/test.js'); - var websiteTester = new WebsiteTester(); + const WebsiteTester = require('./test/website/test.js'); + const websiteTester = new WebsiteTester(); return websiteTester .checkLinks() @@ -708,7 +714,7 @@ function isDockerMachineExist (machineName) { } function startDocker () { - var dockerMachineName = process.env['DOCKER_MACHINE_NAME'] || 'default'; + const dockerMachineName = process.env['DOCKER_MACHINE_NAME'] || 'default'; if (!isDockerMachineExist(dockerMachineName)) childProcess.execSync('docker-machine create -d virtualbox ' + dockerMachineName); @@ -716,7 +722,7 @@ function startDocker () { if (!isDockerMachineRunning(dockerMachineName)) childProcess.execSync('docker-machine start ' + dockerMachineName); - var dockerEnv = getDockerEnv(dockerMachineName); + const dockerEnv = getDockerEnv(dockerMachineName); assignIn(process.env, dockerEnv); } @@ -732,7 +738,7 @@ gulp.task('docker-build', function (done) { } } - var imageId = childProcess + const imageId = childProcess .execSync('docker build -q -t testcafe -f docker/Dockerfile .', { env: process.env }) .toString() .replace(/\n/g, ''); diff --git a/package.json b/package.json index d89f113d..21edd426 100644 --- a/package.json +++ b/package.json @@ -150,6 +150,7 @@ "gulp-prompt": "^1.0.1", "gulp-qunit-harness": "^1.0.2", "gulp-rename": "^1.3.0", + "gulp-sourcemaps": "^2.6.4", "gulp-step": "^1.0.1", "gulp-uglify": "^3.0.0", "gulp-util": "^3.0.7", diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index e2b4ce9e..50ea9165 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -83,6 +83,7 @@ export default class CLIArgumentParser { .option('-q, --quarantine-mode', 'enable the quarantine mode') .option('-d, --debug-mode', 'execute test steps one by one pausing the test after each step') .option('-e, --skip-js-errors', 'make tests not fail when a JS error happens on a page') + .option('-u, --skip-uncaught-errors', 'ignore uncaught errors and unhandled promise rejections, which occur during test execution') .option('-t, --test ', 'run only tests with the specified name') .option('-T, --test-grep ', 'run only tests matching the specified pattern') .option('-f, --fixture ', 'run only fixtures with the specified name') diff --git a/src/compiler/index.js b/src/compiler/index.js index 2a0cebe8..56e1e89d 100644 --- a/src/compiler/index.js +++ b/src/compiler/index.js @@ -1,7 +1,6 @@ import Promise from 'pinkie'; import { flattenDeep as flatten, find, chunk, uniq } from 'lodash'; import stripBom from 'strip-bom'; -import sourceMapSupport from 'source-map-support'; import { Compiler as LegacyTestFileCompiler } from 'testcafe-legacy-api'; import hammerhead from 'testcafe-hammerhead'; import EsNextTestFileCompiler from './test-file/formats/es-next/compiler'; @@ -26,22 +25,12 @@ var testFileCompilers = [ export default class Compiler { constructor (sources) { this.sources = sources; - - Compiler._setupSourceMapsSupport(); } static getSupportedTestFileExtensions () { return uniq(testFileCompilers.map(c => c.getSupportedExtension())); } - static _setupSourceMapsSupport () { - sourceMapSupport.install({ - hookRequire: true, - handleUncaughtExceptions: false, - environment: 'node' - }); - } - async _compileTestFile (filename) { var code = null; diff --git a/src/errors/test-run/index.js b/src/errors/test-run/index.js index c114f196..d56cafc8 100644 --- a/src/errors/test-run/index.js +++ b/src/errors/test-run/index.js @@ -137,6 +137,22 @@ export class UncaughtErrorInCustomDOMPropertyCode extends TestRunErrorBase { } } +export class UnhandledPromiseRejectionError extends TestRunErrorBase { + constructor (err) { + super(TYPE.unhandledPromiseRejection); + + this.errMsg = String(err); + } +} + +export class UncaughtExceptionError extends TestRunErrorBase { + constructor (err) { + super(TYPE.uncaughtException); + + this.errMsg = String(err); + } +} + // Assertion errors //-------------------------------------------------------------------- diff --git a/src/errors/test-run/templates.js b/src/errors/test-run/templates.js index 7adb25f3..e09624bd 100644 --- a/src/errors/test-run/templates.js +++ b/src/errors/test-run/templates.js @@ -105,6 +105,18 @@ export default { Uncaught ${err.objType} "${escapeHtml(err.objStr)}" was thrown. Throw Error instead. `, { withoutCallsite: true }), + [TYPE.unhandledPromiseRejection]: err => markup(err, ` + Unhandled promise rejection: + + ${escapeHtml(err.errMsg)} + `, { withoutCallsite: true }), + + [TYPE.uncaughtException]: err => markup(err, ` + Uncaught exception: + + ${escapeHtml(err.errMsg)} + `, { withoutCallsite: true }), + [TYPE.actionOptionsTypeError]: err => markup(err, ` Action options is expected to be an object, null or undefined but it was ${err.actualType}. `), diff --git a/src/errors/test-run/type.js b/src/errors/test-run/type.js index e10a7ff6..ffff3506 100644 --- a/src/errors/test-run/type.js +++ b/src/errors/test-run/type.js @@ -9,6 +9,8 @@ export default { uncaughtNonErrorObjectInTestCode: 'uncaughtNonErrorObjectInTestCode', uncaughtErrorInClientFunctionCode: 'uncaughtErrorInClientFunctionCode', uncaughtErrorInCustomDOMPropertyCode: 'uncaughtErrorInCustomDOMPropertyCode', + unhandledPromiseRejection: 'unhandledPromiseRejection', + uncaughtException: 'uncaughtException', missingAwaitError: 'missingAwaitError', actionIntegerOptionError: 'actionIntegerOptionError', actionPositiveIntegerOptionError: 'actionPositiveIntegerOptionError', diff --git a/src/runner/index.js b/src/runner/index.js index 035b47ed..57918ea4 100644 --- a/src/runner/index.js +++ b/src/runner/index.js @@ -9,6 +9,7 @@ import Task from './task'; import { GeneralError } from '../errors/runtime'; import MESSAGE from '../errors/runtime/message'; import { assertType, is } from '../errors/runtime/type-assertions'; +import { addRunningTest, removeRunningTest, startHandlingTestErrors, stopHandlingTestErrors } from '../utils/handle-errors'; const DEFAULT_SELECTOR_TIMEOUT = 10000; const DEFAULT_ASSERTION_TIMEOUT = 3000; @@ -98,6 +99,15 @@ export default class Runner extends EventEmitter { var reporters = reporterPlugins.map(reporter => new Reporter(reporter.plugin, task, reporter.outStream)); var completionPromise = this._getTaskResult(task, browserSet, reporters[0], testedApp); + task.once('start', startHandlingTestErrors); + + if (!this.opts.skipUncaughtErrors) { + task.on('test-run-start', addRunningTest); + task.on('test-run-done', removeRunningTest); + } + + task.once('done', stopHandlingTestErrors); + var setCompleted = () => { completed = true; }; @@ -208,17 +218,17 @@ export default class Runner extends EventEmitter { return this; } - run ({ skipJsErrors, disablePageReloads, quarantineMode, debugMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed = 1, debugOnFail } = {}) { - this.opts.skipJsErrors = !!skipJsErrors; - this.opts.disablePageReloads = !!disablePageReloads; - this.opts.quarantineMode = !!quarantineMode; - this.opts.debugMode = !!debugMode; - this.opts.debugOnFail = !!debugOnFail; - this.opts.selectorTimeout = selectorTimeout === void 0 ? DEFAULT_SELECTOR_TIMEOUT : selectorTimeout; - this.opts.assertionTimeout = assertionTimeout === void 0 ? DEFAULT_ASSERTION_TIMEOUT : assertionTimeout; - this.opts.pageLoadTimeout = pageLoadTimeout === void 0 ? DEFAULT_PAGE_LOAD_TIMEOUT : pageLoadTimeout; - - this.opts.speed = speed; + run ({ skipJsErrors, disablePageReloads, quarantineMode, debugMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed = 1, debugOnFail, skipUncaughtErrors } = {}) { + this.opts.skipJsErrors = !!skipJsErrors; + this.opts.disablePageReloads = !!disablePageReloads; + this.opts.quarantineMode = !!quarantineMode; + this.opts.debugMode = !!debugMode; + this.opts.debugOnFail = !!debugOnFail; + this.opts.selectorTimeout = selectorTimeout === void 0 ? DEFAULT_SELECTOR_TIMEOUT : selectorTimeout; + this.opts.assertionTimeout = assertionTimeout === void 0 ? DEFAULT_ASSERTION_TIMEOUT : assertionTimeout; + this.opts.pageLoadTimeout = pageLoadTimeout === void 0 ? DEFAULT_PAGE_LOAD_TIMEOUT : pageLoadTimeout; + this.opts.speed = speed; + this.opts.skipUncaughtErrors = !!skipUncaughtErrors; var runTaskPromise = Promise.resolve() .then(() => { diff --git a/src/test-run/index.js b/src/test-run/index.js index a895f97a..247ee5be 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -376,7 +376,8 @@ export default class TestRun extends EventEmitter { } _rejectCurrentDriverTask (err) { - err.callsite = err.callsite || this.driverTaskQueue[0].callsite; + err.callsite = err.callsite || this.driverTaskQueue[0].callsite; + err.isRejectedDriverTask = true; this.currentDriverTask.reject(err); this._removeAllNonServiceTasks(); diff --git a/src/testcafe.js b/src/testcafe.js index d49c5917..514b234b 100644 --- a/src/testcafe.js +++ b/src/testcafe.js @@ -1,4 +1,5 @@ import Promise from 'pinkie'; +import sourceMapSupport from 'source-map-support'; import { readSync as read } from 'read-file-relative'; import { Proxy } from 'testcafe-hammerhead'; import { CLIENT_RUNNER_SCRIPT as LEGACY_RUNNER_SCRIPT } from 'testcafe-legacy-api'; @@ -6,6 +7,7 @@ import BrowserConnectionGateway from './browser/connection/gateway'; import BrowserConnection from './browser/connection'; import browserProviderPool from './browser/provider/pool'; import Runner from './runner'; +import { registerErrorHandlers } from './utils/handle-errors'; // Const const UI_STYLE = read('./client/ui/styles.css'); @@ -14,6 +16,10 @@ const FAVICON = read('./client/ui/favicon.ico', true); export default class TestCafe { constructor (hostname, port1, port2, sslOptions, developmentMode) { + this._setupSourceMapsSupport(); + + registerErrorHandlers(); + this.closed = false; this.proxy = new Proxy(hostname, port1, port2, sslOptions, developmentMode); this.browserConnectionGateway = new BrowserConnectionGateway(this.proxy); @@ -47,6 +53,13 @@ export default class TestCafe { }); } + _setupSourceMapsSupport () { + sourceMapSupport.install({ + hookRequire: true, + handleUncaughtExceptions: false, + environment: 'node' + }); + } // API async createBrowserConnection () { diff --git a/src/utils/handle-errors.js b/src/utils/handle-errors.js new file mode 100644 index 00000000..8676e751 --- /dev/null +++ b/src/utils/handle-errors.js @@ -0,0 +1,70 @@ +import { UnhandledPromiseRejectionError, UncaughtExceptionError } from '../errors/test-run'; + +const runningTests = {}; +let handlingTestErrors = false; + +function handleError (ErrorCtor, message) { + if (handlingTestErrors) { + Object.values(runningTests).forEach(testRun => { + testRun.addError(new ErrorCtor(message)); + + removeRunningTest(testRun); + }); + } + else { + /* eslint-disable no-process-exit */ + /* eslint-disable no-console */ + console.log(message); + + setTimeout(() => process.exit(1), 0); + /* eslint-enable no-process-exit */ + /* eslint-enable no-console */ + } +} + +function formatUnhandledRejectionReason (reason) { + const reasonType = typeof reason; + const isPrimitiveType = reasonType !== 'object' && reasonType !== 'function'; + + if (isPrimitiveType) + return String(reason); + + if (reason instanceof Error) + return reason.stack; + + return Object.prototype.toString.call(reason); +} + +function onUnhandledRejection (reason) { + if (reason && reason.isRejectedDriverTask) + return; + + const message = formatUnhandledRejectionReason(reason); + + handleError(UnhandledPromiseRejectionError, message); +} + +function onUncaughtException (err) { + handleError(UncaughtExceptionError, err.stack); +} + +export function registerErrorHandlers () { + process.on('unhandledRejection', onUnhandledRejection); + process.on('uncaughtException', onUncaughtException); +} + +export function addRunningTest (testRun) { + runningTests[testRun.id] = testRun; +} + +export function removeRunningTest (testRun) { + delete runningTests[testRun.id]; +} + +export function startHandlingTestErrors () { + handlingTestErrors = true; +} + +export function stopHandlingTestErrors () { + handlingTestErrors = false; +} diff --git a/test/functional/fixtures/regression/gh-2546/pages/index.html b/test/functional/fixtures/regression/gh-2546/pages/index.html new file mode 100644 index 00000000..0217bc67 --- /dev/null +++ b/test/functional/fixtures/regression/gh-2546/pages/index.html @@ -0,0 +1,9 @@ + + + + + gh-2546 + + + + \ No newline at end of file diff --git a/test/functional/fixtures/regression/gh-2546/test.js b/test/functional/fixtures/regression/gh-2546/test.js new file mode 100644 index 00000000..57902b0d --- /dev/null +++ b/test/functional/fixtures/regression/gh-2546/test.js @@ -0,0 +1,82 @@ +const path = require('path'); +const expect = require('chai').expect; +const { exec } = require('child_process'); + +describe('[Regression](GH-2546)', function () { + this.timeout(60000); + + it('Should fail on uncaught promise rejection when skipUncaughtErrors is false', function () { + return runTests('./testcafe-fixtures/index.js', 'Unhandled promise rejection', { shouldFail: true }) + .catch(function (errs) { + const allErrors = []; + + if (!Array.isArray(errs)) { + const browsers = Object.keys(errs); + + browsers.forEach(browser => { + allErrors.push(errs[browser][0]); + }); + } + else + allErrors.push(errs[0]); + + expect(allErrors.length).gte(1); + + allErrors.forEach(function (err) { + expect(err).contains('Unhandled promise rejection'); + }); + }); + }); + + it('Should not fail on uncaught exception when skipUncaughtErrors is true', function () { + let unhandledRejectionRaiseCount = 0; + + const listener = err => { + unhandledRejectionRaiseCount++; + + expect(err.message).eql('reject'); + }; + + process.on('unhandledRejection', listener); + + return runTests('./testcafe-fixtures/index.js', 'Unhandled promise rejection', { skipUncaughtErrors: true }) + .then(() => { + process.removeListener('unhandledRejection', listener); + + expect(unhandledRejectionRaiseCount).gte(1); + }); + }); + + it('Should fail on uncaught exception when skipUncaughtErrors is false', function () { + const testcafePath = path.resolve('bin/testcafe'); + const testFilePath = path.resolve('test/functional/fixtures/regression/gh-2546/testcafe-fixtures/uncaughtException.js'); + const browsers = '"chrome:headless --no-sandbox"'; + const command = `node ${testcafePath} ${browsers} ${testFilePath}`; + + return new Promise(resolve => { + exec(command, (error, stdout) => { + resolve({ error, stdout }); + }); + }).then(value => { + expect(value.stdout).contains('Uncaught exception'); + expect(value.stdout).contains('unhandled'); + expect(value.error).is.not.null; + }); + }); + + it('Should not fail on uncaught promise rejection when skipUncaughtErrors is true', function () { + const testcafePath = path.resolve('bin/testcafe'); + const testFilePath = path.resolve('test/functional/fixtures/regression/gh-2546/testcafe-fixtures/uncaughtException.js'); + const browsers = '"chrome:headless --no-sandbox"'; + const args = '--skip-uncaught-errors'; + const command = `node ${testcafePath} ${browsers} ${testFilePath} ${args}`; + + return new Promise(resolve => { + exec(command, (error, stdout) => { + resolve({ error, stdout }); + }); + }).then(value => { + expect(value.error).is.null; + }); + }); +}); diff --git a/test/functional/fixtures/regression/gh-2546/testcafe-fixtures/index.js b/test/functional/fixtures/regression/gh-2546/testcafe-fixtures/index.js new file mode 100644 index 00000000..390b8c6b --- /dev/null +++ b/test/functional/fixtures/regression/gh-2546/testcafe-fixtures/index.js @@ -0,0 +1,12 @@ +fixture `Should fail on unhandled promise rejection` + .page `http://localhost:3000/fixtures/regression/gh-2546/pages/index.html`; + +test('Unhandled promise rejection', async t => { + await t.wait(0); + + /* eslint-disable no-new */ + new Promise((resolve, reject) => { + reject(new Error('reject')); + }); + /* eslint-enable no-new */ +}); diff --git a/test/functional/fixtures/regression/gh-2546/testcafe-fixtures/uncaughtException.js b/test/functional/fixtures/regression/gh-2546/testcafe-fixtures/uncaughtException.js new file mode 100644 index 00000000..451eeb71 --- /dev/null +++ b/test/functional/fixtures/regression/gh-2546/testcafe-fixtures/uncaughtException.js @@ -0,0 +1,8 @@ +fixture('Fixture3') + .page `https://example.com`; + +test('test', async () => { + setTimeout(function () { + throw new Error('unhandled'); + }, 0); +}); diff --git a/test/functional/setup.js b/test/functional/setup.js index 9cbf4bcf..350c8962 100644 --- a/test/functional/setup.js +++ b/test/functional/setup.js @@ -178,6 +178,7 @@ before(function () { const externalProxyHost = opts && opts.useProxy; const proxyBypass = opts && opts.proxyBypass; const customReporters = opts && opts.reporters; + const skipUncaughtErrors = opts && opts.skipUncaughtErrors; var actualBrowsers = browsersInfo.filter(function (browserInfo) { var { alias, userAgent } = browserInfo.settings; @@ -230,7 +231,7 @@ before(function () { .src(fixturePath) .screenshots(screenshotPath, screenshotsOnFails, screenshotPathPattern) .startApp(appCommand, appInitDelay) - .run({ skipJsErrors, disablePageReloads, quarantineMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed }) + .run({ skipJsErrors, disablePageReloads, quarantineMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed, skipUncaughtErrors: skipUncaughtErrors }) .then(function () { if (customReporters) return; diff --git a/test/server/cli-argument-parser-test.js b/test/server/cli-argument-parser-test.js index 76a69008..bc024334 100644 --- a/test/server/cli-argument-parser-test.js +++ b/test/server/cli-argument-parser-test.js @@ -390,6 +390,7 @@ describe('CLI argument parser', function () { { long: '--dev' }, { long: '--ssl' }, { long: '--qr-code' }, + { long: '--skip-uncaught-errors' }, { long: '--color' }, { long: '--no-color' } ]; diff --git a/test/server/compiler-test.js b/test/server/compiler-test.js index 247c7cf5..5f8a3cf5 100644 --- a/test/server/compiler-test.js +++ b/test/server/compiler-test.js @@ -10,8 +10,14 @@ const assertError = require('./helpers/assert-error').assertError; const compile = require('./helpers/compile'); const { exec } = require('child_process'); +require('source-map-support').install(); + describe('Compiler', function () { - var testRunMock = { id: 'yo' }; + const testRunMock = { id: 'yo' }; + + const tsCompilerPath = path.resolve('src/compiler/test-file/formats/typescript/compiler.js'); + const apiBasedPath = path.resolve('src/compiler/test-file/api-based.js'); + const esNextCompilerPath = path.resolve('src/compiler/test-file/formats/es-next/compiler.js'); this.timeout(20000); @@ -21,7 +27,7 @@ describe('Compiler', function () { } it('Should compile mixed content', function () { - var sources = [ + const sources = [ 'test/server/data/test-suites/mixed-content/testfile.js', 'test/server/data/test-suites/mixed-content/legacy.test.js', 'test/server/data/test-suites/mixed-content/non-testfile.js' @@ -42,17 +48,17 @@ describe('Compiler', function () { describe('ES-next', function () { it('Should compile test files and their dependencies', function () { - var sources = [ + const sources = [ 'test/server/data/test-suites/basic/testfile1.js', 'test/server/data/test-suites/basic/testfile2.js' ]; return compile(sources) .then(function (compiled) { - var testfile1 = path.resolve('test/server/data/test-suites/basic/testfile1.js'); - var testfile2 = path.resolve('test/server/data/test-suites/basic/testfile2.js'); - var tests = compiled.tests; - var fixtures = compiled.fixtures; + const testfile1 = path.resolve('test/server/data/test-suites/basic/testfile1.js'); + const testfile2 = path.resolve('test/server/data/test-suites/basic/testfile2.js'); + const tests = compiled.tests; + const fixtures = compiled.fixtures; expect(tests.length).eql(4); expect(fixtures.length).eql(3); @@ -135,17 +141,17 @@ describe('Compiler', function () { describe('TypeScript', function () { it('Should compile test files and their dependencies', function () { - var sources = [ + const sources = [ 'test/server/data/test-suites/typescript-basic/testfile1.ts', 'test/server/data/test-suites/typescript-basic/testfile2.ts' ]; return compile(sources) .then(function (compiled) { - var testfile1 = path.resolve('test/server/data/test-suites/typescript-basic/testfile1.ts'); - var testfile2 = path.resolve('test/server/data/test-suites/typescript-basic/testfile2.ts'); - var tests = compiled.tests; - var fixtures = compiled.fixtures; + const testfile1 = path.resolve('test/server/data/test-suites/typescript-basic/testfile1.ts'); + const testfile2 = path.resolve('test/server/data/test-suites/typescript-basic/testfile2.ts'); + const tests = compiled.tests; + const fixtures = compiled.fixtures; expect(tests.length).eql(4); expect(fixtures.length).eql(3); @@ -199,10 +205,10 @@ describe('Compiler', function () { }); it('Should complile ts-definitions successfully with the `--strict` option enabled', function () { - var tscPath = path.resolve('node_modules/typescript/bin/tsc'); - var defsPath = path.resolve('ts-defs/index.d.ts'); - var args = '--strict'; - var command = `node ${tscPath} ${defsPath} ${args}`; + const tscPath = path.resolve('node_modules/typescript/bin/tsc'); + const defsPath = path.resolve('ts-defs/index.d.ts'); + const args = '--strict'; + const command = `node ${tscPath} ${defsPath} ${args}`; return new Promise(resolve => { exec(command, (error, stdout) => { @@ -301,13 +307,13 @@ describe('Compiler', function () { describe('RAW file', function () { it('Should compile test files', function () { - var sources = ['test/server/data/test-suites/raw/test.testcafe']; + const sources = ['test/server/data/test-suites/raw/test.testcafe']; return compile(sources) .then(function (compiled) { - var testfile = path.resolve('test/server/data/test-suites/raw/test.testcafe'); - var tests = compiled.tests; - var fixtures = compiled.fixtures; + const testfile = path.resolve('test/server/data/test-suites/raw/test.testcafe'); + const tests = compiled.tests; + const fixtures = compiled.fixtures; expect(tests.length).eql(3); expect(fixtures.length).eql(2); @@ -332,8 +338,8 @@ describe('Compiler', function () { }); it('Should raise an error if it cannot parse a raw file', function () { - var testfile1 = path.resolve('test/server/data/test-suites/raw/invalid.testcafe'); - var testfile2 = path.resolve('test/server/data/test-suites/raw/invalid2.testcafe'); + const testfile1 = path.resolve('test/server/data/test-suites/raw/invalid.testcafe'); + const testfile2 = path.resolve('test/server/data/test-suites/raw/invalid2.testcafe'); return compile(testfile1) .then(function () { @@ -357,7 +363,7 @@ describe('Compiler', function () { }); describe('test.fn()', function () { - var TestRunMock = function (expectedError) { + const TestRunMock = function (expectedError) { this.id = 'PPBqWA9'; this.commands = []; this.expectedError = expectedError; @@ -370,9 +376,9 @@ describe('Compiler', function () { }; it('Should be resolved if the test passed', function () { - var sources = ['test/server/data/test-suites/raw/test.testcafe']; - var test = null; - var testRun = new TestRunMock(); + const sources = ['test/server/data/test-suites/raw/test.testcafe']; + let test = null; + const testRun = new TestRunMock(); return compile(sources) .then(function (compiled) { @@ -386,9 +392,9 @@ describe('Compiler', function () { }); it('Should be rejected if the test failed', function () { - var sources = ['test/server/data/test-suites/raw/test.testcafe']; - var expectedError = 'test-error'; - var testRun = new TestRunMock(expectedError); + const sources = ['test/server/data/test-suites/raw/test.testcafe']; + const expectedError = 'test-error'; + const testRun = new TestRunMock(expectedError); return compile(sources) .then(function (compiled) { @@ -420,9 +426,9 @@ describe('Compiler', function () { } function testClientFnCompilation (testName) { - var testDir = 'test/server/data/client-fn-compilation/' + testName; - var src = testDir + '/testfile.js'; - var expected = getExpected(testDir); + const testDir = 'test/server/data/client-fn-compilation/' + testName; + const src = testDir + '/testfile.js'; + const expected = getExpected(testDir); return compile(src) .then(function (compiled) { @@ -474,8 +480,15 @@ describe('Compiler', function () { }); it('Should raise an error if test dependency has a syntax error', function () { - var testfile = path.resolve('test/server/data/test-suites/syntax-error-in-dep/testfile.js'); - var dep = posixResolve('test/server/data/test-suites/syntax-error-in-dep/dep.js'); + const testfile = path.resolve('test/server/data/test-suites/syntax-error-in-dep/testfile.js'); + const dep = posixResolve('test/server/data/test-suites/syntax-error-in-dep/dep.js'); + + const stack = [ + esNextCompilerPath, + esNextCompilerPath, + apiBasedPath, + testfile + ]; return compile(testfile) .then(function () { @@ -483,7 +496,7 @@ describe('Compiler', function () { }) .catch(function (err) { assertError(err, { - stackTop: testfile, + stackTop: stack, message: 'Cannot prepare tests due to an error.\n\n' + 'SyntaxError: ' + dep + ': Unexpected token, expected { (1:7)' @@ -492,8 +505,14 @@ describe('Compiler', function () { }); it("Should raise an error if dependency can't require a module", function () { - var testfile = path.resolve('test/server/data/test-suites/require-error-in-dep/testfile.js'); - var dep = path.resolve('test/server/data/test-suites/require-error-in-dep/dep.js'); + const testfile = path.resolve('test/server/data/test-suites/require-error-in-dep/testfile.js'); + const dep = path.resolve('test/server/data/test-suites/require-error-in-dep/dep.js'); + + const stack = [ + dep, + apiBasedPath, + testfile + ]; return compile(testfile) .then(function () { @@ -501,10 +520,7 @@ describe('Compiler', function () { }) .catch(function (err) { assertError(err, { - stackTop: [ - dep, - testfile - ], + stackTop: stack, message: 'Cannot prepare tests due to an error.\n\n' + "Error: Cannot find module './yo'" @@ -513,8 +529,8 @@ describe('Compiler', function () { }); it('Should raise an error if dependency throws runtime error', function () { - var testfile = path.resolve('test/server/data/test-suites/runtime-error-in-dep/testfile.js'); - var dep = path.resolve('test/server/data/test-suites/runtime-error-in-dep/dep.js'); + const testfile = path.resolve('test/server/data/test-suites/runtime-error-in-dep/testfile.js'); + const dep = path.resolve('test/server/data/test-suites/runtime-error-in-dep/dep.js'); return compile(testfile) .then(function () { @@ -524,6 +540,7 @@ describe('Compiler', function () { assertError(err, { stackTop: [ dep, + apiBasedPath, testfile ], @@ -534,7 +551,7 @@ describe('Compiler', function () { }); it("Should raise an error if test file can't require a module", function () { - var testfile = path.resolve('test/server/data/test-suites/require-error-in-testfile/testfile.js'); + const testfile = path.resolve('test/server/data/test-suites/require-error-in-testfile/testfile.js'); return compile(testfile) .then(function () { @@ -551,7 +568,7 @@ describe('Compiler', function () { }); it('Should raise an error if test file throws runtime error', function () { - var testfile = path.resolve('test/server/data/test-suites/runtime-error-in-testfile/testfile.js'); + const testfile = path.resolve('test/server/data/test-suites/runtime-error-in-testfile/testfile.js'); return compile(testfile) .then(function () { @@ -568,7 +585,12 @@ describe('Compiler', function () { }); it('Should raise an error if test file has a syntax error', function () { - var testfile = posixResolve('test/server/data/test-suites/syntax-error-in-testfile/testfile.js'); + const testfile = posixResolve('test/server/data/test-suites/syntax-error-in-testfile/testfile.js'); + + const stack = [ + esNextCompilerPath, + apiBasedPath, + ]; return compile(testfile) .then(function () { @@ -576,7 +598,7 @@ describe('Compiler', function () { }) .catch(function (err) { assertError(err, { - stackTop: null, + stackTop: stack, message: 'Cannot prepare tests due to an error.\n\n' + 'SyntaxError: ' + testfile + ': Unexpected token, expected { (1:7)' @@ -585,18 +607,24 @@ describe('Compiler', function () { }); it('Should raise an error if test file has Flow syntax without a marker comment', function () { - var testfiles = [ + const testfiles = [ posixResolve('test/server/data/test-suites/flow-type-declarations/no-flow-marker.js'), posixResolve('test/server/data/test-suites/flow-type-declarations/flower-marker.js') ]; + const stack = [ + esNextCompilerPath, + apiBasedPath, + ]; + return compile(testfiles[0]) .then(function () { throw new Error('Promise rejection expected'); }) .catch(function (err) { assertError(err, { - stackTop: null, + stackTop: stack, + message: 'Cannot prepare tests due to an error.\n\n' + 'SyntaxError: ' + testfiles[0] + ': Unexpected token, expected ; (1:8)' @@ -609,7 +637,7 @@ describe('Compiler', function () { }) .catch(function (err) { assertError(err, { - stackTop: null, + stackTop: stack, message: 'Cannot prepare tests due to an error.\n\n' + 'SyntaxError: ' + testfiles[1] + ': Unexpected token, expected ; (2:8)' @@ -618,7 +646,8 @@ describe('Compiler', function () { }); it('Should raise an error if test file has a TypeScript error', function () { - var testfile = posixResolve('test/server/data/test-suites/typescript-compile-errors/testfile.ts'); + const testfile = posixResolve('test/server/data/test-suites/typescript-compile-errors/testfile.ts'); + const stack = tsCompilerPath; return compile(testfile) .then(function () { @@ -626,7 +655,7 @@ describe('Compiler', function () { }) .catch(function (err) { assertError(err, { - stackTop: null, + stackTop: stack, message: 'Cannot prepare tests due to an error.\n\n' + 'Error: TypeScript compilation failed.\n' + @@ -650,7 +679,7 @@ describe('Compiler', function () { throw 'Promise rejection expected'; }) .catch(function (errList) { - var callsite = errList.items[0].callsite.renderSync({ renderer: renderers.noColor }); + const callsite = errList.items[0].callsite.renderSync({ renderer: renderers.noColor }); expect(callsite).contains(' > 19 | .method1()\n'); }); @@ -672,9 +701,9 @@ describe('Compiler', function () { throw 'Promise rejection expected'; }) .catch(function (errList) { - var stackTraceLimit = 200; - var err = errList.items[0]; - var stack = err.callsite.stackFrames.filter(createStackFilter(stackTraceLimit)); + const stackTraceLimit = 200; + const err = errList.items[0]; + const stack = err.callsite.stackFrames.filter(createStackFilter(stackTraceLimit)); expect(stack.length).eql(3); expect(stack[0].source).to.have.string('helper.js'); diff --git a/test/server/data/expected-test-run-errors/uncaught-exception-error b/test/server/data/expected-test-run-errors/uncaught-exception-error new file mode 100644 index 00000000..f8214e72 --- /dev/null +++ b/test/server/data/expected-test-run-errors/uncaught-exception-error @@ -0,0 +1,7 @@ +Uncaught exception: + +Hey ya! + +Browser: Chrome 15.0.874 / Mac OS X 10.8.1 +Screenshot: /unix/path/with/ + diff --git a/test/server/data/expected-test-run-errors/unhandled-promise-rejection-error b/test/server/data/expected-test-run-errors/unhandled-promise-rejection-error new file mode 100644 index 00000000..82958a0a --- /dev/null +++ b/test/server/data/expected-test-run-errors/unhandled-promise-rejection-error @@ -0,0 +1,7 @@ +Unhandled promise rejection: + +Hey ya! + +Browser: Chrome 15.0.874 / Mac OS X 10.8.1 +Screenshot: /unix/path/with/ + diff --git a/test/server/error-handle-test.js b/test/server/error-handle-test.js new file mode 100644 index 00000000..764adec3 --- /dev/null +++ b/test/server/error-handle-test.js @@ -0,0 +1,72 @@ +const Promise = require('pinkie'); +const expect = require('chai').expect; +const createTestCafe = require('../../lib/'); +const types = require('../../lib/errors/test-run/type'); +const handleErrors = require('../../lib/utils/handle-errors'); + + +class TestRunMock { + constructor (id, reason) { + this.id = id; + this.errors = []; + this.reason = reason; + } + + addError (err) { + this.errors.push(err); + } +} + +describe('Global error handlers', () => { + it('format UnhandledPromiseRejection reason', () => { + handleErrors.registerErrorHandlers(); + handleErrors.startHandlingTestErrors(); + + const reasons = [new Error('test'), null, void 0, 1, 'string message', true, { a: 1 }]; + const testRunMocks = reasons.map((reason, index) => new TestRunMock(index, reason)); + const expectedErrors = ['Error: test', '[object Null]', 'undefined', '1', 'string message', 'true', '[object Object]']; + + testRunMocks.forEach(testRun => { + handleErrors.addRunningTest(testRun); + + process.emit('unhandledRejection', testRun.reason); + }); + + const actualErrors = testRunMocks.map(testRun => testRun.errors[0].errMsg); + + actualErrors[0] = actualErrors[0].substr(0, expectedErrors[0].length); + + expect(actualErrors).eql(expectedErrors); + }); + + it('Should add error to testRun on UnhandledPromiseRejection', () => { + var testCafe = null; + var unhandledRejectionRaised = false; + var testRunMock = new TestRunMock(1); + + return createTestCafe('127.0.0.1', 1335, 1336) + .then(tc => { + testCafe = tc; + }) + .then(() => { + process.on('unhandledRejection', function () { + unhandledRejectionRaised = true; + }); + + handleErrors.addRunningTest(testRunMock); + handleErrors.startHandlingTestErrors(); + + /* eslint-disable no-new */ + new Promise((resolve, reject) => { + reject(new Error()); + }); + /* eslint-enable no-new */ + + return testCafe.close(); + }) + .then(() => { + expect(unhandledRejectionRaised).eql(true); + expect(testRunMock.errors[0].type).eql(types.unhandledPromiseRejection); + }); + }); +}); diff --git a/test/server/test-run-error-formatting-test.js b/test/server/test-run-error-formatting-test.js index 095aaa72..855a43b9 100644 --- a/test/server/test-run-error-formatting-test.js +++ b/test/server/test-run-error-formatting-test.js @@ -1,77 +1,79 @@ -var expect = require('chai').expect; -var read = require('read-file-relative').readSync; -var remove = require('lodash').pull; -var escapeRe = require('lodash').escapeRegExp; -var ReporterPluginHost = require('../../lib/reporter/plugin-host'); -var TEST_RUN_PHASE = require('../../lib/test-run/phase'); -var TYPE = require('../../lib/errors/test-run/type'); -var TestRunErrorFormattableAdapter = require('../../lib/errors/test-run/formattable-adapter'); -var testCallsite = require('./data/test-callsite'); -var AssertionExecutableArgumentError = require('../../lib/errors/test-run').AssertionExecutableArgumentError; -var AssertionUnawaitedPromiseError = require('../../lib/errors/test-run').AssertionUnawaitedPromiseError; -var ActionIntegerOptionError = require('../../lib/errors/test-run').ActionIntegerOptionError; -var ActionPositiveIntegerOptionError = require('../../lib/errors/test-run').ActionPositiveIntegerOptionError; -var ActionIntegerArgumentError = require('../../lib/errors/test-run').ActionIntegerArgumentError; -var ActionPositiveIntegerArgumentError = require('../../lib/errors/test-run').ActionPositiveIntegerArgumentError; -var ActionBooleanOptionError = require('../../lib/errors/test-run').ActionBooleanOptionError; +const expect = require('chai').expect; +const read = require('read-file-relative').readSync; +const remove = require('lodash').pull; +const escapeRe = require('lodash').escapeRegExp; +const ReporterPluginHost = require('../../lib/reporter/plugin-host'); +const TEST_RUN_PHASE = require('../../lib/test-run/phase'); +const TYPE = require('../../lib/errors/test-run/type'); +const TestRunErrorFormattableAdapter = require('../../lib/errors/test-run/formattable-adapter'); +const testCallsite = require('./data/test-callsite'); +const AssertionExecutableArgumentError = require('../../lib/errors/test-run').AssertionExecutableArgumentError; +const AssertionUnawaitedPromiseError = require('../../lib/errors/test-run').AssertionUnawaitedPromiseError; +const ActionIntegerOptionError = require('../../lib/errors/test-run').ActionIntegerOptionError; +const ActionPositiveIntegerOptionError = require('../../lib/errors/test-run').ActionPositiveIntegerOptionError; +const ActionIntegerArgumentError = require('../../lib/errors/test-run').ActionIntegerArgumentError; +const ActionPositiveIntegerArgumentError = require('../../lib/errors/test-run').ActionPositiveIntegerArgumentError; +const ActionBooleanOptionError = require('../../lib/errors/test-run').ActionBooleanOptionError; var ActionBooleanArgumentError = require('../../lib/errors/test-run').ActionBooleanArgumentError; -var ActionSpeedOptionError = require('../../lib/errors/test-run').ActionSpeedOptionError; -var ActionSelectorError = require('../../lib/errors/test-run').ActionSelectorError; -var ActionOptionsTypeError = require('../../lib/errors/test-run').ActionOptionsTypeError; -var ActionStringArgumentError = require('../../lib/errors/test-run').ActionStringArgumentError; -var ActionNullableStringArgumentError = require('../../lib/errors/test-run').ActionNullableStringArgumentError; -var ActionStringOrStringArrayArgumentError = require('../../lib/errors/test-run').ActionStringOrStringArrayArgumentError; -var ActionStringArrayElementError = require('../../lib/errors/test-run').ActionStringArrayElementError; -var PageLoadError = require('../../lib/errors/test-run').PageLoadError; -var UncaughtErrorOnPage = require('../../lib/errors/test-run').UncaughtErrorOnPage; -var UncaughtErrorInTestCode = require('../../lib/errors/test-run').UncaughtErrorInTestCode; -var UncaughtErrorInClientFunctionCode = require('../../lib/errors/test-run').UncaughtErrorInClientFunctionCode; -var UncaughtNonErrorObjectInTestCode = require('../../lib/errors/test-run').UncaughtNonErrorObjectInTestCode; -var UncaughtErrorInCustomDOMPropertyCode = require('../../lib/errors/test-run').UncaughtErrorInCustomDOMPropertyCode; -var ActionElementNotFoundError = require('../../lib/errors/test-run').ActionElementNotFoundError; -var ActionElementIsInvisibleError = require('../../lib/errors/test-run').ActionElementIsInvisibleError; -var ActionSelectorMatchesWrongNodeTypeError = require('../../lib/errors/test-run').ActionSelectorMatchesWrongNodeTypeError; -var ActionAdditionalElementNotFoundError = require('../../lib/errors/test-run').ActionAdditionalElementNotFoundError; -var ActionAdditionalElementIsInvisibleError = require('../../lib/errors/test-run').ActionAdditionalElementIsInvisibleError; -var ActionAdditionalSelectorMatchesWrongNodeTypeError = require('../../lib/errors/test-run').ActionAdditionalSelectorMatchesWrongNodeTypeError; -var ActionElementNonEditableError = require('../../lib/errors/test-run').ActionElementNonEditableError; -var ActionElementNonContentEditableError = require('../../lib/errors/test-run').ActionElementNonContentEditableError; -var ActionRootContainerNotFoundError = require('../../lib/errors/test-run').ActionRootContainerNotFoundError; -var ActionElementNotTextAreaError = require('../../lib/errors/test-run').ActionElementNotTextAreaError; -var ActionIncorrectKeysError = require('../../lib/errors/test-run').ActionIncorrectKeysError; -var ActionCanNotFindFileToUploadError = require('../../lib/errors/test-run').ActionCanNotFindFileToUploadError; -var ActionElementIsNotFileInputError = require('../../lib/errors/test-run').ActionElementIsNotFileInputError; -var ActionUnsupportedDeviceTypeError = require('../../lib/errors/test-run').ActionUnsupportedDeviceTypeError; -var ActionInvalidScrollTargetError = require('../../lib/errors/test-run').ActionInvalidScrollTargetError; -var ClientFunctionExecutionInterruptionError = require('../../lib/errors/test-run').ClientFunctionExecutionInterruptionError; -var ActionElementNotIframeError = require('../../lib/errors/test-run').ActionElementNotIframeError; -var ActionIframeIsNotLoadedError = require('../../lib/errors/test-run').ActionIframeIsNotLoadedError; -var CurrentIframeIsNotLoadedError = require('../../lib/errors/test-run').CurrentIframeIsNotLoadedError; -var CurrentIframeNotFoundError = require('../../lib/errors/test-run').CurrentIframeNotFoundError; -var CurrentIframeIsInvisibleError = require('../../lib/errors/test-run').CurrentIframeIsInvisibleError; -var MissingAwaitError = require('../../lib/errors/test-run').MissingAwaitError; -var ExternalAssertionLibraryError = require('../../lib/errors/test-run').ExternalAssertionLibraryError; -var DomNodeClientFunctionResultError = require('../../lib/errors/test-run').DomNodeClientFunctionResultError; -var InvalidSelectorResultError = require('../../lib/errors/test-run').InvalidSelectorResultError; -var NativeDialogNotHandledError = require('../../lib/errors/test-run').NativeDialogNotHandledError; -var UncaughtErrorInNativeDialogHandler = require('../../lib/errors/test-run').UncaughtErrorInNativeDialogHandler; -var SetNativeDialogHandlerCodeWrongTypeError = require('../../lib/errors/test-run').SetNativeDialogHandlerCodeWrongTypeError; -var CantObtainInfoForElementSpecifiedBySelectorError = require('../../lib/errors/test-run').CantObtainInfoForElementSpecifiedBySelectorError; -var WindowDimensionsOverflowError = require('../../lib/errors/test-run').WindowDimensionsOverflowError; -var InvalidElementScreenshotDimensionsError = require('../../lib/errors/test-run').InvalidElementScreenshotDimensionsError; -var SetTestSpeedArgumentError = require('../../lib/errors/test-run').SetTestSpeedArgumentError; -var RoleSwitchInRoleInitializerError = require('../../lib/errors/test-run').RoleSwitchInRoleInitializerError; -var ActionRoleArgumentError = require('../../lib/errors/test-run').ActionRoleArgumentError; - -var TEST_FILE_STACK_ENTRY_RE = new RegExp('\\s*\\n?\\(' + escapeRe(require.resolve('./data/test-callsite')), 'g'); - -var untestedErrorTypes = Object.keys(TYPE).map(function (key) { +const ActionSpeedOptionError = require('../../lib/errors/test-run').ActionSpeedOptionError; +const ActionSelectorError = require('../../lib/errors/test-run').ActionSelectorError; +const ActionOptionsTypeError = require('../../lib/errors/test-run').ActionOptionsTypeError; +const ActionStringArgumentError = require('../../lib/errors/test-run').ActionStringArgumentError; +const ActionNullableStringArgumentError = require('../../lib/errors/test-run').ActionNullableStringArgumentError; +const ActionStringOrStringArrayArgumentError = require('../../lib/errors/test-run').ActionStringOrStringArrayArgumentError; +const ActionStringArrayElementError = require('../../lib/errors/test-run').ActionStringArrayElementError; +const PageLoadError = require('../../lib/errors/test-run').PageLoadError; +const UncaughtErrorOnPage = require('../../lib/errors/test-run').UncaughtErrorOnPage; +const UncaughtErrorInTestCode = require('../../lib/errors/test-run').UncaughtErrorInTestCode; +const UncaughtErrorInClientFunctionCode = require('../../lib/errors/test-run').UncaughtErrorInClientFunctionCode; +const UncaughtNonErrorObjectInTestCode = require('../../lib/errors/test-run').UncaughtNonErrorObjectInTestCode; +const UncaughtErrorInCustomDOMPropertyCode = require('../../lib/errors/test-run').UncaughtErrorInCustomDOMPropertyCode; +const UnhandledPromiseRejectionError = require('../../lib/errors/test-run').UnhandledPromiseRejectionError; +const UncaughtExceptionError = require('../../lib/errors/test-run').UncaughtExceptionError; +const ActionElementNotFoundError = require('../../lib/errors/test-run').ActionElementNotFoundError; +const ActionElementIsInvisibleError = require('../../lib/errors/test-run').ActionElementIsInvisibleError; +const ActionSelectorMatchesWrongNodeTypeError = require('../../lib/errors/test-run').ActionSelectorMatchesWrongNodeTypeError; +const ActionAdditionalElementNotFoundError = require('../../lib/errors/test-run').ActionAdditionalElementNotFoundError; +const ActionAdditionalElementIsInvisibleError = require('../../lib/errors/test-run').ActionAdditionalElementIsInvisibleError; +const ActionAdditionalSelectorMatchesWrongNodeTypeError = require('../../lib/errors/test-run').ActionAdditionalSelectorMatchesWrongNodeTypeError; +const ActionElementNonEditableError = require('../../lib/errors/test-run').ActionElementNonEditableError; +const ActionElementNonContentEditableError = require('../../lib/errors/test-run').ActionElementNonContentEditableError; +const ActionRootContainerNotFoundError = require('../../lib/errors/test-run').ActionRootContainerNotFoundError; +const ActionElementNotTextAreaError = require('../../lib/errors/test-run').ActionElementNotTextAreaError; +const ActionIncorrectKeysError = require('../../lib/errors/test-run').ActionIncorrectKeysError; +const ActionCanNotFindFileToUploadError = require('../../lib/errors/test-run').ActionCanNotFindFileToUploadError; +const ActionElementIsNotFileInputError = require('../../lib/errors/test-run').ActionElementIsNotFileInputError; +const ActionUnsupportedDeviceTypeError = require('../../lib/errors/test-run').ActionUnsupportedDeviceTypeError; +const ActionInvalidScrollTargetError = require('../../lib/errors/test-run').ActionInvalidScrollTargetError; +const ClientFunctionExecutionInterruptionError = require('../../lib/errors/test-run').ClientFunctionExecutionInterruptionError; +const ActionElementNotIframeError = require('../../lib/errors/test-run').ActionElementNotIframeError; +const ActionIframeIsNotLoadedError = require('../../lib/errors/test-run').ActionIframeIsNotLoadedError; +const CurrentIframeIsNotLoadedError = require('../../lib/errors/test-run').CurrentIframeIsNotLoadedError; +const CurrentIframeNotFoundError = require('../../lib/errors/test-run').CurrentIframeNotFoundError; +const CurrentIframeIsInvisibleError = require('../../lib/errors/test-run').CurrentIframeIsInvisibleError; +const MissingAwaitError = require('../../lib/errors/test-run').MissingAwaitError; +const ExternalAssertionLibraryError = require('../../lib/errors/test-run').ExternalAssertionLibraryError; +const DomNodeClientFunctionResultError = require('../../lib/errors/test-run').DomNodeClientFunctionResultError; +const InvalidSelectorResultError = require('../../lib/errors/test-run').InvalidSelectorResultError; +const NativeDialogNotHandledError = require('../../lib/errors/test-run').NativeDialogNotHandledError; +const UncaughtErrorInNativeDialogHandler = require('../../lib/errors/test-run').UncaughtErrorInNativeDialogHandler; +const SetNativeDialogHandlerCodeWrongTypeError = require('../../lib/errors/test-run').SetNativeDialogHandlerCodeWrongTypeError; +const CantObtainInfoForElementSpecifiedBySelectorError = require('../../lib/errors/test-run').CantObtainInfoForElementSpecifiedBySelectorError; +const WindowDimensionsOverflowError = require('../../lib/errors/test-run').WindowDimensionsOverflowError; +const InvalidElementScreenshotDimensionsError = require('../../lib/errors/test-run').InvalidElementScreenshotDimensionsError; +const SetTestSpeedArgumentError = require('../../lib/errors/test-run').SetTestSpeedArgumentError; +const RoleSwitchInRoleInitializerError = require('../../lib/errors/test-run').RoleSwitchInRoleInitializerError; +const ActionRoleArgumentError = require('../../lib/errors/test-run').ActionRoleArgumentError; + +const TEST_FILE_STACK_ENTRY_RE = new RegExp('\\s*\\n?\\(' + escapeRe(require.resolve('./data/test-callsite')), 'g'); + +const untestedErrorTypes = Object.keys(TYPE).map(function (key) { return TYPE[key]; }); -var userAgentMock = 'Chrome 15.0.874 / Mac OS X 10.8.1'; +const userAgentMock = 'Chrome 15.0.874 / Mac OS X 10.8.1'; -var testAssertionError = (function () { +const testAssertionError = (function () { try { expect(true).eql(false); } @@ -94,11 +96,11 @@ function createOutStreamMock () { } function assertErrorMessage (file, err) { - var screenshotPath = '/unix/path/with/'; - var outStreamMock = createOutStreamMock(); - var plugin = new ReporterPluginHost({}, outStreamMock); + const screenshotPath = '/unix/path/with/'; + const outStreamMock = createOutStreamMock(); + const plugin = new ReporterPluginHost({}, outStreamMock); - var errAdapter = new TestRunErrorFormattableAdapter(err, { + const errAdapter = new TestRunErrorFormattableAdapter(err, { userAgent: userAgentMock, screenshotPath: screenshotPath, callsite: testCallsite, @@ -109,11 +111,11 @@ function assertErrorMessage (file, err) { .useWordWrap(true) .write(plugin.formatError(errAdapter)); - var expectedMsg = read('./data/expected-test-run-errors/' + file) + const expectedMsg = read('./data/expected-test-run-errors/' + file) .replace(/(\r\n)/gm, '\n') .trim(); - var actual = outStreamMock.data.replace(TEST_FILE_STACK_ENTRY_RE, ' (testfile.js'); + const actual = outStreamMock.data.replace(TEST_FILE_STACK_ENTRY_RE, ' (testfile.js'); expect(actual).eql(expectedMsg); @@ -173,6 +175,14 @@ describe('Error formatting', function () { assertErrorMessage('uncaught-error-in-add-custom-dom-properties-code', new UncaughtErrorInCustomDOMPropertyCode(testCallsite, new Error('Custom script error'), 'prop')); }); + it('Should format "unhandledPromiseRejectionError" message', function () { + assertErrorMessage('unhandled-promise-rejection-error', new UnhandledPromiseRejectionError('Hey ya!')); + }); + + it('Should format "uncaughtExceptionError" message', function () { + assertErrorMessage('uncaught-exception-error', new UncaughtExceptionError('Hey ya!')); + }); + it('Should format "actionElementNotFoundError" message', function () { assertErrorMessage('action-element-not-found-error', new ActionElementNotFoundError()); }); From 19fd15ddf3e819ce73d45faa42c2a4b1eef4e823 Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Fri, 17 Aug 2018 13:12:49 +0300 Subject: [PATCH 059/184] [docs] Add a description for new option, and reorder other cli options (#2736) --- .../using-testcafe/command-line-interface.md | 135 ++++++++++-------- .../programming-interface/runner.md | 1 + 2 files changed, 75 insertions(+), 61 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index c7ef963f..31662b62 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -28,25 +28,26 @@ testcafe [options] * [-S, --screenshots-on-fails](#-s---screenshots-on-fails) * [-p, --screenshot-path-pattern](#-p---screenshot-path-pattern) * [-q, --quarantine-mode](#-q---quarantine-mode) + * [-d, --debug-mode](#-d---debug-mode) * [-e, --skip-js-errors](#-e---skip-js-errors) - * [-c \, --concurrency \](#-c-n---concurrency-n) + * [-u, --skip-uncaught-errors](#-u---skip-uncaught-errors) * [-t \, --test \](#-t-name---test-name) * [-T \, --test-grep \](#-t-pattern---test-grep-pattern) * [-f \, --fixture \](#-f-name---fixture-name) * [-F \, --fixture-grep \](#-f-pattern---fixture-grep-pattern) * [-a \, --app \](#-a-command---app-command) - * [-d, --debug-mode](#-d---debug-mode) + * [-c \, --concurrency \](#-c-n---concurrency-n) * [--debug-on-fail](#--debug-on-fail) * [--app-init-delay \](#--app-init-delay-ms) * [--selector-timeout \](#--selector-timeout-ms) * [--assertion-timeout \](#--assertion-timeout-ms) * [--page-load-timeout \](#--page-load-timeout-ms) - * [--proxy \](#--proxy-host) - * [--proxy-bypass \](#--proxy-bypass-rules) + * [--speed \](#--speed-factor) * [--ports \](#--ports-port1port2) * [--hostname \](#--hostname-name) + * [--proxy \](#--proxy-host) * [--ssl \](#--ssl-options) - * [--speed \](#--speed-factor) + * [--proxy-bypass \](#--proxy-bypass-rules) * [--dev](#--dev) * [--qr-code](#--qr-code) * [--color](#--color) @@ -336,6 +337,19 @@ Enables the [quarantine mode](programming-interface/runner.md#quarantine-mode) f testcafe all tests/sample-fixture.js -q ``` +### -d, --debug-mode + +Specify this option to run tests in the debugging mode. In this mode, test execution is paused before the first action or assertion allowing you to invoke the developer tools and debug. + +The footer displays a status bar in which you can resume test execution or skip to the next action or assertion. + +![Debugging status bar](../../images/debugging/client-debugging-footer.png) + +> If the test you run in the debugging mode contains a [test hook](../test-api/test-code-structure.md#test-hooks), +> it is paused within this hook before the first action. + +You can also use the **Unlock page** switch in the footer to unlock the tested page and interact with its elements. + ### -e, --skip-js-errors When a JavaScript error occurs on a tested web page, TestCafe stops test execution and posts an error message to a report. To ignore JavaScript errors, use the `-e`(`--skip-js-errors`) option. @@ -346,19 +360,16 @@ For example, the following command runs tests from the specified file and forces testcafe ie tests/sample-fixture.js -e ``` -### -c \, --concurrency \ - -Specifies that tests should run concurrently. +### -u, --skip-uncaught-errors -TestCafe opens `n` instances of the same browser and creates a pool of browser instances. -Tests are run concurrently against this pool, that is, each test is run in the first free instance. +When an uncaught error or unhandled promise rejection occurs on the server during test execution, TestCafe stops the test and posts an error message to a report. Note that if you run tests [concurrently](#-c-n---concurrency-n) and such an error occurs in any test, all tests that are running at this moment will fail. -See [Concurrent Test Execution](common-concepts/concurrent-test-execution.md) for more information about concurrent test execution. +To ignore these errors, use the `-u`(`--skip-uncaught-errors`) option. -The following example shows how to run tests in three Chrome instances: +For example, the following command runs tests from the specified file and forces TestCafe to ignore uncaught errors and unhandled promise rejections: ```sh -testcafe -c 3 chrome tests/sample-fixture.js +testcafe ie tests/sample-fixture.js -u ``` ### -t \, --test \ @@ -413,18 +424,20 @@ testcafe chrome my-tests --app "node server.js" Use the [--app-init-delay](#--app-init-delay-ms) option to specify the amount of time allowed for this command to initialize the tested application. -### -d, --debug-mode +### -c \, --concurrency \ -Specify this option to run tests in the debugging mode. In this mode, test execution is paused before the first action or assertion allowing you to invoke the developer tools and debug. +Specifies that tests should run concurrently. -The footer displays a status bar in which you can resume test execution or skip to the next action or assertion. +TestCafe opens `n` instances of the same browser and creates a pool of browser instances. +Tests are run concurrently against this pool, that is, each test is run in the first free instance. -![Debugging status bar](../../images/debugging/client-debugging-footer.png) +See [Concurrent Test Execution](common-concepts/concurrent-test-execution.md) for more information about concurrent test execution. -> If the test you run in the debugging mode contains a [test hook](../test-api/test-code-structure.md#test-hooks), -> it is paused within this hook before the first action. +The following example shows how to run tests in three Chrome instances: -You can also use the **Unlock page** switch in the footer to unlock the tested page and interact with its elements. +```sh +testcafe -c 3 chrome tests/sample-fixture.js +``` ### --debug-on-fail @@ -485,61 +498,52 @@ You can set the page load timeout to `0` to skip waiting for the `window.load` e testcafe ie my-tests --page-load-timeout 0 ``` -### --proxy \ +### --speed \ -Specifies the proxy server used in your local network to access the Internet. +Specifies the test execution speed. -```sh -testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com -``` +Tests are run at the maximum speed by default. You can use this option +to slow the test down. + +`factor` should be a number between `1` (the fastest) and `0.01` (the slowest). ```sh -testcafe chrome my-tests/**/*.js --proxy 172.0.10.10:8080 +testcafe chrome my-tests --speed 0.1 ``` -You can also specify authentication credentials with the proxy host. +If the speed is also specified for an [individual action](../test-api/actions/action-options.md#basic-action-options), the action's speed setting overrides the test speed. -```js -testcafe chrome my-tests/**/*.js --proxy username:password@proxy.mycorp.com -``` +**Default value**: `1` -### --proxy-bypass \ +### --ports \ -Specifies the resources accessed bypassing the proxy server. +Specifies custom port numbers TestCafe uses to perform testing. The number range is [0-65535]. -When you access the Internet through a proxy server specified using the [--proxy](#--proxy-host) option, you may still need some local or external resources to be accessed directly. In this instance, provide their URLs to the `--proxy-bypass` option. +TestCafe automatically selects ports if ports are not specified. -The `rules` parameter takes a comma-separated list (without spaces) of URLs that require direct access. You can replace parts of the URL with the `*` wildcard that matches any number of characters. Wildcards at the beginning and end of the rules can be omitted (`*.mycompany.com` and `.mycompany.com` have the same effect). +### --hostname \ -The following example uses the proxy server at `proxy.corp.mycompany.com` with the `localhost:8080` address accessed directly: +Specifies your computer's hostname. It is used when running tests in [remote browsers](#remote-browsers). -```sh -testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com --proxy-bypass localhost:8080 -``` +If the hostname is not specified, TestCafe uses the operating system's hostname or the current machine's network IP address. -In the example below, two resources are accessed by bypassing the proxy: `localhost:8080` and `internal-resource.corp.mycompany.com`. +### --proxy \ + +Specifies the proxy server used in your local network to access the Internet. ```sh -testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com --proxy-bypass localhost:8080,internal-resource.corp.mycompany.com +testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com ``` -The `*.mycompany.com` value means that all URLs in the `mycompany.com` subdomains are accessed directly. - ```sh -testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com --proxy-bypass *.mycompany.com +testcafe chrome my-tests/**/*.js --proxy 172.0.10.10:8080 ``` -### --ports \ - -Specifies custom port numbers TestCafe uses to perform testing. The number range is [0-65535]. - -TestCafe automatically selects ports if ports are not specified. - -### --hostname \ - -Specifies your computer's hostname. It is used when running tests in [remote browsers](#remote-browsers). +You can also specify authentication credentials with the proxy host. -If the hostname is not specified, TestCafe uses the operating system's hostname or the current machine's network IP address. +```js +testcafe chrome my-tests/**/*.js --proxy username:password@proxy.mycorp.com +``` ### --ssl \ @@ -558,22 +562,31 @@ Provide the `--ssl` flag if the tested webpage uses browser features that requir secure origin ([Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API), [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API), [ApplePaySession](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession), [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto), etc). See [Connect to the TestCafe Server over HTTPS](common-concepts/connect-to-the-testcafe-server-over-https.md) for more information. -### --speed \ +### --proxy-bypass \ -Specifies the test execution speed. +Specifies the resources accessed bypassing the proxy server. -Tests are run at the maximum speed by default. You can use this option -to slow the test down. +When you access the Internet through a proxy server specified using the [--proxy](#--proxy-host) option, you may still need some local or external resources to be accessed directly. In this instance, provide their URLs to the `--proxy-bypass` option. -`factor` should be a number between `1` (the fastest) and `0.01` (the slowest). +The `rules` parameter takes a comma-separated list (without spaces) of URLs that require direct access. You can replace parts of the URL with the `*` wildcard that matches any number of characters. Wildcards at the beginning and end of the rules can be omitted (`*.mycompany.com` and `.mycompany.com` have the same effect). + +The following example uses the proxy server at `proxy.corp.mycompany.com` with the `localhost:8080` address accessed directly: ```sh -testcafe chrome my-tests --speed 0.1 +testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com --proxy-bypass localhost:8080 ``` -If the speed is also specified for an [individual action](../test-api/actions/action-options.md#basic-action-options), the action's speed setting overrides the test speed. +In the example below, two resources are accessed by bypassing the proxy: `localhost:8080` and `internal-resource.corp.mycompany.com`. -**Default value**: `1` +```sh +testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com --proxy-bypass localhost:8080,internal-resource.corp.mycompany.com +``` + +The `*.mycompany.com` value means that all URLs in the `mycompany.com` subdomains are accessed directly. + +```sh +testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com --proxy-bypass *.mycompany.com +``` ### --dev diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index 8ea35944..ac254ae9 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -409,6 +409,7 @@ You can pass the following options to the `runner.run` function. Parameter | Type | Description | Default ----------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- `skipJsErrors` | Boolean | Defines whether to continue running a test after a JavaScript error occurs on a page (`true`), or consider such a test failed (`false`). | `false` +`skipUncaughtErrors` | Boolean | Defines whether to continue running a test after an uncaught error or unhandled promise rejection occurs on the server (`true`), or consider such a test failed (`false`). | `false` `quarantineMode` | Boolean | Defines whether to enable the [quarantine mode](#quarantine-mode). | `false` `selectorTimeout` | Number | Specifies the time (in milliseconds) within which [selectors](../../test-api/selecting-page-elements/selectors/README.md) make attempts to obtain a node to be returned. See [Selector Timeout](../../test-api/selecting-page-elements/selectors/using-selectors.md#selector-timeout). | `10000` `assertionTimeout` | Number | Specifies the time (in milliseconds) within which TestCafe makes attempts to successfully execute an [assertion](../../test-api/assertions/README.md) if [a selector property](../../test-api/selecting-page-elements/selectors/using-selectors.md#define-assertion-actual-value) or a [client function](../../test-api/obtaining-data-from-the-client/README.md) was passed as an actual value. See [Smart Assertion Query Mechanism](../../test-api/assertions/README.md#smart-assertion-query-mechanism). | `3000` From eb40d23497d4998e61739a423cf562fc59008e0e Mon Sep 17 00:00:00 2001 From: Boris Kirov Date: Tue, 21 Aug 2018 10:58:36 +0300 Subject: [PATCH 060/184] Added the parsing of meta info (#2367) (#2724) --- .../formats/es-next/get-test-list.js | 45 +++- .../formats/typescript/get-test-list.js | 60 ++++- .../test-file/test-file-parser-base.js | 83 +++++- .../test-suites/meta/custom-field-value.js | 54 ++++ test/server/data/test-suites/meta/testfile.js | 2 +- test/server/parse-fixture-test.js | 239 ++++++++++++------ 6 files changed, 375 insertions(+), 108 deletions(-) create mode 100644 test/server/data/test-suites/meta/custom-field-value.js diff --git a/src/compiler/test-file/formats/es-next/get-test-list.js b/src/compiler/test-file/formats/es-next/get-test-list.js index c89ef29f..81cf8cb1 100644 --- a/src/compiler/test-file/formats/es-next/get-test-list.js +++ b/src/compiler/test-file/formats/es-next/get-test-list.js @@ -1,4 +1,4 @@ -import { assign } from 'lodash'; +import { assign, merge } from 'lodash'; import { transform } from 'babel-core'; import ESNextTestFileCompiler from './compiler'; import { TestFileParserBase } from '../../test-file-parser-base'; @@ -15,7 +15,7 @@ const TOKEN_TYPE = { ExpressionStatement: 'ExpressionStatement', ReturnStatement: 'ReturnStatement', FunctionDeclaration: 'FunctionDeclaration', - VariableDeclaration: 'VariableDeclaration' + ObjectLiteralExpression: 'ObjectExpression' }; export class EsNextTestFileParser extends TestFileParserBase { @@ -40,17 +40,44 @@ export class EsNextTestFileParser extends TestFileParserBase { return token.declarations[0].init; } + getStringValue (token) { + const stringTypes = [this.tokenType.StringLiteral, this.tokenType.TemplateLiteral, this.tokenType.Identifier]; + + if (stringTypes.indexOf(token.type) > -1) + return this.formatFnArg(token); + + return null; + } + getFunctionBody (token) { return token.body && token.body.body ? token.body.body : []; } - formatFnData (name, value, token) { + getCalleeToken (token) { + return token.callee; + } + + getMemberFnName (token) { + return token.callee.property.name; + } + + formatFnData (name, value, token, meta = [{}]) { return { fnName: name, value: value, loc: token.loc, start: token.start, - end: token.end + end: token.end, + meta: merge({}, ...meta) + }; + } + + getKeyValue (prop) { + const { key, value } = prop; + + return { + key: key.name || this.formatFnArg(key), + value: this.getStringValue(value) }; } @@ -78,13 +105,15 @@ export class EsNextTestFileParser extends TestFileParserBase { if (!this.isApiFn(exp.name)) return null; + const meta = this.getMetaInfo(callStack.slice()); + let parentExp = callStack.pop(); if (parentExp.type === tokenType.CallExpression) - return this.formatFnData(exp.name, this.formatFnArg(parentExp.arguments[0]), token); + return this.formatFnData(exp.name, this.formatFnArg(parentExp.arguments[0]), token, meta); if (parentExp.type === tokenType.TaggedTemplateExpression) - return this.formatFnData(exp.name, EsNextTestFileParser.getTagStrValue(parentExp.quasi), token); + return this.formatFnData(exp.name, EsNextTestFileParser.getTagStrValue(parentExp.quasi), token, meta); if (parentExp.type === tokenType.PropertyAccessExpression) { while (parentExp) { @@ -93,7 +122,7 @@ export class EsNextTestFileParser extends TestFileParserBase { const calleeMemberFn = parentExp.callee.property && parentExp.callee.property.name; if (this.checkExpDefineTargetName(calleeType, calleeMemberFn)) - return this.formatFnData(exp.name, this.formatFnArg(parentExp.arguments[0]), token); + return this.formatFnData(exp.name, this.formatFnArg(parentExp.arguments[0]), token, meta); } if (parentExp.type === tokenType.TaggedTemplateExpression && parentExp.tag) { @@ -101,7 +130,7 @@ export class EsNextTestFileParser extends TestFileParserBase { const tagMemberFn = parentExp.tag.property && parentExp.tag.property.name; if (this.checkExpDefineTargetName(tagType, tagMemberFn)) - return this.formatFnData(exp.name, EsNextTestFileParser.getTagStrValue(parentExp.quasi), token); + return this.formatFnData(exp.name, EsNextTestFileParser.getTagStrValue(parentExp.quasi), token, meta); } parentExp = callStack.pop(); diff --git a/src/compiler/test-file/formats/typescript/get-test-list.js b/src/compiler/test-file/formats/typescript/get-test-list.js index 693ee047..047c1a4a 100644 --- a/src/compiler/test-file/formats/typescript/get-test-list.js +++ b/src/compiler/test-file/formats/typescript/get-test-list.js @@ -1,5 +1,5 @@ import ts from 'typescript'; -import { repeat } from 'lodash'; +import { repeat, merge } from 'lodash'; import TypeScriptTestFileCompiler from './compiler'; import { TestFileParserBase } from '../../test-file-parser-base'; @@ -16,10 +16,33 @@ class TypeScriptTestFileParser extends TestFileParserBase { super(ts.SyntaxKind); } + getComputedNameString ({ pos, end }) { + const templatePos = this.getLocationByOffsets(pos, end); + + return TestFileParserBase.formatComputedName(templatePos.loc.start.line); + } + getTokenType (token) { return token.kind; } + getCalleeToken (token) { + return token.expression; + } + + getMemberFnName (token) { + return token.expression.name.text; + } + + getKeyValue (prop) { + const { name, initializer } = prop; + + return { + key: name.text, + value: this.getStringValue(initializer) + }; + } + getFixedStartOffset (start) { let fixedStartOffset = start; @@ -59,6 +82,15 @@ class TypeScriptTestFileParser extends TestFileParserBase { return token.initializer; } + getStringValue (token) { + const stringTypes = [this.tokenType.StringLiteral, this.tokenType.TemplateExpression]; + + if (stringTypes.indexOf(token.kind) > -1 || token.text && token.kind !== this.tokenType.NumericLiteral) + return this.formatFnArg(token); + + return null; + } + isAsyncFn (token) { const isGeneratorFn = !!token.asteriskToken; const isAsyncFn = token.modifiers && @@ -71,13 +103,7 @@ class TypeScriptTestFileParser extends TestFileParserBase { return token.body.statements; } - formatFnData (name, value, token) { - if (value && typeof value === 'object') { - const templatePos = this.getLocationByOffsets(value.pos, value.end); - - value = TypeScriptTestFileParser.formatComputedName(templatePos.loc.start.line); - } - + formatFnData (name, value, token, meta = [{}]) { const loc = this.getLocationByOffsets(token.pos, token.end); return { @@ -85,7 +111,8 @@ class TypeScriptTestFileParser extends TestFileParserBase { value: value, loc: loc.loc, start: loc.start, - end: loc.end + end: loc.end, + meta: merge({}, ...meta) }; } @@ -100,6 +127,8 @@ class TypeScriptTestFileParser extends TestFileParserBase { callStack.push(exp); } + const meta = this.getMetaInfo(callStack.slice()); + if (exp && this.isApiFn(exp.text)) { let parentExp = callStack.pop(); @@ -110,7 +139,7 @@ class TypeScriptTestFileParser extends TestFileParserBase { parentExp.expression.name.text; if (this.checkExpDefineTargetName(calleeType, calleeMemberFn)) - return this.formatFnData(exp.text, this.formatFnArg(parentExp.arguments[0]), token); + return this.formatFnData(exp.text, this.formatFnArg(parentExp.arguments[0]), token, meta); } if (parentExp.kind === tokenType.TaggedTemplateExpression && parentExp.tag) { @@ -118,7 +147,7 @@ class TypeScriptTestFileParser extends TestFileParserBase { const tagMemberFn = tagType === tokenType.PropertyAccessExpression && parentExp.tag.name.text; if (this.checkExpDefineTargetName(tagType, tagMemberFn)) - return this.formatFnData(exp.text, this.formatFnArg(parentExp), token); + return this.formatFnData(exp.text, this.formatFnArg(parentExp), token, meta); } parentExp = callStack.pop(); @@ -129,14 +158,17 @@ class TypeScriptTestFileParser extends TestFileParserBase { } formatFnArg (arg) { + if (arg.templateSpans) + return this.getComputedNameString({ pos: arg.pos, end: arg.end }); + if (arg.head) - return { pos: arg.template.pos, end: arg.template.end }; + return this.getComputedNameString({ pos: arg.template.pos, end: arg.template.end }); if (arg.template) - return arg.template.text || { pos: arg.template.pos, end: arg.template.end }; + return arg.template.text || this.getComputedNameString({ pos: arg.template.pos, end: arg.template.end }); if (arg.kind === this.tokenType.Identifier) - return { pos: arg.pos, end: arg.end }; + return this.getComputedNameString({ pos: arg.pos, end: arg.end }); if (arg.text && arg.kind !== this.tokenType.NumericLiteral) return arg.text; diff --git a/src/compiler/test-file/test-file-parser-base.js b/src/compiler/test-file/test-file-parser-base.js index 2a97ddc6..e094e0ca 100644 --- a/src/compiler/test-file/test-file-parser-base.js +++ b/src/compiler/test-file/test-file-parser-base.js @@ -11,21 +11,23 @@ const METHODS_SPECIFYING_NAME = ['only', 'skip']; const COMPUTED_NAME_TEXT_TMP = '(line: %s)'; export class Fixture { - constructor (name, start, end, loc) { + constructor (name, start, end, loc, meta) { this.name = name; this.loc = loc; this.start = start; this.end = end; + this.meta = meta; this.tests = []; } } export class Test { - constructor (name, start, end, loc) { + constructor (name, start, end, loc, meta) { this.name = name; this.loc = loc; this.start = start; this.end = end; + this.meta = meta; } } @@ -78,10 +80,83 @@ export class TestFileParserBase { throw new Error('Not implemented'); } + getTokenType (/* token */) { + throw new Error('Not implemented'); + } + + getCalleeToken (/* token */) { + throw new Error('Not implemented'); + } + + getMemberFnName () { + throw new Error('Not implemented'); + } + + getKeyValue () { + throw new Error('Not implemented'); + } + + getStringValue () { + throw new Error('Not implemented'); + } + isApiFn (fn) { return fn === 'fixture' || fn === 'test'; } + serializeObjExp (token) { + if (this.getTokenType(token) !== this.tokenType.ObjectLiteralExpression) + return {}; + + return token.properties.reduce((obj, prop) => { + const { key, value } = this.getKeyValue(prop); + + if (typeof value !== 'string') return {}; + + obj[key] = value; + + return obj; + }, {}); + } + + processMetaArgs (token) { + if (this.getTokenType(token) !== this.tokenType.CallExpression) + return null; + + const args = token.arguments; + + let meta = {}; + + if (args.length === 2) { + const value = this.getStringValue(args[1]); + + if (typeof value !== 'string') return {}; + + meta = { [this.formatFnArg(args[0])]: value }; + } + + else if (args.length === 1) + meta = this.serializeObjExp(args[0]); + + return meta; + } + + getMetaInfo (callStack) { + return callStack.reduce((metaCalls, exp) => { + if (this.getTokenType(exp) !== this.tokenType.CallExpression) + return metaCalls; + + const callee = this.getCalleeToken(exp); + const calleeType = this.getTokenType(callee); + const isCalleeMemberExp = calleeType === this.tokenType.PropertyAccessExpression; + + if (isCalleeMemberExp && this.getMemberFnName(exp) === 'meta') + return [this.processMetaArgs(exp)].concat(metaCalls); + + return metaCalls; + }, []); + } + checkExpDefineTargetName (type, apiFn) { //NOTE: fixture('fixtureName').chainFn or test('testName').chainFn const isDirectCall = type === this.tokenType.Identifier; @@ -151,13 +226,13 @@ export class TestFileParserBase { if (!call || typeof call.value !== 'string') return; if (call.fnName === 'fixture') { - fixtures.push(new Fixture(call.value, call.start, call.end, call.loc)); + fixtures.push(new Fixture(call.value, call.start, call.end, call.loc, call.meta)); return; } if (!fixtures.length) return; - const test = new Test(call.value, call.start, call.end, call.loc); + const test = new Test(call.value, call.start, call.end, call.loc, call.meta); fixtures[fixtures.length - 1].tests.push(test); }); diff --git a/test/server/data/test-suites/meta/custom-field-value.js b/test/server/data/test-suites/meta/custom-field-value.js new file mode 100644 index 00000000..04dd7145 --- /dev/null +++ b/test/server/data/test-suites/meta/custom-field-value.js @@ -0,0 +1,54 @@ +const fieldIndex = 2; + +fixture `Fixture1` + .meta('field 1', `field 1`) + .meta('field 2', `field ${fieldIndex}`) + .meta('field 3', fieldIndex); + +test `Test1` + .meta('field 1', `field 1`) + .meta('field 2', `field ${fieldIndex}`) + .meta('field 3', fieldIndex); + +fixture `Fixture2` + .meta({ 'field 1': `field 1` }) + .meta({ 'field 2': `field ${fieldIndex}` }) + .meta({ 'field 3': fieldIndex }); + +test `Test2` + .meta({ 'field 1': `field 1` }) + .meta({ 'field 2': `field ${fieldIndex}` }) + .meta({ 'field 3': fieldIndex }); + +test `Test3` + .meta({ + field1: true, + field2: 1, + field3: null, + field4: void 0, + field5: Symbol(), + + field6: {}, + field7: { + a: 1, + b: true, + c: _c, + d: function () { + + }, + e: { + f: g.i + } + }, + + field8: [], + field9: [1, 'string', a, b.c, function () { + + }], + + field10: function () { + }, + + field11: () => { + } + }); diff --git a/test/server/data/test-suites/meta/testfile.js b/test/server/data/test-suites/meta/testfile.js index 13ed380f..7377b0cf 100644 --- a/test/server/data/test-suites/meta/testfile.js +++ b/test/server/data/test-suites/meta/testfile.js @@ -17,4 +17,4 @@ fixture('Fixture2') test('Fixture2Test1', async () => { // do nothing -}).meta('emptyField'); \ No newline at end of file +}).meta('emptyField'); diff --git a/test/server/parse-fixture-test.js b/test/server/parse-fixture-test.js index 97d3a383..c4768d62 100644 --- a/test/server/parse-fixture-test.js +++ b/test/server/parse-fixture-test.js @@ -1,20 +1,20 @@ -var expect = require('chai').expect; -var fs = require('fs'); -var path = require('path'); -var assign = require('lodash').assign; -var getTestList = require('../../lib/embedding-utils').getTestList; -var getTypeScriptTestList = require('../../lib/embedding-utils').getTypeScriptTestList; -var getCoffeeScriptTestList = require('../../lib/embedding-utils').getCoffeeScriptTestList; -var getTestListFromCode = require('../../lib/embedding-utils').getTestListFromCode; -var getTypeScriptTestListFromCode = require('../../lib/embedding-utils').getTypeScriptTestListFromCode; -var getCoffeeScriptTestListFromCode = require('../../lib/embedding-utils').getCoffeeScriptTestListFromCode; -var Promise = require('pinkie'); -var parserBase = require('../../lib/compiler/test-file/test-file-parser-base'); - -var Test = parserBase.Test; -var Fixture = function (name, start, end, loc, tests) { +const expect = require('chai').expect; +const fs = require('fs'); +const path = require('path'); +const assign = require('lodash').assign; +const getTestList = require('../../lib/embedding-utils').getTestList; +const getTypeScriptTestList = require('../../lib/embedding-utils').getTypeScriptTestList; +const getTestListFromCode = require('../../lib/embedding-utils').getTestListFromCode; +const getTypeScriptTestListFromCode = require('../../lib/embedding-utils').getTypeScriptTestListFromCode; +const getCoffeeScriptTestList = require('../../lib/embedding-utils').getCoffeeScriptTestList; +const getCoffeeScriptTestListFromCode = require('../../lib/embedding-utils').getCoffeeScriptTestListFromCode; +const Promise = require('pinkie'); +const parserBase = require('../../lib/compiler/test-file/test-file-parser-base'); + +const Test = parserBase.Test; +const Fixture = function (name, start, end, loc, meta, tests) { return assign( - new parserBase.Fixture(name, start, end, loc), + new parserBase.Fixture(name, start, end, loc, meta), { tests: tests } ); }; @@ -25,13 +25,13 @@ function Loc (lineStart, columnStart, lineEnd, columnEnd) { } function testFixtureParser (dir, expectedStructure, fileParser, codeParser) { - var dirPath = path.join(__dirname, dir); - var fileList = fs.readdirSync(dirPath).sort(); + const dirPath = path.join(__dirname, dir); + const fileList = fs.readdirSync(dirPath).sort(); - var parseFilePromises = fileList.map(function (filename, index) { - var expected = expectedStructure[index]; - var filePath = path.join(dirPath, filename); - var fileContent = fs.readFileSync(filePath, 'utf8'); + const parseFilePromises = fileList.map(function (filename, index) { + const expected = expectedStructure[index]; + const filePath = path.join(dirPath, filename); + const fileContent = fs.readFileSync(filePath, 'utf8'); return fileParser(filePath) .then(function (structure) { @@ -60,26 +60,26 @@ function testCoffeeScriptFilesParser (dir, expectedStructure) { describe('Should get structure of files (esnext and typescript common cases)', function () { it('Base', function () { - var expectedStructure = [ + const expectedStructure = [ [], [], [ - new Fixture('Fixture1', 30, 49, new Loc(3, 0, 3, 19), + new Fixture('Fixture1', 30, 49, new Loc(3, 0, 3, 19), {}, [ - new Test('Fixture1Test1', 52, 148, new Loc(5, 0, 9, 2)), - new Test('(line: 13)', 187, 238, new Loc(13, 0, 15, 2)) + new Test('Fixture1Test1', 52, 148, new Loc(5, 0, 9, 2), {}), + new Test('(line: 13)', 187, 238, new Loc(13, 0, 15, 2), {}) ] ), - new Fixture('(line: 17)', 241, 353, new Loc(17, 0, 20, 26), + new Fixture('(line: 17)', 241, 353, new Loc(17, 0, 20, 26), {}, [ - new Test('Fixture2Test1', 356, 413, new Loc(22, 0, 24, 2)) + new Test('Fixture2Test1', 356, 413, new Loc(22, 0, 24, 2), {}) ] )], [ - new Fixture('Fixture3', 30, 136, new Loc(3, 0, 6, 27), + new Fixture('Fixture3', 30, 136, new Loc(3, 0, 6, 27), {}, [ - new Test('(line: 10)', 178, 271, new Loc(10, 0, 14, 2)) + new Test('(line: 10)', 178, 271, new Loc(10, 0, 14, 2), {}) ] ) ] @@ -89,10 +89,10 @@ describe('Should get structure of files (esnext and typescript common cases)', f }); it('Fixture name is not a string', function () { - var expectedStructure = [[ - new Fixture('Yo', 173, 185, new Loc(5, 0, 5, 12), + const expectedStructure = [[ + new Fixture('Yo', 173, 185, new Loc(5, 0, 5, 12), {}, [ - new Test('Test', 214, 254, new Loc(9, 0, 11, 2)) + new Test('Test', 214, 254, new Loc(9, 0, 11, 2), {}) ] ) ]]; @@ -101,11 +101,11 @@ describe('Should get structure of files (esnext and typescript common cases)', f }); it('Test name is not a string', function () { - var expectedStructure = [ + const expectedStructure = [ [ - new Fixture('Test name is not a string', 0, 35, new Loc(1, 0, 1, 35), + new Fixture('Test name is not a string', 0, 35, new Loc(1, 0, 1, 35), {}, [ - new Test('TheAnswer', 210, 238, new Loc(6, 0, 7, 2)) + new Test('TheAnswer', 210, 238, new Loc(6, 0, 7, 2), {}) ] ) ]]; @@ -114,11 +114,11 @@ describe('Should get structure of files (esnext and typescript common cases)', f }); it('Call from async function', function () { - var expectedStructure = [ + const expectedStructure = [ [ - new Fixture('fixture 1', 0, 20, new Loc(1, 0, 1, 20), + new Fixture('fixture 1', 0, 20, new Loc(1, 0, 1, 20), {}, [ - new Test('test 1', 466, 480, new Loc(38, 0, 38, 14)) + new Test('test 1', 466, 480, new Loc(38, 0, 38, 14), {}) ] )] ]; @@ -127,58 +127,58 @@ describe('Should get structure of files (esnext and typescript common cases)', f }); it('Hooks in test file', function () { - var expectedStructure = [ + const expectedStructure = [ [ - new Fixture('fixture1', 0, 23, new Loc(1, 0, 1, 23), + new Fixture('fixture1', 0, 23, new Loc(1, 0, 1, 23), {}, [ - new Test('fixture1test1', 26, 111, new Loc(3, 0, 9, 2)) + new Test('fixture1test1', 26, 111, new Loc(3, 0, 9, 2), {}) ] ), - new Fixture('fixture2', 115, 137, new Loc(12, 0, 12, 22), + new Fixture('fixture2', 115, 137, new Loc(12, 0, 12, 22), {}, [ - new Test('fixture2test1', 140, 164, new Loc(14, 0, 14, 24)), - new Test('fixture2test2', 166, 190, new Loc(15, 0, 15, 24)), - new Test('fixture2test3', 193, 241, new Loc(17, 0, 17, 48)), - new Test('fixture2test4', 243, 269, new Loc(18, 0, 18, 26)) + new Test('fixture2test1', 140, 164, new Loc(14, 0, 14, 24), {}), + new Test('fixture2test2', 166, 190, new Loc(15, 0, 15, 24), {}), + new Test('fixture2test3', 193, 241, new Loc(17, 0, 17, 48), {}), + new Test('fixture2test4', 243, 269, new Loc(18, 0, 18, 26), {}) ] ), - new Fixture('fixture 3', 272, 297, new Loc(20, 0, 20, 25), + new Fixture('fixture 3', 272, 297, new Loc(20, 0, 20, 25), {}, [ - new Test('fixture3test1', 300, 348, new Loc(22, 0, 22, 48)), - new Test('fixture3test2', 350, 376, new Loc(23, 0, 23, 26)), - new Test('fixture3test4', 379, 468, new Loc(25, 0, 32, 6)) + new Test('fixture3test1', 300, 348, new Loc(22, 0, 22, 48), {}), + new Test('fixture3test2', 350, 376, new Loc(23, 0, 23, 26), {}), + new Test('fixture3test4', 379, 468, new Loc(25, 0, 32, 6), {}) ] ), - new Fixture('fixture4', 472, 554, new Loc(35, 0, 38, 16), + new Fixture('fixture4', 472, 554, new Loc(35, 0, 38, 16), {}, [ - new Test('fixture4test1', 557, 636, new Loc(40, 0, 43, 21)) + new Test('fixture4test1', 557, 636, new Loc(40, 0, 43, 21), {}) ] ), - new Fixture('fixture5', 639, 721, new Loc(45, 0, 48, 16), + new Fixture('fixture5', 639, 721, new Loc(45, 0, 48, 16), {}, [ - new Test('fixture5test1', 724, 801, new Loc(50, 0, 53, 19)) + new Test('fixture5test1', 724, 801, new Loc(50, 0, 53, 19), {}) ] ), - new Fixture('fixture6', 804, 912, new Loc(55, 0, 59, 25), + new Fixture('fixture6', 804, 912, new Loc(55, 0, 59, 25), {}, [ - new Test('fixture6test1', 915, 1026, new Loc(61, 0, 65, 31)) + new Test('fixture6test1', 915, 1026, new Loc(61, 0, 65, 31), {}) ] ), - new Fixture('fixture7', 1029, 1137, new Loc(67, 0, 71, 25), + new Fixture('fixture7', 1029, 1137, new Loc(67, 0, 71, 25), {}, [ - new Test('fixture7test1', 1140, 1251, new Loc(73, 0, 77, 31)) + new Test('fixture7test1', 1140, 1251, new Loc(73, 0, 77, 31), {}) ] ), - new Fixture('fixture8', 1254, 1360, new Loc(79, 0, 83, 25), + new Fixture('fixture8', 1254, 1360, new Loc(79, 0, 83, 25), {}, [ - new Test('(line: 88)', 1363, 1467, new Loc(85, 0, 89, 31)) + new Test('(line: 88)', 1363, 1467, new Loc(85, 0, 89, 31), {}) ] ) ] @@ -188,10 +188,10 @@ describe('Should get structure of files (esnext and typescript common cases)', f }); it('Tests and fixtures definitions in IIFE', function () { - var expectedStructure = [[ - new Fixture('fixture', 19, 59, new Loc(2, 4, 2, 44), + const expectedStructure = [[ + new Fixture('fixture', 19, 59, new Loc(2, 4, 2, 44), {}, [ - new Test('testName', 83, 158, new Loc(5, 8, 7, 10)) + new Test('testName', 83, 158, new Loc(5, 8, 7, 10), {}) ] ) ]]; @@ -200,33 +200,110 @@ describe('Should get structure of files (esnext and typescript common cases)', f }); it('Hooks in test file - invalid usage', function () { - var expectedStructure = [[]]; + const expectedStructure = [[]]; return testJSFilesParser('./data/test-suites/fixture-and-test-hooks-invalid-usage', expectedStructure); }); + + it('Meta info', function () { + const fixture1Meta = { + metaField1: 'fixtureMetaValue1', + metaField2: 'fixtureMetaUpdatedValue2', + metaField3: 'fixtureMetaValue3' + }; + + const testMeta = { + metaField1: 'testMetaValue1', + metaField4: 'testMetaUpdatedValue4', + metaField5: 'testMetaValue5' + }; + + const fixtureComputedMetaData1 = { + 'field 1': 'field 1', + 'field 2': '(line: 5)', + 'field 3': '(line: 6)' + }; + + const testComputedMetaData1 = { + 'field 1': 'field 1', + 'field 2': '(line: 10)', + 'field 3': '(line: 11)' + }; + + const fixtureComputedMetaData2 = { + 'field 1': 'field 1', + 'field 2': '(line: 15)', + 'field 3': '(line: 16)' + }; + + const testComputedMetaData2 = { + 'field 1': 'field 1', + 'field 2': '(line: 20)', + 'field 3': '(line: 21)' + }; + + const testComputedMetaData3 = {}; + + const expectedStructure = [ + [ + new Fixture('Fixture1', 23, 150, new Loc(3, 0, 6, 32), fixtureComputedMetaData1, [ + new Test('Test1', 153, 274, new Loc(8, 0, 11, 32), testComputedMetaData1) + ]), + + new Fixture('Fixture2', 277, 416, new Loc(13, 0, 16, 36), fixtureComputedMetaData2, [ + new Test('Test2', 419, 552, new Loc(18, 0, 21, 36), testComputedMetaData2), + new Test('Test3', 555, 1071, new Loc(23, 0, 54, 6), testComputedMetaData3) + ]) + ], + + [ + new Fixture('Fixture1', 0, 63, new Loc(1, 0, 3, 11), {}, [ + new Test('Fixture1Test1', 66, 135, new Loc(5, 0, 8, 6), {}) + ]) + ], + + [ + new Fixture('Fixture1', 0, 51, new Loc(1, 0, 2, 31), {}, [ + new Test('Fixture1Test1', 54, 139, new Loc(4, 0, 8, 6), {}) + ]) + ], + + [ + new Fixture('Fixture1', 0, 228, new Loc(1, 0, 5, 51), fixture1Meta, [ + new Test('Fixture1Test1', 231, 465, new Loc(7, 0, 13, 48), testMeta) + ]), + + new Fixture('Fixture2', 468, 511, new Loc(15, 0, 16, 23), {}, [ + new Test('Fixture2Test1', 514, 589, new Loc(18, 0, 20, 21), {}) + ]) + ] + ]; + + return testJSFilesParser('./data/test-suites/meta', expectedStructure); + }); }); describe('Should get structure of TypeScript files', function () { it('Smoke test', () => { - var expectedStructure = [ + const expectedStructure = [ [ - new Fixture('fixture 1', 72, 132, new Loc(5, 0, 5, 60), + new Fixture('fixture 1', 72, 132, new Loc(5, 0, 5, 60), {}, [ - new Test('test 1', 246, 325, new Loc(9, 0, 11, 2)) + new Test('test 1', 246, 325, new Loc(9, 0, 11, 2), {}) ] ), - new Fixture('(line: 14)', 380, 422, new Loc(14, 1, 14, 43), + new Fixture('(line: 14)', 380, 422, new Loc(14, 1, 14, 43), {}, [ - new Test('(line: 15)', 425, 456, new Loc(15, 1, 16, 3)) + new Test('(line: 15)', 425, 456, new Loc(15, 1, 16, 3), {}) ] ) ], [ - new Fixture('fixture 1', 97, 138, new Loc(9, 9, 9, 50), + new Fixture('fixture 1', 97, 138, new Loc(9, 9, 9, 50), {}, [ - new Test('test 1', 147, 222, new Loc(11, 6, 13, 12)) + new Test('test 1', 147, 222, new Loc(11, 6, 13, 12), {}) ] ) ] @@ -240,23 +317,23 @@ describe('Should get structure of CoffeeScript files', function () { it('Smoke test', () => { var expectedStructure = [ [ - new Fixture('fixture 1', 94, 138, new Loc(7, 0, 7, 44), + new Fixture('fixture 1', 94, 138, new Loc(7, 0, 7, 44), {}, [ - new Test('test 1', 221, 291, new Loc(13, 0, 15, 2)) + new Test('test 1', 221, 291, new Loc(13, 0, 15, 2), {}) ] ), - new Fixture('(line: 18)', 331, 373, new Loc(18, 2, 18, 44), + new Fixture('(line: 18)', 331, 373, new Loc(18, 2, 18, 44), {}, [ - new Test('(line: 19)', 384, 409, new Loc(19, 9, 19, 34)) + new Test('(line: 19)', 384, 409, new Loc(19, 9, 19, 34), {}) ] ) ], [ - new Fixture('fixture 1', 0, 41, new Loc(1, 0, 1, 41), + new Fixture('fixture 1', 0, 41, new Loc(1, 0, 1, 41), {}, [ - new Test('test 1', 44, 110, new Loc(3, 0, 5, 12)) + new Test('test 1', 44, 110, new Loc(3, 0, 5, 12), {}) ] ) ] @@ -268,9 +345,9 @@ describe('Should get structure of CoffeeScript files', function () { describe('Regression', function () { it('Parser fails with "JS allocation failed" error (GH-1771)', function () { - var expectedStructure = [[ - new Fixture('Fixture', 93, 135, new Loc(5, 0, 6, 24), [ - new Test('Test', 138, 167, new Loc(8, 0, 10, 2)) + const expectedStructure = [[ + new Fixture('Fixture', 93, 135, new Loc(5, 0, 6, 24), {}, [ + new Test('Test', 138, 167, new Loc(8, 0, 10, 2), {}) ]) ]]; From 5522e04aba99adce701491c94a9a3396318c1f0d Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Wed, 22 Aug 2018 16:34:26 +0300 Subject: [PATCH 061/184] add the selector text used when selector does not match element (closes #2568) (#2704) --- src/client-functions/selectors/add-api.js | 325 +++++++++++------- .../selectors/selector-builder.js | 98 ++++-- .../selectors/snapshot-properties.js | 2 + .../client-functions/element-utils.js | 16 - .../selector-executor/filter.js | 137 +++++--- .../selector-executor/index.js | 14 +- src/client/driver/driver.js | 28 +- src/client/driver/utils/element-utils.js | 38 ++ src/client/driver/utils/ensure-elements.js | 4 +- src/errors/test-run/index.js | 28 +- src/errors/test-run/templates.js | 35 +- src/test-run/commands/observation.js | 2 + .../api/es-next/iframe-switching/test.js | 4 +- .../fixtures/api/es-next/selector/test.js | 6 +- .../api/es-next/take-screenshot/test.js | 5 +- .../functional/fixtures/api/raw/click/test.js | 5 +- test/functional/fixtures/api/raw/drag/test.js | 10 +- .../api/raw/select-editable-content/test.js | 5 +- .../fixtures/api/raw/upload/test.js | 5 +- .../fixtures/api/typescript/smoke/test.js | 5 +- .../fixtures/regression/gh-1907/test.js | 6 +- .../fixtures/regression/gh-1994/test.js | 4 +- .../regression/gh-2568/pages/index.html | 22 ++ .../fixtures/regression/gh-2568/test.js | 175 ++++++++++ .../gh-2568/testcafe-fixtures/index.js | 128 +++++++ .../action-additional-element-not-found-error | 5 + .../action-element-not-found-error | 5 + ...fo-for-element-specified-by-selector-error | 5 + test/server/test-run-error-formatting-test.js | 8 +- 29 files changed, 867 insertions(+), 263 deletions(-) delete mode 100644 src/client/driver/command-executors/client-functions/element-utils.js create mode 100644 src/client/driver/utils/element-utils.js create mode 100644 test/functional/fixtures/regression/gh-2568/pages/index.html create mode 100644 test/functional/fixtures/regression/gh-2568/test.js create mode 100644 test/functional/fixtures/regression/gh-2568/testcafe-fixtures/index.js diff --git a/src/client-functions/selectors/add-api.js b/src/client-functions/selectors/add-api.js index ff27d6ac..680446d1 100644 --- a/src/client-functions/selectors/add-api.js +++ b/src/client-functions/selectors/add-api.js @@ -1,7 +1,6 @@ import { assign } from 'lodash'; import clientFunctionBuilderSymbol from '../builder-symbol'; -import { ELEMENT_SNAPSHOT_PROPERTIES, NODE_SNAPSHOT_PROPERTIES } from './snapshot-properties'; -import { CantObtainInfoForElementSpecifiedBySelectorError } from '../../errors/test-run'; +import { SNAPSHOT_PROPERTIES } from './snapshot-properties'; import { getCallsiteForMethod } from '../../errors/get-callsite'; import ClientFunctionBuilder from '../client-function-builder'; import ReExecutablePromise from '../../utils/re-executable-promise'; @@ -10,34 +9,31 @@ import makeRegExp from '../../utils/make-reg-exp'; import selectorTextFilter from './selector-text-filter'; import selectorAttributeFilter from './selector-attribute-filter'; -const SNAPSHOT_PROPERTIES = NODE_SNAPSHOT_PROPERTIES.concat(ELEMENT_SNAPSHOT_PROPERTIES); - - -var filterNodes = (new ClientFunctionBuilder((nodes, filter, querySelectorRoot, originNode, ...filterArgs) => { +const filterNodes = (new ClientFunctionBuilder((nodes, filter, querySelectorRoot, originNode, ...filterArgs) => { if (typeof filter === 'number') { - var matchingNode = filter < 0 ? nodes[nodes.length + filter] : nodes[filter]; + const matchingNode = filter < 0 ? nodes[nodes.length + filter] : nodes[filter]; return matchingNode ? [matchingNode] : []; } - var result = []; + const result = []; if (typeof filter === 'string') { // NOTE: we can search for elements only in document or element. if (querySelectorRoot.nodeType !== 1 && querySelectorRoot.nodeType !== 9) return null; - var matching = querySelectorRoot.querySelectorAll(filter); - var matchingArr = []; + const matching = querySelectorRoot.querySelectorAll(filter); + const matchingArr = []; - for (var i = 0; i < matching.length; i++) + for (let i = 0; i < matching.length; i++) matchingArr.push(matching[i]); filter = node => matchingArr.indexOf(node) > -1; } if (typeof filter === 'function') { - for (var j = 0; j < nodes.length; j++) { + for (let j = 0; j < nodes.length; j++) { if (filter(nodes[j], j, originNode, ...filterArgs)) result.push(nodes[j]); } @@ -46,19 +42,19 @@ var filterNodes = (new ClientFunctionBuilder((nodes, filter, querySelectorRoot, return result; })).getFunction(); -var expandSelectorResults = (new ClientFunctionBuilder((selector, populateDerivativeNodes) => { - var nodes = selector(); +const expandSelectorResults = (new ClientFunctionBuilder((selector, populateDerivativeNodes) => { + const nodes = selector(); if (!nodes.length) return null; - var result = []; + const result = []; - for (var i = 0; i < nodes.length; i++) { - var derivativeNodes = populateDerivativeNodes(nodes[i]); + for (let i = 0; i < nodes.length; i++) { + const derivativeNodes = populateDerivativeNodes(nodes[i]); if (derivativeNodes) { - for (var j = 0; j < derivativeNodes.length; j++) { + for (let j = 0; j < derivativeNodes.length; j++) { if (result.indexOf(derivativeNodes[j]) < 0) result.push(derivativeNodes[j]); } @@ -69,9 +65,9 @@ var expandSelectorResults = (new ClientFunctionBuilder((selector, populateDeriva })).getFunction(); -async function getSnapshot (getSelector, callsite) { - var node = null; - var selector = getSelector(); +async function getSnapshot (getSelector, callsite, SelectorBuilder) { + let node = null; + const selector = new SelectorBuilder(getSelector(), { needError: true }, { instantiation: 'Selector' }).getFunction(); try { node = await selector(); @@ -82,9 +78,6 @@ async function getSnapshot (getSelector, callsite) { throw err; } - if (!node) - throw new CantObtainInfoForElementSpecifiedBySelectorError(callsite); - return node; } @@ -107,14 +100,31 @@ function assertAddCustomMethods (properties, opts) { }); } -function addSnapshotProperties (obj, getSelector, properties) { +function prepareApiFnArgs (fnName, ...args) { + args = args.map(arg => { + if (typeof arg === 'string') + return `'${arg}'`; + if (typeof arg === 'function') + return '[function]'; + return arg; + }); + args = args.join(', '); + + return `.${fnName}(${args})`; +} + +function getDerivativeSelectorArgs (options, selectorFn, apiFn, filter, additionalDependencies) { + return Object.assign({}, options, { selectorFn, apiFn, filter, additionalDependencies }); +} + +function addSnapshotProperties (obj, getSelector, SelectorBuilder, properties) { properties.forEach(prop => { Object.defineProperty(obj, prop, { get: () => { - var callsite = getCallsiteForMethod('get'); + const callsite = getCallsiteForMethod('get'); return ReExecutablePromise.fromFn(async () => { - var snapshot = await getSnapshot(getSelector, callsite); + const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder); return snapshot[prop]; }); @@ -146,10 +156,15 @@ export function addCustomMethods (obj, getSelector, SelectorBuilder, customMetho /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, () => true, { + const apiFn = prepareApiFnArgs(prop, ...args); + const filter = () => true; + + const additionalDependencies = { args, customMethod: method - }); + }; + + return createDerivativeSelectorWithFilter({ getSelector, SelectorBuilder, selectorFn, apiFn, filter, additionalDependencies }); }; } else { @@ -164,60 +179,60 @@ export function addCustomMethods (obj, getSelector, SelectorBuilder, customMetho }); } -function addSnapshotPropertyShorthands (obj, getSelector, SelectorBuilder, customDOMProperties, customMethods) { - var properties = SNAPSHOT_PROPERTIES; +function addSnapshotPropertyShorthands ({ obj, getSelector, SelectorBuilder, customDOMProperties, customMethods }) { + let properties = SNAPSHOT_PROPERTIES; if (customDOMProperties) properties = properties.concat(Object.keys(customDOMProperties)); - addSnapshotProperties(obj, getSelector, properties); + addSnapshotProperties(obj, getSelector, SelectorBuilder, properties); addCustomMethods(obj, getSelector, SelectorBuilder, customMethods); obj.getStyleProperty = prop => { - var callsite = getCallsiteForMethod('getStyleProperty'); + const callsite = getCallsiteForMethod('getStyleProperty'); return ReExecutablePromise.fromFn(async () => { - var snapshot = await getSnapshot(getSelector, callsite); + const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder); return snapshot.style ? snapshot.style[prop] : void 0; }); }; obj.getAttribute = attrName => { - var callsite = getCallsiteForMethod('getAttribute'); + const callsite = getCallsiteForMethod('getAttribute'); return ReExecutablePromise.fromFn(async () => { - var snapshot = await getSnapshot(getSelector, callsite); + const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder); return snapshot.attributes ? snapshot.attributes[attrName] : void 0; }); }; obj.hasAttribute = attrName => { - var callsite = getCallsiteForMethod('hasAttribute'); + const callsite = getCallsiteForMethod('hasAttribute'); return ReExecutablePromise.fromFn(async () => { - var snapshot = await getSnapshot(getSelector, callsite); + const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder); return snapshot.attributes ? snapshot.attributes.hasOwnProperty(attrName) : false; }); }; obj.getBoundingClientRectProperty = prop => { - var callsite = getCallsiteForMethod('getBoundingClientRectProperty'); + const callsite = getCallsiteForMethod('getBoundingClientRectProperty'); return ReExecutablePromise.fromFn(async () => { - var snapshot = await getSnapshot(getSelector, callsite); + const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder); return snapshot.boundingClientRect ? snapshot.boundingClientRect[prop] : void 0; }); }; obj.hasClass = name => { - var callsite = getCallsiteForMethod('hasClass'); + const callsite = getCallsiteForMethod('hasClass'); return ReExecutablePromise.fromFn(async () => { - var snapshot = await getSnapshot(getSelector, callsite); + const snapshot = await getSnapshot(getSelector, callsite, SelectorBuilder); return snapshot.classNames ? snapshot.classNames.indexOf(name) > -1 : false; }); @@ -225,9 +240,9 @@ function addSnapshotPropertyShorthands (obj, getSelector, SelectorBuilder, custo } function createCounter (getSelector, SelectorBuilder) { - var builder = new SelectorBuilder(getSelector(), { counterMode: true }, { instantiation: 'Selector' }); - var counter = builder.getFunction(); - var callsite = getCallsiteForMethod('get'); + const builder = new SelectorBuilder(getSelector(), { counterMode: true }, { instantiation: 'Selector' }); + const counter = builder.getFunction(); + const callsite = getCallsiteForMethod('get'); return async () => { try { @@ -241,10 +256,10 @@ function createCounter (getSelector, SelectorBuilder) { }; } -function addCounterProperties (obj, getSelector, SelectorBuilder) { +function addCounterProperties ({ obj, getSelector, SelectorBuilder }) { Object.defineProperty(obj, 'count', { get: () => { - var counter = createCounter(getSelector, SelectorBuilder); + const counter = createCounter(getSelector, SelectorBuilder); return ReExecutablePromise.fromFn(() => counter()); } @@ -252,7 +267,7 @@ function addCounterProperties (obj, getSelector, SelectorBuilder) { Object.defineProperty(obj, 'exists', { get: () => { - var counter = createCounter(getSelector, SelectorBuilder); + const counter = createCounter(getSelector, SelectorBuilder); return ReExecutablePromise.fromFn(async () => await counter() > 0); } @@ -261,9 +276,9 @@ function addCounterProperties (obj, getSelector, SelectorBuilder) { function convertFilterToClientFunctionIfNecessary (callsiteName, filter, dependencies) { if (typeof filter === 'function') { - var builder = filter[clientFunctionBuilderSymbol]; - var fn = builder ? builder.fn : filter; - var options = builder ? assign({}, builder.options, { dependencies }) : { dependencies }; + const builder = filter[clientFunctionBuilderSymbol]; + const fn = builder ? builder.fn : filter; + const options = builder ? assign({}, builder.options, { dependencies }) : { dependencies }; return (new ClientFunctionBuilder(fn, options, { instantiation: callsiteName })).getFunction(); } @@ -271,35 +286,37 @@ function convertFilterToClientFunctionIfNecessary (callsiteName, filter, depende return filter; } -function createDerivativeSelectorWithFilter (getSelector, SelectorBuilder, selectorFn, filter, additionalDependencies) { - var collectionModeSelectorBuilder = new SelectorBuilder(getSelector(), { collectionMode: true }); - var customDOMProperties = collectionModeSelectorBuilder.options.customDOMProperties; - var customMethods = collectionModeSelectorBuilder.options.customMethods; +function createDerivativeSelectorWithFilter ({ getSelector, SelectorBuilder, selectorFn, apiFn, filter, additionalDependencies }) { + const collectionModeSelectorBuilder = new SelectorBuilder(getSelector(), { collectionMode: true }); + const customDOMProperties = collectionModeSelectorBuilder.options.customDOMProperties; + const customMethods = collectionModeSelectorBuilder.options.customMethods; - var dependencies = { + let dependencies = { selector: collectionModeSelectorBuilder.getFunction(), filter: filter, filterNodes: filterNodes }; - var { boundTestRun, timeout, visibilityCheck } = collectionModeSelectorBuilder.options; + const { boundTestRun, timeout, visibilityCheck, apiFnChain } = collectionModeSelectorBuilder.options; dependencies = assign(dependencies, additionalDependencies); - var builder = new SelectorBuilder(selectorFn, { + const builder = new SelectorBuilder(selectorFn, { dependencies, customDOMProperties, customMethods, boundTestRun, timeout, - visibilityCheck + visibilityCheck, + apiFnChain, + apiFn }, { instantiation: 'Selector' }); return builder.getFunction(); } -var filterByText = convertFilterToClientFunctionIfNecessary('filter', selectorTextFilter); -var filterByAttr = convertFilterToClientFunctionIfNecessary('filter', selectorAttributeFilter); +const filterByText = convertFilterToClientFunctionIfNecessary('filter', selectorTextFilter); +const filterByAttr = convertFilterToClientFunctionIfNecessary('filter', selectorAttributeFilter); function ensureRegExpContext (str) { // NOTE: if a regexp is created in a separate context (via the 'vm' module) we @@ -310,11 +327,14 @@ function ensureRegExpContext (str) { return str; } -function addFilterMethods (obj, getSelector, SelectorBuilder) { +function addFilterMethods (options) { + const { obj, getSelector, SelectorBuilder } = options; + obj.nth = index => { assertType(is.number, 'nth', '"index" argument', index); - var builder = new SelectorBuilder(getSelector(), { index: index }, { instantiation: 'Selector' }); + const apiFn = prepareApiFnArgs('nth', index); + const builder = new SelectorBuilder(getSelector(), { index, apiFn }, { instantiation: 'Selector' }); return builder.getFunction(); }; @@ -322,11 +342,13 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) { obj.withText = text => { assertType([is.string, is.regExp], 'withText', '"text" argument', text); + const apiFn = prepareApiFnArgs('withText', text); + text = ensureRegExpContext(text); - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ - var nodes = selector(); + const nodes = selector(); if (!nodes.length) return null; @@ -335,17 +357,17 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filterByText, { - textRe: makeRegExp(text) - }); + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filterByText, { textRe: makeRegExp(text) }); + + return createDerivativeSelectorWithFilter(args); }; obj.withExactText = text => { assertType(is.string, 'withExactText', '"text" argument', text); - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ - var nodes = selector(); + const nodes = selector(); if (!nodes.length) return null; @@ -354,14 +376,17 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filterByText, { - exactText: text - }); + const apiFn = prepareApiFnArgs('withExactText', text); + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filterByText, { exactText: text }); + + return createDerivativeSelectorWithFilter(args); }; obj.withAttribute = (attrName, attrValue) => { assertType([is.string, is.regExp], 'withAttribute', '"attrName" argument', attrName); + const apiFn = prepareApiFnArgs('withAttribute', attrName, attrValue); + attrName = ensureRegExpContext(attrName); if (attrValue !== void 0) { @@ -369,9 +394,9 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) { attrValue = ensureRegExpContext(attrValue); } - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ - var nodes = selector(); + const nodes = selector(); if (!nodes.length) return null; @@ -380,20 +405,24 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filterByAttr, { + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filterByAttr, { attrName, attrValue }); + + return createDerivativeSelectorWithFilter(args); }; obj.filter = (filter, dependencies) => { assertType([is.string, is.function], 'filter', '"filter" argument', filter); + const apiFn = prepareApiFnArgs('filter', filter); + filter = convertFilterToClientFunctionIfNecessary('filter', filter, dependencies); - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ - var nodes = selector(); + const nodes = selector(); if (!nodes.length) return null; @@ -402,33 +431,38 @@ function addFilterMethods (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter); + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter); + + return createDerivativeSelectorWithFilter(args); }; obj.filterVisible = () => { - const builder = new SelectorBuilder(getSelector(), { filterVisible: true }, { instantiation: 'Selector' }); + const apiFn = prepareApiFnArgs('filterVisible'); + const builder = new SelectorBuilder(getSelector(), { filterVisible: true, apiFn }, { instantiation: 'Selector' }); return builder.getFunction(); }; obj.filterHidden = () => { - const builder = new SelectorBuilder(getSelector(), { filterHidden: true }, { instantiation: 'Selector' }); + const apiFn = prepareApiFnArgs('filterHidden'); + const builder = new SelectorBuilder(getSelector(), { filterHidden: true, apiFn }, { instantiation: 'Selector' }); return builder.getFunction(); }; } -function addCustomDOMPropertiesMethod (obj, getSelector, SelectorBuilder) { +function addCustomDOMPropertiesMethod ({ obj, getSelector, SelectorBuilder }) { obj.addCustomDOMProperties = customDOMProperties => { assertAddCustomDOMPropertiesOptions(customDOMProperties); - var builder = new SelectorBuilder(getSelector(), { customDOMProperties }, { instantiation: 'Selector' }); + const builder = new SelectorBuilder(getSelector(), { customDOMProperties }, { instantiation: 'Selector' }); return builder.getFunction(); }; } -function addCustomMethodsMethod (obj, getSelector, SelectorBuilder) { +function addCustomMethodsMethod ({ obj, getSelector, SelectorBuilder }) { obj.addCustomMethods = function (methods, opts) { assertAddCustomMethods(methods, opts); @@ -447,14 +481,18 @@ function addCustomMethodsMethod (obj, getSelector, SelectorBuilder) { }; } -function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { +function addHierarchicalSelectors (options) { + const { obj } = options; + // Find obj.find = (filter, dependencies) => { assertType([is.string, is.function], 'find', '"filter" argument', filter); + const apiFn = prepareApiFnArgs('find', filter); + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ return expandSelectorResults(selector, node => { if (typeof filter === 'string') { @@ -463,13 +501,13 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { null; } - var results = []; + const results = []; - var visitNode = currentNode => { - var cnLength = currentNode.childNodes.length; + const visitNode = currentNode => { + const cnLength = currentNode.childNodes.length; - for (var i = 0; i < cnLength; i++) { - var child = currentNode.childNodes[i]; + for (let i = 0; i < cnLength; i++) { + const child = currentNode.childNodes[i]; results.push(child); @@ -484,7 +522,9 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults }); + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); }; // Parent @@ -492,14 +532,16 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { if (filter !== void 0) assertType([is.string, is.function, is.number], 'parent', '"filter" argument', filter); + const apiFn = prepareApiFnArgs('parent', filter); + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ return expandSelectorResults(selector, node => { - var parents = []; + const parents = []; - for (var parent = node.parentNode; parent; parent = parent.parentNode) + for (let parent = node.parentNode; parent; parent = parent.parentNode) parents.push(parent); return filter !== void 0 ? filterNodes(parents, filter, document, node) : parents; @@ -507,7 +549,9 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults }); + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); }; // Child @@ -515,16 +559,18 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { if (filter !== void 0) assertType([is.string, is.function, is.number], 'child', '"filter" argument', filter); + const apiFn = prepareApiFnArgs('child', filter); + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ return expandSelectorResults(selector, node => { - var childElements = []; - var cnLength = node.childNodes.length; + const childElements = []; + const cnLength = node.childNodes.length; - for (var i = 0; i < cnLength; i++) { - var child = node.childNodes[i]; + for (let i = 0; i < cnLength; i++) { + const child = node.childNodes[i]; if (child.nodeType === 1) childElements.push(child); @@ -535,7 +581,9 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults }); + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); }; // Sibling @@ -543,21 +591,23 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { if (filter !== void 0) assertType([is.string, is.function, is.number], 'sibling', '"filter" argument', filter); + const apiFn = prepareApiFnArgs('sibling', filter); + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ return expandSelectorResults(selector, node => { - var parent = node.parentNode; + const parent = node.parentNode; if (!parent) return null; - var siblings = []; - var cnLength = parent.childNodes.length; + const siblings = []; + const cnLength = parent.childNodes.length; - for (var i = 0; i < cnLength; i++) { - var child = parent.childNodes[i]; + for (let i = 0; i < cnLength; i++) { + const child = parent.childNodes[i]; if (child.nodeType === 1 && child !== node) siblings.push(child); @@ -568,7 +618,9 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults }); + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); }; // Next sibling @@ -576,22 +628,24 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { if (filter !== void 0) assertType([is.string, is.function, is.number], 'nextSibling', '"filter" argument', filter); + const apiFn = prepareApiFnArgs('nextSibling', filter); + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ return expandSelectorResults(selector, node => { - var parent = node.parentNode; + const parent = node.parentNode; if (!parent) return null; - var siblings = []; - var cnLength = parent.childNodes.length; - var afterNode = false; + const siblings = []; + const cnLength = parent.childNodes.length; + let afterNode = false; - for (var i = 0; i < cnLength; i++) { - var child = parent.childNodes[i]; + for (let i = 0; i < cnLength; i++) { + const child = parent.childNodes[i]; if (child === node) afterNode = true; @@ -605,7 +659,9 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults }); + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); }; // Prev sibling @@ -613,21 +669,23 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { if (filter !== void 0) assertType([is.string, is.function, is.number], 'prevSibling', '"filter" argument', filter); + const apiFn = prepareApiFnArgs('prevSibling', filter); + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); - var selectorFn = () => { + const selectorFn = () => { /* eslint-disable no-undef */ return expandSelectorResults(selector, node => { - var parent = node.parentNode; + const parent = node.parentNode; if (!parent) return null; - var siblings = []; - var cnLength = parent.childNodes.length; + const siblings = []; + const cnLength = parent.childNodes.length; - for (var i = 0; i < cnLength; i++) { - var child = parent.childNodes[i]; + for (let i = 0; i < cnLength; i++) { + const child = parent.childNodes[i]; if (child === node) break; @@ -641,16 +699,19 @@ function addHierarchicalSelectors (obj, getSelector, SelectorBuilder) { /* eslint-enable no-undef */ }; - return createDerivativeSelectorWithFilter(getSelector, SelectorBuilder, selectorFn, filter, { expandSelectorResults }); - }; + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + return createDerivativeSelectorWithFilter(args); + }; } -export function addAPI (obj, getSelector, SelectorBuilder, customDOMProperties, customMethods) { - addSnapshotPropertyShorthands(obj, getSelector, SelectorBuilder, customDOMProperties, customMethods); - addCustomDOMPropertiesMethod(obj, getSelector, SelectorBuilder); - addCustomMethodsMethod(obj, getSelector, SelectorBuilder); - addFilterMethods(obj, getSelector, SelectorBuilder); - addHierarchicalSelectors(obj, getSelector, SelectorBuilder); - addCounterProperties(obj, getSelector, SelectorBuilder); +export function addAPI (selector, getSelector, SelectorBuilder, customDOMProperties, customMethods) { + const options = { obj: selector, getSelector, SelectorBuilder, customDOMProperties, customMethods }; + + addFilterMethods(options); + addHierarchicalSelectors(options); + addSnapshotPropertyShorthands(options); + addCustomDOMPropertiesMethod(options); + addCustomMethodsMethod(options); + addCounterProperties(options); } diff --git a/src/client-functions/selectors/selector-builder.js b/src/client-functions/selectors/selector-builder.js index d9ab5cff..a4e77ab5 100644 --- a/src/client-functions/selectors/selector-builder.js +++ b/src/client-functions/selectors/selector-builder.js @@ -13,9 +13,10 @@ import createSnapshotMethods from './create-snapshot-methods'; export default class SelectorBuilder extends ClientFunctionBuilder { constructor (fn, options, callsiteNames) { - var builderFromSelector = fn && fn[functionBuilderSymbol]; - var builderFromPromiseOrSnapshot = fn && fn.selector && fn.selector[functionBuilderSymbol]; - var builder = builderFromSelector || builderFromPromiseOrSnapshot; + const apiFn = options && options.apiFn; + const builderFromSelector = fn && fn[functionBuilderSymbol]; + const builderFromPromiseOrSnapshot = fn && fn.selector && fn.selector[functionBuilderSymbol]; + let builder = builderFromSelector || builderFromPromiseOrSnapshot; builder = builder instanceof SelectorBuilder ? builder : null; @@ -27,20 +28,34 @@ export default class SelectorBuilder extends ClientFunctionBuilder { } super(fn, options, callsiteNames); + + if (!this.options.apiFnChain) { + const fnType = typeof this.fn; + let item = fnType === 'string' ? `'${this.fn}'` : `[${fnType}]`; + + item = `Selector(${item})`; + this.options.apiFn = item; + this.options.apiFnChain = [item]; + } + + if (apiFn) + this.options.apiFnChain.push(apiFn); + + this.options.apiFnID = this.options.apiFnChain.length - 1; } _getCompiledFnCode () { // OPTIMIZATION: if selector was produced from another selector and // it has same dependencies as source selector, then we can // avoid recompilation and just re-use already compiled code. - var hasSameDependenciesAsSourceSelector = this.options.sourceSelectorBuilder && - this.options.sourceSelectorBuilder.options.dependencies === - this.options.dependencies; + const hasSameDependenciesAsSourceSelector = this.options.sourceSelectorBuilder && + this.options.sourceSelectorBuilder.options.dependencies === + this.options.dependencies; if (hasSameDependenciesAsSourceSelector) return this.options.sourceSelectorBuilder.compiledFnCode; - var code = typeof this.fn === 'string' ? + const code = typeof this.fn === 'string' ? `(function(){return document.querySelectorAll(${JSON.stringify(this.fn)});});` : super._getCompiledFnCode(); @@ -49,8 +64,16 @@ export default class SelectorBuilder extends ClientFunctionBuilder { `(function(){ var __f$=${code}; return function(){ - var args = __dependencies$.boundArgs || arguments; - return window['%testCafeSelectorFilter%'](__f$.apply(this, args), __dependencies$.filterOptions); + var args = __dependencies$.boundArgs || arguments; + var selectorFilter = window['%testCafeSelectorFilter%']; + + var nodes = __f$.apply(this, args); + nodes = selectorFilter.cast(nodes); + + if (!nodes.length && !selectorFilter.error) + selectorFilter.error = __dependencies$.apiInfo.apiFnID; + + return selectorFilter.filter(nodes, __dependencies$.filterOptions, __dependencies$.apiInfo); }; })();` ); @@ -64,7 +87,7 @@ export default class SelectorBuilder extends ClientFunctionBuilder { } _executeCommand (args, testRun, callsite) { - var resultPromise = super._executeCommand(args, testRun, callsite); + const resultPromise = super._executeCommand(args, testRun, callsite); this._addBoundArgsSelectorGetter(resultPromise, args); @@ -74,23 +97,45 @@ export default class SelectorBuilder extends ClientFunctionBuilder { return resultPromise; } + _getSourceSelectorBuilderApiFnID () { + let selectorAncestor = this; + + while (selectorAncestor.options.sourceSelectorBuilder) + selectorAncestor = selectorAncestor.options.sourceSelectorBuilder; + + return selectorAncestor.options.apiFnID; + } + getFunctionDependencies () { - var dependencies = super.getFunctionDependencies(); - var customDOMProperties = this.options.customDOMProperties; - var customMethods = this.options.customMethods; + const dependencies = super.getFunctionDependencies(); + + const { + filterVisible, + filterHidden, + counterMode, + collectionMode, + index, + customDOMProperties, + customMethods, + apiFnChain, + boundArgs + } = this.options; return merge({}, dependencies, { filterOptions: { - filterVisible: this.options.filterVisible, - filterHidden: this.options.filterHidden, - counterMode: this.options.counterMode, - collectionMode: this.options.collectionMode, - index: isNullOrUndefined(this.options.index) ? null : this.options.index + filterVisible, + filterHidden, + counterMode, + collectionMode, + index: isNullOrUndefined(index) ? null : index }, - - boundArgs: this.options.boundArgs, - customDOMProperties: customDOMProperties, - customMethods: customMethods + apiInfo: { + apiFnChain, + apiFnID: this._getSourceSelectorBuilderApiFnID() + }, + boundArgs, + customDOMProperties, + customMethods }); } @@ -100,6 +145,8 @@ export default class SelectorBuilder extends ClientFunctionBuilder { fnCode: this.compiledFnCode, args: encodedArgs, dependencies: encodedDependencies, + needError: this.options.needError, + apiFnChain: this.options.apiFnChain, visibilityCheck: !!this.options.visibilityCheck, timeout: this.options.timeout }); @@ -116,7 +163,7 @@ export default class SelectorBuilder extends ClientFunctionBuilder { } _getReplicatorTransforms () { - var transforms = super._getReplicatorTransforms(); + const transforms = super._getReplicatorTransforms(); transforms.push(new SelectorNodeTransform()); @@ -125,7 +172,7 @@ export default class SelectorBuilder extends ClientFunctionBuilder { _addBoundArgsSelectorGetter (obj, selectorArgs) { defineLazyProperty(obj, 'selector', () => { - var builder = new SelectorBuilder(this.getFunction(), { boundArgs: selectorArgs }); + const builder = new SelectorBuilder(this.getFunction(), { boundArgs: selectorArgs }); return builder.getFunction(); }); @@ -138,7 +185,7 @@ export default class SelectorBuilder extends ClientFunctionBuilder { } _processResult (result, selectorArgs) { - var snapshot = super._processResult(result, selectorArgs); + const snapshot = super._processResult(result, selectorArgs); if (snapshot && !this.options.counterMode) { this._addBoundArgsSelectorGetter(snapshot, selectorArgs); @@ -151,3 +198,4 @@ export default class SelectorBuilder extends ClientFunctionBuilder { return snapshot; } } + diff --git a/src/client-functions/selectors/snapshot-properties.js b/src/client-functions/selectors/snapshot-properties.js index e664e3f8..407e1d78 100644 --- a/src/client-functions/selectors/snapshot-properties.js +++ b/src/client-functions/selectors/snapshot-properties.js @@ -40,3 +40,5 @@ export const ELEMENT_SNAPSHOT_PROPERTIES = [ 'clientLeft', 'clientTop' ]; + +export const SNAPSHOT_PROPERTIES = NODE_SNAPSHOT_PROPERTIES.concat(ELEMENT_SNAPSHOT_PROPERTIES); diff --git a/src/client/driver/command-executors/client-functions/element-utils.js b/src/client/driver/command-executors/client-functions/element-utils.js deleted file mode 100644 index 16e114f9..00000000 --- a/src/client/driver/command-executors/client-functions/element-utils.js +++ /dev/null @@ -1,16 +0,0 @@ -import { domUtils, positionUtils } from '../../deps/testcafe-core'; -import { selectElement as selectElementUI } from '../../deps/testcafe-ui'; - -export function exists (el) { - return !!el; -} - -export function visible (el) { - if (!domUtils.isDomElement(el) && !domUtils.isTextNode(el)) - return false; - - if (domUtils.isOptionElement(el) || domUtils.getTagName(el) === 'optgroup') - return selectElementUI.isOptionElementVisible(el); - - return positionUtils.isElementVisible(el); -} diff --git a/src/client/driver/command-executors/client-functions/selector-executor/filter.js b/src/client/driver/command-executors/client-functions/selector-executor/filter.js index 1bdb27d8..939cc637 100644 --- a/src/client/driver/command-executors/client-functions/selector-executor/filter.js +++ b/src/client/driver/command-executors/client-functions/selector-executor/filter.js @@ -1,75 +1,116 @@ import { InvalidSelectorResultError } from '../../../../../errors/test-run'; -import { exists, visible } from '../element-utils'; +import { exists, visible, IsNodeCollection } from '../../../utils/element-utils'; import testCafeCore from '../../../deps/testcafe-core'; import hammerhead from '../../../deps/hammerhead'; -// NOTE: save original ctors and methods because they may be overwritten by page code -var isArray = Array.isArray; -var Node = window.Node; -var HTMLCollection = window.HTMLCollection; -var NodeList = window.NodeList; -var arrayUtils = testCafeCore.arrayUtils; +const arrayUtils = testCafeCore.arrayUtils; +const typeUtils = hammerhead.utils.types; +const nativeMethods = hammerhead.nativeMethods; + +const SELECTOR_FILTER_ERROR = { + filterVisible: 1, + filterHidden: 2, + nth: 3 +}; + +const FILTER_ERROR_TO_API_RE = { + [SELECTOR_FILTER_ERROR.filterVisible]: /^\.filterVisible\(\)$/, + [SELECTOR_FILTER_ERROR.filterHidden]: /^\.filterHidden\(\)$/, + [SELECTOR_FILTER_ERROR.nth]: /^\.nth\(\d+\)$/ +}; + +class SelectorFilter { + constructor () { + this.err = null; + } -function isArrayOfNodes (obj) { - if (!isArray(obj)) - return false; + get error () { + return this.err; + } - for (var i = 0; i < obj.length; i++) { - if (!(obj[i] instanceof Node)) - return false; + set error (message) { + if (this.err === null) + this.err = message; } - return true; -} + filter (node, options, apiInfo) { + let filtered = arrayUtils.filter(node, exists); -function getNodeByIndex (collection, index) { - return index < 0 ? collection[collection.length + index] : collection[index]; -} + if (options.filterVisible) { + filtered = filtered.filter(visible); + this.assertFilterError(filtered, apiInfo, SELECTOR_FILTER_ERROR.filterVisible); + } -// Selector filter -hammerhead.nativeMethods.objectDefineProperty.call(window, window, '%testCafeSelectorFilter%', { - value: (node, options) => { - var filtered = []; + if (options.filterHidden) { + filtered = filtered.filter(n => !visible(n)); - if (node === null || node === void 0) - filtered = []; + this.assertFilterError(filtered, apiInfo, SELECTOR_FILTER_ERROR.filterHidden); + } - else if (node instanceof Node) - filtered = [node]; + if (options.counterMode) { + if (options.index !== null) + filtered = this.getNodeByIndex(filtered, options.index) ? 1 : 0; + else + filtered = filtered.length; + } + else if (options.collectionMode) { + if (options.index !== null) { + const nodeOnIndex = this.getNodeByIndex(filtered, options.index); - else if (node instanceof HTMLCollection || node instanceof NodeList || isArrayOfNodes(node)) - filtered = node; + filtered = nodeOnIndex ? [nodeOnIndex] : []; + } + } + else { + filtered = this.getNodeByIndex(filtered, options.index || 0); - else - throw new InvalidSelectorResultError(); + if (typeof options.index === 'number') + this.assertFilterError(filtered, apiInfo, SELECTOR_FILTER_ERROR.nth); + } - filtered = arrayUtils.filter(filtered, n => exists(n)); + return filtered; + } - if (options.filterVisible) - filtered = filtered.filter(n => visible(n)); + cast (node) { + let result = null; - if (options.filterHidden) - filtered = filtered.filter(n => !visible(n)); + if (typeUtils.isNullOrUndefined(node)) + result = []; - if (options.counterMode) { - if (options.index !== null) - return getNodeByIndex(filtered, options.index) ? 1 : 0; + else if (node instanceof Node) + result = [node]; - return filtered.length; - } + else if (IsNodeCollection(node)) + result = node; - if (options.collectionMode) { - if (options.index !== null) { - var nodeOnIndex = getNodeByIndex(filtered, options.index); + else + throw new InvalidSelectorResultError(); - return nodeOnIndex ? [nodeOnIndex] : []; - } + return result; + } + + assertFilterError (filtered, apiInfo, filterError) { + if (!filtered || filtered.length === 0) + this.error = this.getErrorItem(apiInfo, filterError); + } - return filtered; + getErrorItem ({ apiFnChain, apiFnID }, err) { + if (err) { + for (let i = apiFnID; i < apiFnChain.length; i++) { + if (FILTER_ERROR_TO_API_RE[err].test(apiFnChain[i])) + return i; + } } + return null; + } - return getNodeByIndex(filtered, options.index || 0); - }, + getNodeByIndex (collection, index) { + return index < 0 ? collection[collection.length + index] : collection[index]; + } +} + +// Selector filter +nativeMethods.objectDefineProperty.call(window, window, '%testCafeSelectorFilter%', { + value: new SelectorFilter(), configurable: true }); diff --git a/src/client/driver/command-executors/client-functions/selector-executor/index.js b/src/client/driver/command-executors/client-functions/selector-executor/index.js index 38a8d718..4386afce 100644 --- a/src/client/driver/command-executors/client-functions/selector-executor/index.js +++ b/src/client/driver/command-executors/client-functions/selector-executor/index.js @@ -1,7 +1,7 @@ import { Promise } from '../../../deps/hammerhead'; import { delay } from '../../../deps/testcafe-core'; import ClientFunctionExecutor from '../client-function-executor'; -import { exists, visible } from '../element-utils'; +import { exists, visible } from '../../../utils/element-utils'; import { createReplicator, FunctionTransform, SelectorNodeTransform } from '../replicator'; import './filter'; @@ -34,6 +34,16 @@ export default class SelectorExecutor extends ClientFunctionExecutor { ]); } + _getTimeoutErrorParams () { + const apiFnIndex = window['%testCafeSelectorFilter%'].error; + const apiFnChain = this.command.apiFnChain; + + if (typeof apiFnIndex !== 'undefined') + return { apiFnIndex, apiFnChain }; + + return null; + } + _validateElement (args, startTime) { return Promise.resolve() .then(() => this.fn.apply(window, args)) @@ -50,7 +60,7 @@ export default class SelectorExecutor extends ClientFunctionExecutor { return delay(CHECK_ELEMENT_DELAY).then(() => this._validateElement(args, startTime)); if (createTimeoutError) - throw createTimeoutError(); + throw createTimeoutError(this._getTimeoutErrorParams()); return null; }); diff --git a/src/client/driver/driver.js b/src/client/driver/driver.js index 59b06084..91beed9c 100644 --- a/src/client/driver/driver.js +++ b/src/client/driver/driver.js @@ -27,7 +27,8 @@ import { ActionElementIsInvisibleError, CurrentIframeIsNotLoadedError, CurrentIframeNotFoundError, - CurrentIframeIsInvisibleError + CurrentIframeIsInvisibleError, + CantObtainInfoForElementSpecifiedBySelectorError } from '../../errors/test-run'; import BrowserConsoleMessages from '../../test-run/browser-console-messages'; @@ -48,11 +49,11 @@ import { } from './command-executors/execute-selector'; import ClientFunctionExecutor from './command-executors/client-functions/client-function-executor'; -var transport = hammerhead.transport; -var Promise = hammerhead.Promise; -var messageSandbox = hammerhead.eventSandbox.message; -var storages = hammerhead.storages; - +const transport = hammerhead.transport; +const Promise = hammerhead.Promise; +const messageSandbox = hammerhead.eventSandbox.message; +const storages = hammerhead.storages; +const DateCtor = hammerhead.nativeMethods.date; const TEST_DONE_SENT_FLAG = 'testcafe|driver|test-done-sent-flag'; const PENDING_STATUS = 'testcafe|driver|pending-status'; @@ -302,7 +303,7 @@ export default class Driver { var commandSelectorTimeout = hasSpecificTimeout ? selector.timeout : this.selectorTimeout; return getExecuteSelectorResult(selector, commandSelectorTimeout, null, - () => new iframeErrorCtors.NotFoundError(), () => iframeErrorCtors.IsInvisibleError(), this.statusBar) + fn => new iframeErrorCtors.NotFoundError(fn), () => iframeErrorCtors.IsInvisibleError(), this.statusBar) .then(iframe => { if (!domUtils.isIframeElement(iframe)) throw new ActionElementNotIframeError(); @@ -388,9 +389,16 @@ export default class Driver { } _onExecuteSelectorCommand (command) { - var startTime = this.contextStorage.getItem(SELECTOR_EXECUTION_START_TIME) || new Date(); - - getExecuteSelectorResultDriverStatus(command, this.selectorTimeout, startTime, null, null, this.statusBar) + const startTime = this.contextStorage.getItem(SELECTOR_EXECUTION_START_TIME) || new DateCtor(); + const elementNotFoundOrNotVisible = fn => new CantObtainInfoForElementSpecifiedBySelectorError(null, fn); + const createError = command.needError ? elementNotFoundOrNotVisible : null; + + getExecuteSelectorResultDriverStatus(command, + this.selectorTimeout, + startTime, + createError, + createError, + this.statusBar) .then(driverStatus => { this.contextStorage.setItem(SELECTOR_EXECUTION_START_TIME, null); this._onReady(driverStatus); diff --git a/src/client/driver/utils/element-utils.js b/src/client/driver/utils/element-utils.js new file mode 100644 index 00000000..c88372d8 --- /dev/null +++ b/src/client/driver/utils/element-utils.js @@ -0,0 +1,38 @@ +import { domUtils, positionUtils } from '../deps/testcafe-core'; +import { selectElement as selectElementUI } from '../deps/testcafe-ui'; + +// NOTE: save original ctors and methods because they may be overwritten by page code +const isArray = Array.isArray; +const Node = window.Node; +const HTMLCollection = window.HTMLCollection; +const NodeList = window.NodeList; + +export function exists (el) { + return !!el; +} + +export function visible (el) { + if (!domUtils.isDomElement(el) && !domUtils.isTextNode(el)) + return false; + + if (domUtils.isOptionElement(el) || domUtils.getTagName(el) === 'optgroup') + return selectElementUI.isOptionElementVisible(el); + + return positionUtils.isElementVisible(el); +} + +export function IsNodeCollection (obj) { + return obj instanceof HTMLCollection || obj instanceof NodeList || isArrayOfNodes(obj); +} + +function isArrayOfNodes (obj) { + if (!isArray(obj)) + return false; + + for (let i = 0; i < obj.length; i++) { + if (!(obj[i] instanceof Node)) + return false; + } + + return true; +} diff --git a/src/client/driver/utils/ensure-elements.js b/src/client/driver/utils/ensure-elements.js index abd3ddbe..2a4543cf 100644 --- a/src/client/driver/utils/ensure-elements.js +++ b/src/client/driver/utils/ensure-elements.js @@ -55,7 +55,7 @@ export function ensureElements (elementDescriptors, globalSelectorTimeout) { export function createElementDescriptor (selector) { return { selector: selector, - createNotFoundError: () => new ActionElementNotFoundError(), + createNotFoundError: fn => new ActionElementNotFoundError(fn), createIsInvisibleError: () => new ActionElementIsInvisibleError(), createHasWrongNodeTypeError: nodeDescription => new ActionSelectorMatchesWrongNodeTypeError(nodeDescription) }; @@ -64,7 +64,7 @@ export function createElementDescriptor (selector) { export function createAdditionalElementDescriptor (selector, elementName) { return { selector: selector, - createNotFoundError: () => new ActionAdditionalElementNotFoundError(elementName), + createNotFoundError: fn => new ActionAdditionalElementNotFoundError(elementName, fn), createIsInvisibleError: () => new ActionAdditionalElementIsInvisibleError(elementName), createHasWrongNodeTypeError: nodeDescription => new ActionAdditionalSelectorMatchesWrongNodeTypeError(elementName, nodeDescription) }; diff --git a/src/errors/test-run/index.js b/src/errors/test-run/index.js index d56cafc8..a25cf11f 100644 --- a/src/errors/test-run/index.js +++ b/src/errors/test-run/index.js @@ -63,21 +63,29 @@ export class DomNodeClientFunctionResultError extends TestRunErrorBase { // Selector errors //-------------------------------------------------------------------- +class SelectorErrorBase extends TestRunErrorBase { + constructor (type, { apiFnChain, apiFnIndex }) { + super(type); + + this.apiFnChain = apiFnChain; + this.apiFnIndex = apiFnIndex; + } +} + export class InvalidSelectorResultError extends TestRunErrorBase { constructor () { super(TYPE.invalidSelectorResultError); } } -export class CantObtainInfoForElementSpecifiedBySelectorError extends TestRunErrorBase { - constructor (callsite) { - super(TYPE.cantObtainInfoForElementSpecifiedBySelectorError); +export class CantObtainInfoForElementSpecifiedBySelectorError extends SelectorErrorBase { + constructor (callsite, apiFnArgs) { + super(TYPE.cantObtainInfoForElementSpecifiedBySelectorError, apiFnArgs); this.callsite = callsite; } } - // Page errors //-------------------------------------------------------------------- export class PageLoadError extends TestRunErrorBase { @@ -292,9 +300,9 @@ export class ActionSelectorError extends TestRunErrorBase { // Action execution errors //-------------------------------------------------------------------- -export class ActionElementNotFoundError extends TestRunErrorBase { - constructor () { - super(TYPE.actionElementNotFoundError); +export class ActionElementNotFoundError extends SelectorErrorBase { + constructor (apiFnArgs) { + super(TYPE.actionElementNotFoundError, apiFnArgs); } } @@ -312,9 +320,9 @@ export class ActionSelectorMatchesWrongNodeTypeError extends TestRunErrorBase { } } -export class ActionAdditionalElementNotFoundError extends TestRunErrorBase { - constructor (argumentName) { - super(TYPE.actionAdditionalElementNotFoundError); +export class ActionAdditionalElementNotFoundError extends SelectorErrorBase { + constructor (argumentName, apiFnArgs) { + super(TYPE.actionAdditionalElementNotFoundError, apiFnArgs); this.argumentName = argumentName; } diff --git a/src/errors/test-run/templates.js b/src/errors/test-run/templates.js index e09624bd..765a16a1 100644 --- a/src/errors/test-run/templates.js +++ b/src/errors/test-run/templates.js @@ -16,6 +16,29 @@ const SUBTITLES = { [TEST_RUN_PHASE.inBookmarkRestore]: 'Error while restoring configuration after Role switch\n' }; +function formatSelectorCallstack (apiFnChain, apiFnIndex, viewportWidth) { + if (typeof apiFnIndex === 'undefined') + return ''; + + const emptySpaces = 10; + const ellipsis = '...)'; + const availableWidth = viewportWidth - emptySpaces; + + return apiFnChain.map((apiFn, index) => { + let formattedApiFn = String.fromCharCode(160); + + formattedApiFn += index === apiFnIndex ? '>' : ' '; + formattedApiFn += ' | '; + formattedApiFn += index !== 0 ? ' ' : ''; + formattedApiFn += apiFn; + + if (formattedApiFn.length > availableWidth) + return formattedApiFn.substr(0, availableWidth - emptySpaces) + ellipsis; + + return formattedApiFn; + }).join('\n'); +} + function markup (err, msgMarkup, opts = {}) { msgMarkup = dedent(` ${SUBTITLES[err.testRunPhase]}
${dedent(msgMarkup)}
@@ -153,8 +176,10 @@ export default { The "${err.argumentName}" argument is expected to be a positive integer, but it was ${err.actualValue}. `), - [TYPE.actionElementNotFoundError]: err => markup(err, ` + [TYPE.actionElementNotFoundError]: (err, viewportWidth) => markup(err, ` The specified selector does not match any element in the DOM tree. + + ${ formatSelectorCallstack(err.apiFnChain, err.apiFnIndex, viewportWidth) } `), [TYPE.actionElementIsInvisibleError]: err => markup(err, ` @@ -165,8 +190,10 @@ export default { The specified selector is expected to match a DOM element, but it matches a ${err.nodeDescription} node. `), - [TYPE.actionAdditionalElementNotFoundError]: err => markup(err, ` + [TYPE.actionAdditionalElementNotFoundError]: (err, viewportWidth) => markup(err, ` The specified "${err.argumentName}" does not match any element in the DOM tree. + + ${ formatSelectorCallstack(err.apiFnChain, err.apiFnIndex, viewportWidth) } `), [TYPE.actionAdditionalElementIsInvisibleError]: err => markup(err, ` @@ -256,8 +283,10 @@ export default { ${escapeHtml(err.errMsg)} `), - [TYPE.cantObtainInfoForElementSpecifiedBySelectorError]: err => markup(err, ` + [TYPE.cantObtainInfoForElementSpecifiedBySelectorError]: (err, viewportWidth) => markup(err, ` Cannot obtain information about the node because the specified selector does not match any node in the DOM tree. + + ${ formatSelectorCallstack(err.apiFnChain, err.apiFnIndex, viewportWidth) } `), [TYPE.windowDimensionsOverflowError]: err => markup(err, ` diff --git a/src/test-run/commands/observation.js b/src/test-run/commands/observation.js index ea7f469d..816e6460 100644 --- a/src/test-run/commands/observation.js +++ b/src/test-run/commands/observation.js @@ -45,6 +45,8 @@ export class ExecuteSelectorCommand extends ExecuteClientFunctionCommandBase { return super._getAssignableProperties().concat([ { name: 'visibilityCheck', defaultValue: false }, { name: 'timeout', defaultValue: null }, + { name: 'apiFnChain' }, + { name: 'needError' }, { name: 'index', defaultValue: 0 } ]); } diff --git a/test/functional/fixtures/api/es-next/iframe-switching/test.js b/test/functional/fixtures/api/es-next/iframe-switching/test.js index 28699c55..a21d5cd3 100644 --- a/test/functional/fixtures/api/es-next/iframe-switching/test.js +++ b/test/functional/fixtures/api/es-next/iframe-switching/test.js @@ -56,7 +56,9 @@ describe('[API] t.switchToIframe(), t.switchToMainWindow()', function () { return runTests('./testcafe-fixtures/iframe-switching-test.js', 'Switch to a non-existent iframe', { shouldFail: true }) .catch(function (errs) { - expect(errs[0]).to.contains('The specified selector does not match any element in the DOM tree.'); + expect(errs[0]).to.contains( + 'The specified selector does not match any element in the DOM tree.' + + ' > | Selector(\'#non-existent\')'); expect(errs[0]).to.contains("> 56 | await t.switchToIframe('#non-existent');"); }); }); diff --git a/test/functional/fixtures/api/es-next/selector/test.js b/test/functional/fixtures/api/es-next/selector/test.js index 8b3fd83b..dfee59bf 100644 --- a/test/functional/fixtures/api/es-next/selector/test.js +++ b/test/functional/fixtures/api/es-next/selector/test.js @@ -187,7 +187,8 @@ describe('[API] Selector', function () { }) .catch(function (errs) { expect(errs[0]).contains( - 'Cannot obtain information about the node because the specified selector does not match any node in the DOM tree.' + 'Cannot obtain information about the node because the specified selector does not match any node in the DOM tree.' + + ' > | Selector(\'#someUnknownElement\')' ); expect(errs[0]).contains("> 23 | await Selector('#someUnknownElement').tagName;"); }); @@ -200,7 +201,8 @@ describe('[API] Selector', function () { }) .catch(function (errs) { expect(errs[0]).contains( - 'Cannot obtain information about the node because the specified selector does not match any node in the DOM tree.' + 'Cannot obtain information about the node because the specified selector does not match any node in the DOM tree.' + + ' > | Selector(\'#someUnknownElement\')' ); expect(errs[0]).contains("> 27 | await Selector('#someUnknownElement').getStyleProperty('width');"); }); diff --git a/test/functional/fixtures/api/es-next/take-screenshot/test.js b/test/functional/fixtures/api/es-next/take-screenshot/test.js index 1fddb8e5..b5a0cd33 100644 --- a/test/functional/fixtures/api/es-next/take-screenshot/test.js +++ b/test/functional/fixtures/api/es-next/take-screenshot/test.js @@ -402,7 +402,10 @@ describe('[API] t.takeElementScreenshot()', function () { only: 'chrome' }) .catch(function (errs) { - expect(errs[0]).to.contains('The specified selector does not match any element in the DOM tree.'); + expect(errs[0]).to.contains( + 'The specified selector does not match any element in the DOM tree.' + + ' > | Selector(\'table\')' + ); expect(errs[0]).to.contains( ' 49 | .click(\'#remove\')' + ' > 50 | .takeElementScreenshot(\'table\', \'custom/\' + t.ctx.parsedUA.family + \'.png\');' + diff --git a/test/functional/fixtures/api/raw/click/test.js b/test/functional/fixtures/api/raw/click/test.js index a272eda3..18f6a3f4 100644 --- a/test/functional/fixtures/api/raw/click/test.js +++ b/test/functional/fixtures/api/raw/click/test.js @@ -60,7 +60,10 @@ describe('[Raw API] Click action', function () { it("Should fail if an action target doesn't exist", function () { return runTests('./testcafe-fixtures/click.testcafe', 'Click non-existent button', { shouldFail: true }) .catch(function (errs) { - expect(errs[0]).contains('The specified selector does not match any element in the DOM tree.'); + expect(errs[0]).contains( + 'The specified selector does not match any element in the DOM tree.' + + ' > | Selector(\'#new-button\')' + ); expect(errs[0]).contains('[[Click non-existent button callsite]]'); }); }); diff --git a/test/functional/fixtures/api/raw/drag/test.js b/test/functional/fixtures/api/raw/drag/test.js index 8ffa522b..394d731d 100644 --- a/test/functional/fixtures/api/raw/drag/test.js +++ b/test/functional/fixtures/api/raw/drag/test.js @@ -22,7 +22,10 @@ describe('[Raw API] Drag actions', function () { it("Should fail if a dragged element doesn't exist", function () { return runTests('./testcafe-fixtures/drag.testcafe', 'Drag non-existent element to another element', { shouldFail: true }) .catch(function (errs) { - expect(errs[0]).contains('The specified selector does not match any element in the DOM tree.'); + expect(errs[0]).contains( + 'The specified selector does not match any element in the DOM tree.' + + ' > | Selector(\'#non-existent\')' + ); expect(errs[0]).contains('[[Drag non-existent element to another element callsite]]'); }); }); @@ -38,7 +41,10 @@ describe('[Raw API] Drag actions', function () { it("Should fail if a destination element doesn't exist", function () { return runTests('./testcafe-fixtures/drag.testcafe', 'Drag to non-existent element', { shouldFail: true }) .catch(function (errs) { - expect(errs[0]).contains('The specified "destinationSelector" does not match any element in the DOM tree.'); + expect(errs[0]).contains( + 'The specified "destinationSelector" does not match any element in the DOM tree.' + + ' > | Selector(\'#non-existent\')' + ); expect(errs[0]).contains('[[Drag to non-existent element callsite]]'); }); }); diff --git a/test/functional/fixtures/api/raw/select-editable-content/test.js b/test/functional/fixtures/api/raw/select-editable-content/test.js index a7f96b70..ace80497 100644 --- a/test/functional/fixtures/api/raw/select-editable-content/test.js +++ b/test/functional/fixtures/api/raw/select-editable-content/test.js @@ -12,7 +12,10 @@ describe('[Raw API] Select editable content', function () { it("Should fail if a start element doesn't exist", function () { return runTests('./testcafe-fixtures/select-editable-content.testcafe', 'Select editable content in non-existent div', { shouldFail: true }) .catch(function (errs) { - expect(errs[0]).contains('The specified "startSelector" does not match any element in the DOM tree.'); + expect(errs[0]).contains( + 'The specified "startSelector" does not match any element in the DOM tree.' + + ' > | Selector(\'#new-div\')' + ); expect(errs[0]).contains('[[Select editable content in non-existent div callsite]]'); }); }); diff --git a/test/functional/fixtures/api/raw/upload/test.js b/test/functional/fixtures/api/raw/upload/test.js index a915ca3c..f7feb8de 100644 --- a/test/functional/fixtures/api/raw/upload/test.js +++ b/test/functional/fixtures/api/raw/upload/test.js @@ -44,7 +44,10 @@ describe('[Raw API] Upload', function () { it('Should clear the upload', function () { return runTests('./testcafe-fixtures/upload.testcafe', 'Clear the upload', { shouldFail: true }) .catch(function (errs) { - expect(errs[0]).contains('The specified selector does not match any element in the DOM tree.'); + expect(errs[0]).contains( + 'The specified selector does not match any element in the DOM tree.' + + ' > | Selector(\'#button\')' + ); }); }); diff --git a/test/functional/fixtures/api/typescript/smoke/test.js b/test/functional/fixtures/api/typescript/smoke/test.js index 43d6b17c..f6e63a9f 100644 --- a/test/functional/fixtures/api/typescript/smoke/test.js +++ b/test/functional/fixtures/api/typescript/smoke/test.js @@ -8,7 +8,10 @@ describe('[TypeScript] Smoke tests', function () { it('Should produce correct callsites on error', function () { return runTests('./testcafe-fixtures/callsite-test.ts', null, { shouldFail: true }) .catch(function (errs) { - expect(errs[0]).contains('The specified selector does not match any element in the DOM tree.'); + expect(errs[0]).contains( + 'The specified selector does not match any element in the DOM tree.' + + ' > | Selector(\'#heyheyhey\')' + ); expect(errs[0]).contains('> 5 |async function doSmthg(selector: string, t: any): Promise { await (t).click(selector); }'); }); }); diff --git a/test/functional/fixtures/regression/gh-1907/test.js b/test/functional/fixtures/regression/gh-1907/test.js index 9c4cb9c0..3e15be84 100644 --- a/test/functional/fixtures/regression/gh-1907/test.js +++ b/test/functional/fixtures/regression/gh-1907/test.js @@ -11,7 +11,11 @@ describe('[Regression](GH-1907)', function () { shouldFail: true }) .catch(function (errs) { - expect(errs[0]).contains('Cannot obtain information about the node because the specified selector does not match any node in the DOM tree.'); + expect(errs[0]).contains( + 'Cannot obtain information about the node because the specified selector does not match any node in the DOM tree. ' + + ' | Selector(\'#hidden\')' + + ' | .withText(\'Hidden\')' + ); expect(errs[0]).contains('> 40 | await t.expect(div.textContent).eql(\'Hidden\');'); }); }); diff --git a/test/functional/fixtures/regression/gh-1994/test.js b/test/functional/fixtures/regression/gh-1994/test.js index 045c1886..b5ecf57d 100644 --- a/test/functional/fixtures/regression/gh-1994/test.js +++ b/test/functional/fixtures/regression/gh-1994/test.js @@ -8,7 +8,9 @@ describe('[Regression](GH-1994)', function () { it('Click on hidden element removed on timeout', function () { return runTests('./testcafe-fixtures/index.js', 'Remove invisible element and click', { shouldFail: true, selectorTimeout: 1000 }) .catch(function (errs) { - expect(errs[0]).contains('The specified selector does not match any element in the DOM tree.'); + expect(errs[0]).contains( + 'The specified selector does not match any element in the DOM tree.' + + ' > | Selector(\'#targetRemove\')'); }); }); diff --git a/test/functional/fixtures/regression/gh-2568/pages/index.html b/test/functional/fixtures/regression/gh-2568/pages/index.html new file mode 100644 index 00000000..33dd3dce --- /dev/null +++ b/test/functional/fixtures/regression/gh-2568/pages/index.html @@ -0,0 +1,22 @@ + + + + Title + + +
+ + +
loren ipsum
+
loren ipsum
+
loren bipsum
+
+
+
+
1
+
+ 2 +
3
+
+ + \ No newline at end of file diff --git a/test/functional/fixtures/regression/gh-2568/test.js b/test/functional/fixtures/regression/gh-2568/test.js new file mode 100644 index 00000000..0ea2c20e --- /dev/null +++ b/test/functional/fixtures/regression/gh-2568/test.js @@ -0,0 +1,175 @@ +const expect = require('chai').expect; + +function removeWhitespaces (str) { + return str.replace(/\s+|\n/g, ' ').trim(); +} + +function assertSelectorCallstack (actual, expected) { + expect(removeWhitespaces(actual)).contains(removeWhitespaces(expected)); +} + +describe('[Regression](GH-2568)', function () { + it('nested selector', function () { + return runTests('testcafe-fixtures/index.js', 'nested selector', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + | Selector('div') + > | .filter('.non-existing-class') + | .filterVisible() + `); + }); + }); + + it('client function selector', function () { + return runTests('testcafe-fixtures/index.js', 'client function selector', { selectorTimeout: 100, shouldFail: true, }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + > | Selector([function]) + | .filterVisible() + `); + }); + }); + + it('nested client function selector', function () { + return runTests('testcafe-fixtures/index.js', 'nested client function selector', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + | Selector([function]) + | .withText('loren') + | .filter([function]) + > | .filter([function]) + | .filterVisible() + `); + }); + }); + + it('nth', function () { + return runTests('testcafe-fixtures/index.js', 'nth', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + | Selector('div') + | .filter('.filtered') + | .withText('loren') + | .withExactText('loren ipsum') + | .withAttribute('attr', '3') + | .filterVisible() + > | .nth(500) + `); + }); + }); + + it('filterVisible', function () { + return runTests('testcafe-fixtures/index.js', 'filterVisible', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + | Selector('div') + | .filter('.filtered') + | .withText('loren') + | .withExactText('loren ipsum') + | .withAttribute('attr', '1') + > | .filterVisible() + | .nth(0) + `); + }); + }); + + it('filterHidden', function () { + return runTests('testcafe-fixtures/index.js', 'filterHidden', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + | Selector('div') + | .filter('.filtered') + | .withText('loren') + | .withExactText('loren ipsum') + | .withAttribute('attr', '3') + > | .filterHidden() + | .nth(0) + `); + }); + }); + + it('withAttribute', function () { + return runTests('testcafe-fixtures/index.js', 'withAttribute', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + | Selector('div') + | .filter('.filtered') + | .withText('loren') + | .withExactText('loren ipsum') + > | .withAttribute('attr', '4') + | .filterVisible() + | .nth(0) + `); + }); + }); + + it('root', function () { + return runTests('testcafe-fixtures/index.js', 'root', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + > | Selector('divf') + | .filter('.filtered') + | .withText('loren') + | .withExactText('loren ipsum') + | .withAttribute('attr', '3') + | .filterVisible() + | .nth(500) + `); + }); + }); + + it('parent', function () { + return runTests('testcafe-fixtures/index.js', 'parent', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + | Selector('body') + | .find('div.parent > div') + | .nextSibling() + > | .parent('span') + | .child('p') + `); + }); + }); + + it('snapshot', function () { + return runTests('testcafe-fixtures/index.js', 'snapshot', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + Cannot obtain information about the node because the specified selector does not match any node in the DOM tree. + > | Selector('ul li') + | .filter('test') + `); + }); + }); + + it('custom DOM properties', function () { + return runTests('testcafe-fixtures/index.js', 'custom DOM properties', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + Cannot obtain information about the node because the specified selector does not match any node in the DOM tree. + > | Selector('ul li') + `); + }); + }); + + it('custom methods', function () { + return runTests('testcafe-fixtures/index.js', 'custom methods', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + | Selector('div') + > | .customFilter('1', 2, [object Object], /regexp/, [function]) + | .withText('loren') + `); + }); + }); +}); diff --git a/test/functional/fixtures/regression/gh-2568/testcafe-fixtures/index.js b/test/functional/fixtures/regression/gh-2568/testcafe-fixtures/index.js new file mode 100644 index 00000000..e108dd4a --- /dev/null +++ b/test/functional/fixtures/regression/gh-2568/testcafe-fixtures/index.js @@ -0,0 +1,128 @@ +import { Selector } from 'testcafe'; + +fixture `GH-2568` + .page `http://localhost:3000/fixtures/regression/gh-2568/pages/index.html`; + +test('nested selector', async t => { + await t.click(Selector(Selector(Selector(Selector(Selector('div'))).filter('.non-existing-class'))).filterVisible()); +}); + +test('client function selector', async t => { + await t.click(Selector(function () { + return document.querySelectorAll('b'); + }).filterVisible()); +}); + +test('nested client function selector', async t => { + await t.click(Selector(function () { + return document.querySelectorAll('div'); + }) + .withText('loren') + .filter(function () { + return true; + }) + .filter(function () { + return false; + }) + .filterVisible()); +}); + +test('nth', async t => { + const selector = Selector('div') + .filter('.filtered') + .withText('loren') + .withExactText('loren ipsum') + .withAttribute('attr', '3') + .filterVisible() + .nth(500); + + await t.click(selector); +}); + +test('filterVisible', async t => { + const selector = Selector('div') + .filter('.filtered') + .withText('loren') + .withExactText('loren ipsum') + .withAttribute('attr', '1') + .filterVisible() + .nth(0); + + await t.click(selector); +}); + +test('filterHidden', async t => { + const selector = Selector('div') + .filter('.filtered') + .withText('loren') + .withExactText('loren ipsum') + .withAttribute('attr', '3') + .filterHidden() + .nth(0); + + await t.click(selector); +}); + +test('withAttribute', async t => { + const selector = Selector('div') + .filter('.filtered') + .withText('loren') + .withExactText('loren ipsum') + .withAttribute('attr', '4') + .filterVisible() + .nth(0); + + await t.click(selector); +}); + +test('root', async t => { + const selector = Selector('divf') + .filter('.filtered') + .withText('loren') + .withExactText('loren ipsum') + .withAttribute('attr', '3') + .filterVisible() + .nth(500); + + await t.click(selector); +}); + +test('parent', async t => { + const selector = Selector('body') + .find('div.parent > div') + .nextSibling() + .parent('span') + .child('p'); + + await t.click(selector); +}); + +test('drag', async t => { + const selector = Selector('div.parent').child('ul'); + + await t.dragToElement('div.parent', selector); +}); + +test('snapshot', async () => { + await Selector('ul li').filter('test').hasClass('yo'); +}); + +test('custom DOM properties', async t => { + const selector = Selector('ul li').addCustomDOMProperties({ + innerHTML: el => el.innerHTML + }); + + await t.expect(selector.innerHTML).eql('test'); +}); + +test('custom methods', async t => { + let selector = Selector('div').addCustomMethods({ + customFilter: nodes => nodes.filter(node => !!node.id) + }, { returnDOMNodes: true }); + + selector = selector + .customFilter('1', 2, { key: 'value' }, new RegExp('regexp'), () => {}) + .withText('loren'); + + await t.click(selector); +}); diff --git a/test/server/data/expected-test-run-errors/action-additional-element-not-found-error b/test/server/data/expected-test-run-errors/action-additional-element-not-found-error index 18a1fa37..e4083aa1 100644 --- a/test/server/data/expected-test-run-errors/action-additional-element-not-found-error +++ b/test/server/data/expected-test-run-errors/action-additional-element-not-found-error @@ -1,5 +1,10 @@ The specified "startSelector" does not match any element in the DOM tree. +  | Lorem ipsum dolor sit amet, consectetur adipiscing el...) + > | one +  | two +  | three + Browser: Chrome 15.0.874 / Mac OS X 10.8.1 Screenshot: /unix/path/with/ diff --git a/test/server/data/expected-test-run-errors/action-element-not-found-error b/test/server/data/expected-test-run-errors/action-element-not-found-error index 9d9ef542..c1d79d84 100644 --- a/test/server/data/expected-test-run-errors/action-element-not-found-error +++ b/test/server/data/expected-test-run-errors/action-element-not-found-error @@ -1,5 +1,10 @@ The specified selector does not match any element in the DOM tree. +  | Lorem ipsum dolor sit amet, consectetur adipiscing el...) + > | one +  | two +  | three + Browser: Chrome 15.0.874 / Mac OS X 10.8.1 Screenshot: /unix/path/with/ diff --git a/test/server/data/expected-test-run-errors/cant-obtain-info-for-element-specified-by-selector-error b/test/server/data/expected-test-run-errors/cant-obtain-info-for-element-specified-by-selector-error index 70be3c9e..1bcb1c77 100644 --- a/test/server/data/expected-test-run-errors/cant-obtain-info-for-element-specified-by-selector-error +++ b/test/server/data/expected-test-run-errors/cant-obtain-info-for-element-specified-by-selector-error @@ -1,6 +1,11 @@ Cannot obtain information about the node because the specified selector does not match any node in the DOM tree. +  | Lorem ipsum dolor sit amet, consectetur adipiscing el...) + > | one +  | two +  | three + Browser: Chrome 15.0.874 / Mac OS X 10.8.1 Screenshot: /unix/path/with/ diff --git a/test/server/test-run-error-formatting-test.js b/test/server/test-run-error-formatting-test.js index 855a43b9..3e05bbec 100644 --- a/test/server/test-run-error-formatting-test.js +++ b/test/server/test-run-error-formatting-test.js @@ -84,6 +84,8 @@ const testAssertionError = (function () { return null; })(); +const longSelector = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'; + // Output stream and errorDecorator mocks function createOutStreamMock () { return { @@ -184,7 +186,7 @@ describe('Error formatting', function () { }); it('Should format "actionElementNotFoundError" message', function () { - assertErrorMessage('action-element-not-found-error', new ActionElementNotFoundError()); + assertErrorMessage('action-element-not-found-error', new ActionElementNotFoundError({ apiFnChain: [longSelector, 'one', 'two', 'three'], apiFnIndex: 1 })); }); it('Should format "actionElementIsInvisibleError" message', function () { @@ -224,7 +226,7 @@ describe('Error formatting', function () { }); it('Should format "actionAdditionalElementNotFoundError" message', function () { - assertErrorMessage('action-additional-element-not-found-error', new ActionAdditionalElementNotFoundError('startSelector')); + assertErrorMessage('action-additional-element-not-found-error', new ActionAdditionalElementNotFoundError('startSelector', { apiFnChain: [longSelector, 'one', 'two', 'three'], apiFnIndex: 1 })); }); it('Should format "actionAdditionalElementIsInvisibleError" message', function () { @@ -324,7 +326,7 @@ describe('Error formatting', function () { }); it('Should format "cantObtainInfoForElementSpecifiedBySelectorError"', function () { - assertErrorMessage('cant-obtain-info-for-element-specified-by-selector-error', new CantObtainInfoForElementSpecifiedBySelectorError(testCallsite)); + assertErrorMessage('cant-obtain-info-for-element-specified-by-selector-error', new CantObtainInfoForElementSpecifiedBySelectorError(testCallsite, { apiFnChain: [longSelector, 'one', 'two', 'three'], apiFnIndex: 1 })); }); it('Should format "windowDimensionsOverflowError"', function () { From 5be879e3b9e772dd6a0acc442b8adb0f49874cdb Mon Sep 17 00:00:00 2001 From: aleks-pro Date: Thu, 23 Aug 2018 09:29:58 +0300 Subject: [PATCH 062/184] setNativeDialogHandler command added to RAW API (#2749) * initialize native dialog handler from raw api * tests added --- src/test-run/commands/actions.js | 11 +- .../native-dialogs-handling/pages/index.html | 22 +++ .../api/raw/native-dialogs-handling/test.js | 34 +++++ .../native-dialogs-test.testcafe | 129 ++++++++++++++++++ 4 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 test/functional/fixtures/api/raw/native-dialogs-handling/pages/index.html create mode 100644 test/functional/fixtures/api/raw/native-dialogs-handling/test.js create mode 100644 test/functional/fixtures/api/raw/native-dialogs-handling/testcafe-fixtures/native-dialogs-test.testcafe diff --git a/src/test-run/commands/actions.js b/src/test-run/commands/actions.js index 3ef70a46..079b0c55 100644 --- a/src/test-run/commands/actions.js +++ b/src/test-run/commands/actions.js @@ -5,6 +5,8 @@ import functionBuilderSymbol from '../../client-functions/builder-symbol'; import CommandBase from './base'; import { ActionOptions, ClickOptions, MouseOptions, TypeOptions, DragToElementOptions } from './options'; import { initSelector, initUploadSelector } from './validations/initializers'; +import { executeJsExpression } from '../execute-js-expression'; +import { isJSExpression } from './utils'; import { actionOptions, @@ -44,8 +46,13 @@ function initDragToElementOptions (name, val) { return new DragToElementOptions(val, true); } -function initDialogHandler (name, val) { - var fn = val.fn; +function initDialogHandler (name, val, { skipVisibilityCheck, testRun }) { + var fn; + + if (isJSExpression(val)) + fn = executeJsExpression(val.value, testRun, { skipVisibilityCheck }); + else + fn = val.fn; if (fn === null || fn instanceof ExecuteClientFunctionCommand) return fn; diff --git a/test/functional/fixtures/api/raw/native-dialogs-handling/pages/index.html b/test/functional/fixtures/api/raw/native-dialogs-handling/pages/index.html new file mode 100644 index 00000000..69a335c0 --- /dev/null +++ b/test/functional/fixtures/api/raw/native-dialogs-handling/pages/index.html @@ -0,0 +1,22 @@ + + + + + Title + + + + + +
+ + + diff --git a/test/functional/fixtures/api/raw/native-dialogs-handling/test.js b/test/functional/fixtures/api/raw/native-dialogs-handling/test.js new file mode 100644 index 00000000..b0a43bb7 --- /dev/null +++ b/test/functional/fixtures/api/raw/native-dialogs-handling/test.js @@ -0,0 +1,34 @@ +var pageUrl = 'http://localhost:3000/fixtures/api/es-next/native-dialogs-handling/pages/index.html'; +var errorInEachBrowserContains = require('../../../../assertion-helper.js').errorInEachBrowserContains; +var getNativeDialogNotHandledErrorText = require('../../es-next/native-dialogs-handling/errors.js').getNativeDialogNotHandledErrorText; + +describe('Native dialogs handling', function () { + it('Should pass if the expected confirm dialog appears after an action', function () { + return runTests('./testcafe-fixtures/native-dialogs-test.testcafe', 'Expected confirm after an action'); + }); + + it('Should pass if the expected confirm dialog appears after an action (client function)', function () { + return runTests('./testcafe-fixtures/native-dialogs-test.testcafe', 'Expected confirm after an action (client function)'); + }); + + it('Should fail if Selector send as dialog handler', function () { + return runTests('./testcafe-fixtures/native-dialogs-test.testcafe', 'Selector as dialogHandler', { shouldFail: true }) + .catch(function (errs) { + errorInEachBrowserContains(errs, 'The native dialog handler is expected to be a function, ClientFunction or null, but it was Selector.', 0); + }); + }); + + it('Should fail if dialog handler has wrong type', function () { + return runTests('./testcafe-fixtures/native-dialogs-test.testcafe', 'Dialog handler has wrong type', { shouldFail: true }) + .catch(function (errs) { + errorInEachBrowserContains(errs, 'The native dialog handler is expected to be a function, ClientFunction or null, but it was number.', 0); + }); + }); + + it('Should remove dialog handler if `null` specified', function () { + return runTests('./testcafe-fixtures/native-dialogs-test.testcafe', 'Null handler', { shouldFail: true }) + .catch(function (errs) { + errorInEachBrowserContains(errs, getNativeDialogNotHandledErrorText('alert', pageUrl), 0); + }); + }); +}); diff --git a/test/functional/fixtures/api/raw/native-dialogs-handling/testcafe-fixtures/native-dialogs-test.testcafe b/test/functional/fixtures/api/raw/native-dialogs-handling/testcafe-fixtures/native-dialogs-test.testcafe new file mode 100644 index 00000000..e4f69a40 --- /dev/null +++ b/test/functional/fixtures/api/raw/native-dialogs-handling/testcafe-fixtures/native-dialogs-test.testcafe @@ -0,0 +1,129 @@ +{ + "fixtures": [ + { + "name": "Native dialogs", + "pageUrl": "http://localhost:3000/fixtures/api/es-next/native-dialogs-handling/pages/index.html", + "tests": [ + { + "name": "Expected confirm after an action", + "commands": [ + { + "type": "set-native-dialog-handler", + "dialogHandler": { + "type": "js-expr", + "value": "(type, text) => {\r\n if (type === 'confirm' && text === 'Confirm?')\r\n return true;\r\n\r\n return null;\r\n}" + } + }, + { + "selector": { + "type": "js-expr", + "value": "'#buttonConfirm'" + }, + "type": "click" + }, + { + "type": "assertion", + "assertionType": "eql", + "actual": { + "type": "js-expr", + "value": "Selector('#result').textContent" + }, + "expected": { + "type": "js-expr", + "value": "'true'" + } + } + ] + }, + { + "name": "Expected confirm after an action (client function)", + "commands": [ + { + "type": "set-native-dialog-handler", + "dialogHandler": { + "type": "js-expr", + "value": "ClientFunction((type, text) => {\r\n if (type === 'confirm' && text === 'Confirm?')\r\n return true;\r\n\r\n return null;\r\n})" + } + }, + { + "selector": { + "type": "js-expr", + "value": "'#buttonConfirm'" + }, + "type": "click" + }, + { + "type": "assertion", + "assertionType": "eql", + "actual": { + "type": "js-expr", + "value": "Selector('#result').textContent" + }, + "expected": { + "type": "js-expr", + "value": "'true'" + } + } + ] + }, + { + "name": "Selector as dialogHandler", + "commands": [ + { + "type": "set-native-dialog-handler", + "dialogHandler": { + "type": "js-expr", + "value": "Selector(() => document.body)" + } + } + ] + }, + { + "name": "Dialog handler has wrong type", + "commands": [ + { + "type": "set-native-dialog-handler", + "dialogHandler": { + "type": "js-expr", + "value": "42" + } + } + ] + }, + { + "name": "Null handler", + "commands": [ + { + "type": "set-native-dialog-handler", + "dialogHandler": { + "type": "js-expr", + "value": "() => true" + } + }, + { + "selector": { + "type": "js-expr", + "value": "'#buttonAlert'" + }, + "type": "click" + }, + { + "type": "set-native-dialog-handler", + "dialogHandler": { + "type": "js-expr", + "value": "null" + } + }, + { + "selector": { + "type": "js-expr", + "value": "'#buttonAlert'" + }, + "type": "click" + } + ] + } + ] + } + ] +} \ No newline at end of file From c37db3c4311035aa722a5fdf51b836e7b7a0206e Mon Sep 17 00:00:00 2001 From: Artem Lavrov Date: Thu, 23 Aug 2018 14:08:22 +0300 Subject: [PATCH 063/184] update hammerhead (#2743) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 21edd426..08b6da0f 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.5", - "testcafe-hammerhead": "14.2.4", + "testcafe-hammerhead": "14.2.5", "testcafe-legacy-api": "3.1.7", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", From 10c2e1178df1576c52f24af3bf7e7e4454f94917 Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Thu, 23 Aug 2018 16:00:10 +0300 Subject: [PATCH 064/184] [docs] selector callstack (#2733) --- .../selectors/using-selectors.md | 8 +++++--- docs/articles/images/failed-selector-report.png | Bin 0 -> 99964 bytes 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 docs/articles/images/failed-selector-report.png diff --git a/docs/articles/documentation/test-api/selecting-page-elements/selectors/using-selectors.md b/docs/articles/documentation/test-api/selecting-page-elements/selectors/using-selectors.md index 60e66adc..6b72061c 100644 --- a/docs/articles/documentation/test-api/selecting-page-elements/selectors/using-selectors.md +++ b/docs/articles/documentation/test-api/selecting-page-elements/selectors/using-selectors.md @@ -181,7 +181,9 @@ method if you use API or specify the [selector-timeout](../../../using-testcafe/ if you run TestCafe from the command line. Within the selector timeout, the selector is executed over and over again, until it returns a -DOM node or the timeout exceeds. +DOM node or the timeout exceeds. If TestCafe cannot find the corresponding node in the DOM, the test fails. The test report shows a sequence of the selector's methods that were called during the test and highlights the failed method. This helps you understand what caused the fail. -Note that you can additionally require that the node returned by the selector is visible. -To do this, use the [visibilityCheck](selector-options.md#optionsvisibilitycheck) option. +![Selector methods in reports](../../../../images/failed-selector-report.png) + +> Note that you can require that the node returned by the selector is visible. +To do this, use the [visibilityCheck](selector-options.md#optionsvisibilitycheck) option. \ No newline at end of file diff --git a/docs/articles/images/failed-selector-report.png b/docs/articles/images/failed-selector-report.png new file mode 100644 index 0000000000000000000000000000000000000000..c5467393e19136077f92d07cb3c4daa11be24d4f GIT binary patch literal 99964 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%0DxqD53Xgo+5_!AY8}eq&}5%Ht{UaY8)8s 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 Date: Thu, 23 Aug 2018 18:02:23 +0300 Subject: [PATCH 065/184] Fix supported Node version in README (#2767) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 42cb7fce..0f8172c9 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ Check out [TestCafe Studio](https://testcafe-studio.devexpress.com): all the per ### Installation -Ensure that [Node.js](https://nodejs.org/) (version 4 or newer) and [npm](https://www.npmjs.com/) are installed on your computer before running it: +Ensure that [Node.js](https://nodejs.org/) (version 6 or newer) and [npm](https://www.npmjs.com/) are installed on your computer before running it: ```sh npm install -g testcafe From 433d6089cd115afa30e6bbfa6a873eedbd1f66c6 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Fri, 24 Aug 2018 10:43:03 +0300 Subject: [PATCH 066/184] Reduce number of created temp dirs for profiles (closes #2735, closes #2013) (#2740) * Reduce number of created temp dirs for profiles (closes #2735) * Add test * Remove temp dirs in a separate process * Fix tests * Fix remarks --- .../built-in/chrome/create-temp-profile.js | 10 +- src/browser/provider/built-in/chrome/index.js | 3 + .../provider/built-in/chrome/local-chrome.js | 4 +- .../provider/built-in/chrome/runtime-info.js | 22 +-- .../built-in/firefox/create-temp-profile.js | 8 +- .../provider/built-in/firefox/index.js | 3 + .../built-in/firefox/local-firefox.js | 4 +- .../provider/utils/kill-browser-process.js | 38 ----- src/utils/kill-browser-process.js | 63 ++++++++ src/utils/promisified-functions.js | 3 + .../cleanup-process/commands.js | 5 + .../temp-directory/cleanup-process/index.js | 136 ++++++++++++++++++ .../temp-directory/cleanup-process/worker.js | 72 ++++++++++ src/utils/temp-directory/index.js | 116 +++++++++++++++ src/utils/temp-directory/lockfile.js | 64 +++++++++ test/functional/assertion-helper.js | 4 +- test/server/util-test.js | 58 ++++++++ 17 files changed, 540 insertions(+), 73 deletions(-) delete mode 100644 src/browser/provider/utils/kill-browser-process.js create mode 100644 src/utils/kill-browser-process.js create mode 100644 src/utils/temp-directory/cleanup-process/commands.js create mode 100644 src/utils/temp-directory/cleanup-process/index.js create mode 100644 src/utils/temp-directory/cleanup-process/worker.js create mode 100644 src/utils/temp-directory/index.js create mode 100644 src/utils/temp-directory/lockfile.js diff --git a/src/browser/provider/built-in/chrome/create-temp-profile.js b/src/browser/provider/built-in/chrome/create-temp-profile.js index 63efba2d..073a82a1 100644 --- a/src/browser/provider/built-in/chrome/create-temp-profile.js +++ b/src/browser/provider/built-in/chrome/create-temp-profile.js @@ -1,13 +1,11 @@ import path from 'path'; -import tmp from 'tmp'; +import TempDirectory from '../../../../utils/temp-directory'; import { writeFile, ensureDir } from '../../../../utils/promisified-functions'; export default async function (proxyHostName) { - tmp.setGracefulCleanup(); - - const tempDir = tmp.dirSync({ unsafeCleanup: true }); - const profileDirName = path.join(tempDir.name, 'Default'); + const tempDir = await TempDirectory.createDirectory('chrome-profile'); + const profileDirName = path.join(tempDir.path, 'Default'); await ensureDir(profileDirName); @@ -39,7 +37,7 @@ export default async function (proxyHostName) { }; await writeFile(path.join(profileDirName, 'Preferences'), JSON.stringify(preferences)); - await writeFile(path.join(tempDir.name, 'First Run'), ''); + await writeFile(path.join(tempDir.path, 'First Run'), ''); return tempDir; } diff --git a/src/browser/provider/built-in/chrome/index.js b/src/browser/provider/built-in/chrome/index.js index 12a4ca4c..cfd0cc3e 100644 --- a/src/browser/provider/built-in/chrome/index.js +++ b/src/browser/provider/built-in/chrome/index.js @@ -46,6 +46,9 @@ export default { if (OS.mac || runtimeInfo.config.headless) await stopLocalChrome(runtimeInfo); + if (runtimeInfo.tempProfileDir) + await runtimeInfo.tempProfileDir.dispose(); + delete this.openedBrowsers[browserId]; }, diff --git a/src/browser/provider/built-in/chrome/local-chrome.js b/src/browser/provider/built-in/chrome/local-chrome.js index 62649cbf..9a652375 100644 --- a/src/browser/provider/built-in/chrome/local-chrome.js +++ b/src/browser/provider/built-in/chrome/local-chrome.js @@ -1,5 +1,5 @@ import browserTools from 'testcafe-browser-tools'; -import killBrowserProcess from '../../utils/kill-browser-process'; +import killBrowserProcess from '../../../../utils/kill-browser-process'; import BrowserStarter from '../../utils/browser-starter'; @@ -9,7 +9,7 @@ function buildChromeArgs (config, cdpPort, platformArgs, profileDir) { return [] .concat( cdpPort ? [`--remote-debugging-port=${cdpPort}`] : [], - !config.userProfile ? [`--user-data-dir=${profileDir.name}`] : [], + !config.userProfile ? [`--user-data-dir=${profileDir.path}`] : [], config.headless ? ['--headless'] : [], config.userArgs ? [config.userArgs] : [], platformArgs ? [platformArgs] : [] diff --git a/src/browser/provider/built-in/chrome/runtime-info.js b/src/browser/provider/built-in/chrome/runtime-info.js index ab291b09..cb68ac36 100644 --- a/src/browser/provider/built-in/chrome/runtime-info.js +++ b/src/browser/provider/built-in/chrome/runtime-info.js @@ -3,26 +3,10 @@ import getConfig from './config'; import createTempProfile from './create-temp-profile'; -var commonTempProfile = null; - -async function getTempProfile (proxyHostName, config) { - - var tempProfile = commonTempProfile; - var shouldUseCommonProfile = !config.headless && !config.emulation; - - if (!shouldUseCommonProfile || !commonTempProfile) - tempProfile = await createTempProfile(proxyHostName); - - if (shouldUseCommonProfile && !commonTempProfile) - commonTempProfile = tempProfile; - - return tempProfile; -} - export default async function (proxyHostName, configString) { - var config = getConfig(configString); - var tempProfileDir = !config.userProfile ? await getTempProfile(proxyHostName, config) : null; - var cdpPort = config.cdpPort || (!config.userProfile ? await getFreePort() : null); + const config = getConfig(configString); + const tempProfileDir = !config.userProfile ? await createTempProfile(proxyHostName, config) : null; + const cdpPort = config.cdpPort || (!config.userProfile ? await getFreePort() : null); return { config, cdpPort, tempProfileDir }; } diff --git a/src/browser/provider/built-in/firefox/create-temp-profile.js b/src/browser/provider/built-in/firefox/create-temp-profile.js index c30e7f88..5d5283b9 100644 --- a/src/browser/provider/built-in/firefox/create-temp-profile.js +++ b/src/browser/provider/built-in/firefox/create-temp-profile.js @@ -1,5 +1,5 @@ import path from 'path'; -import tmp from 'tmp'; +import TempDirectory from '../../../../utils/temp-directory'; import { writeFile } from '../../../../utils/promisified-functions'; @@ -54,11 +54,9 @@ async function generatePreferences (profileDir, { marionettePort, config }) { } export default async function (runtimeInfo) { - tmp.setGracefulCleanup(); + const tmpDir = await TempDirectory.createDirectory('firefox-profile'); - const tmpDir = tmp.dirSync({ unsafeCleanup: true }); - - await generatePreferences(tmpDir.name, runtimeInfo); + await generatePreferences(tmpDir.path, runtimeInfo); return tmpDir; } diff --git a/src/browser/provider/built-in/firefox/index.js b/src/browser/provider/built-in/firefox/index.js index bbb3aa1c..92fed99c 100644 --- a/src/browser/provider/built-in/firefox/index.js +++ b/src/browser/provider/built-in/firefox/index.js @@ -53,6 +53,9 @@ export default { if (OS.mac && !config.headless) await stopLocalFirefox(runtimeInfo); + if (runtimeInfo.tempProfileDir) + await runtimeInfo.tempProfileDir.dispose(); + delete this.openedBrowsers[browserId]; }, diff --git a/src/browser/provider/built-in/firefox/local-firefox.js b/src/browser/provider/built-in/firefox/local-firefox.js index 75aff2cb..a480fcdc 100644 --- a/src/browser/provider/built-in/firefox/local-firefox.js +++ b/src/browser/provider/built-in/firefox/local-firefox.js @@ -1,6 +1,6 @@ import OS from 'os-family'; import browserTools from 'testcafe-browser-tools'; -import killBrowserProcess from '../../utils/kill-browser-process'; +import killBrowserProcess from '../../../../utils/kill-browser-process'; import BrowserStarter from '../../utils/browser-starter'; @@ -18,7 +18,7 @@ function buildFirefoxArgs (config, platformArgs, { marionettePort, tempProfileDi return [] .concat( marionettePort ? ['-marionette'] : [], - !config.userProfile ? ['-no-remote', '-new-instance', `-profile "${tempProfileDir.name}"`] : [], + !config.userProfile ? ['-no-remote', '-new-instance', `-profile "${tempProfileDir.path}"`] : [], config.headless ? ['-headless'] : [], config.userArgs ? [config.userArgs] : [], platformArgs ? [platformArgs] : [] diff --git a/src/browser/provider/utils/kill-browser-process.js b/src/browser/provider/utils/kill-browser-process.js deleted file mode 100644 index 563d0231..00000000 --- a/src/browser/provider/utils/kill-browser-process.js +++ /dev/null @@ -1,38 +0,0 @@ -import OS from 'os-family'; -import { findProcess, killProcess, exec } from '../../../utils/promisified-functions'; - - -const BROWSER_CLOSING_TIMEOUT = 5; - -async function findProcessWin (processOptions) { - var cmd = `wmic process where "commandline like '%${processOptions.arguments}%' and name <> 'cmd.exe' and name <> 'wmic.exe'" get processid`; - var wmicOutput = await exec(cmd); - var processList = wmicOutput.split(/\s*\n/); - - processList = processList - // NOTE: remove list's header and empty last element, caused by trailing newline - .slice(1, -1) - .map(pid => ({ pid: Number(pid) })); - - return processList; -} - -export default async function (browserId) { - var processOptions = { arguments: browserId, psargs: 'aux' }; - var processList = OS.win ? await findProcessWin(processOptions) : await findProcess(processOptions); - - if (!processList.length) - return true; - - try { - if (OS.win) - process.kill(processList[0].pid); - else - await killProcess(processList[0].pid, { timeout: BROWSER_CLOSING_TIMEOUT }); - - return true; - } - catch (e) { - return false; - } -} diff --git a/src/utils/kill-browser-process.js b/src/utils/kill-browser-process.js new file mode 100644 index 00000000..d1171619 --- /dev/null +++ b/src/utils/kill-browser-process.js @@ -0,0 +1,63 @@ +import { spawn } from 'child_process'; +import OS from 'os-family'; +import promisifyEvent from 'promisify-event'; +import Promise from 'pinkie'; +import { findProcess, killProcess } from './promisified-functions'; + + +const BROWSER_CLOSING_TIMEOUT = 5; + +async function runWMIC (args) { + const wmicProcess = spawn('wmic.exe', args, { detached: true }); + + let wmicOutput = ''; + + wmicProcess.stdout.on('data', data => { + wmicOutput += data.toString(); + }); + + try { + await Promise.race([ + promisifyEvent(wmicProcess.stdout, 'end'), + promisifyEvent(wmicProcess, 'error') + ]); + + return wmicOutput; + } + catch (e) { + return ''; + } +} + +async function findProcessWin (processOptions) { + var wmicArgs = ['process', 'where', `commandline like '%${processOptions.arguments}%' and name <> 'cmd.exe' and name <> 'wmic.exe'`, 'get', 'processid']; + var wmicOutput = await runWMIC(wmicArgs); + var processList = wmicOutput.split(/\s*\n/); + + processList = processList + // NOTE: remove list's header and empty last element, caused by trailing newline + .slice(1, -1) + .map(pid => ({ pid: Number(pid) })); + + return processList; +} + +export default async function (browserId) { + var processOptions = { arguments: browserId, psargs: '-ef' }; + var processList = OS.win ? await findProcessWin(processOptions) : await findProcess(processOptions); + + if (!processList.length) + return true; + + try { + if (OS.win) + process.kill(processList[0].pid); + else + await killProcess(processList[0].pid, { timeout: BROWSER_CLOSING_TIMEOUT }); + + return true; + } + catch (e) { + return false; + } +} diff --git a/src/utils/promisified-functions.js b/src/utils/promisified-functions.js index a6aa010a..5f0095a5 100644 --- a/src/utils/promisified-functions.js +++ b/src/utils/promisified-functions.js @@ -6,6 +6,7 @@ import promisify from './promisify'; export const ensureDir = promisify(mkdirp); +export const readDir = promisify(fs.readdir); export const stat = promisify(fs.stat); export const writeFile = promisify(fs.writeFile); export const readFile = promisify(fs.readFile); @@ -15,3 +16,5 @@ export const findProcess = promisify(psNode.lookup); export const killProcess = promisify(psNode.kill); export const exec = promisify(childProcess.exec); + +export const sendMessageToChildProcess = promisify((process, ...args) => process.send(...args)); diff --git a/src/utils/temp-directory/cleanup-process/commands.js b/src/utils/temp-directory/cleanup-process/commands.js new file mode 100644 index 00000000..619f22f5 --- /dev/null +++ b/src/utils/temp-directory/cleanup-process/commands.js @@ -0,0 +1,5 @@ +export default { + init: 'init', + add: 'add', + remove: 'remove' +}; diff --git a/src/utils/temp-directory/cleanup-process/index.js b/src/utils/temp-directory/cleanup-process/index.js new file mode 100644 index 00000000..a7b30893 --- /dev/null +++ b/src/utils/temp-directory/cleanup-process/index.js @@ -0,0 +1,136 @@ +import { spawn } from 'child_process'; +import debug from 'debug'; +import promisifyEvent from 'promisify-event'; +import Promise from 'pinkie'; +import { sendMessageToChildProcess } from '../../promisified-functions'; +import COMMANDS from './commands'; + + +const WORKER_PATH = require.resolve('./worker'); +const WORKER_STDIO_CONFIG = ['ignore', 'ignore', 'ignore', 'ipc']; + +const DEBUG_LOGGER = debug('testcafe:utils:temp-directory:cleanup-process'); + +class CleanupProcess { + constructor () { + this.worker = null; + this.initialized = false; + this.initPromise = Promise.resolve(void 0); + + this.messageCounter = 0; + + this.pendingResponses = {}; + } + + _sendMessage (id, msg) { + return sendMessageToChildProcess(this.worker, { id, ...msg }); + } + + _onResponse (response) { + const pendingResponse = this.pendingResponses[response.id]; + + if (response.error) { + if (pendingResponse) + pendingResponse.control.reject(response.error); + else + this.pendingResponses[response.id] = Promise.reject(response.error); + } + else if (pendingResponse) + pendingResponse.control.resolve(); + else + this.pendingResponses[response.id] = Promise.resolve(); + } + + async _waitResponse (id) { + if (!this.pendingResponses[id]) { + const promiseControl = {}; + + this.pendingResponses[id] = new Promise((resolve, reject) => { + Object.assign(promiseControl, { resolve, reject }); + }); + + this.pendingResponses[id].control = promiseControl; + } + + try { + await this.pendingResponses[id]; + } + finally { + delete this.pendingResponses[id]; + } + } + + async _waitResponseForMessage (msg) { + const currentId = this.messageCounter; + + this.messageCounter++; + + await this._sendMessage(currentId, msg); + await this._waitResponse(currentId); + } + + init () { + this.initPromise = this.initPromise + .then(async initialized => { + if (initialized !== void 0) + return initialized; + + this.worker = spawn(process.argv[0], [WORKER_PATH], { detached: true, stdio: WORKER_STDIO_CONFIG }); + + this.worker.on('message', message => this._onResponse(message)); + + this.worker.unref(); + + try { + await Promise.race([ + this._waitResponseForMessage({ command: COMMANDS.init }), + promisifyEvent(this.worker, 'error') + ]); + + const channel = this.worker.channel || this.worker._channel; + + channel.unref(); + + this.initialized = true; + } + catch (e) { + DEBUG_LOGGER('Failed to start cleanup process'); + DEBUG_LOGGER(e); + + this.initialized = false; + } + + return this.initialized; + }); + + return this.initPromise; + } + + async addDirectory (path) { + if (!this.initialized) + return; + + try { + await this._waitResponseForMessage({ command: COMMANDS.add, path }); + } + catch (e) { + DEBUG_LOGGER(`Failed to add the ${path} directory to cleanup process`); + DEBUG_LOGGER(e); + } + } + + async removeDirectory (path) { + if (!this.initialized) + return; + + try { + await this._waitResponseForMessage({ command: COMMANDS.remove, path }); + } + catch (e) { + DEBUG_LOGGER(`Failed to remove the ${path} directory in cleanup process`); + DEBUG_LOGGER(e); + } + } +} + +export default new CleanupProcess(); diff --git a/src/utils/temp-directory/cleanup-process/worker.js b/src/utils/temp-directory/cleanup-process/worker.js new file mode 100644 index 00000000..987eb119 --- /dev/null +++ b/src/utils/temp-directory/cleanup-process/worker.js @@ -0,0 +1,72 @@ +import path from 'path'; +import { inspect } from 'util'; +import del from 'del'; +import Promise from 'pinkie'; +import { noop } from 'lodash'; +import killBrowserProcess from '../../kill-browser-process'; +import COMMANDS from './commands'; + + +const DIRECTORIES_TO_CLEANUP = {}; + +function addDirectory (dirPath) { + if (!DIRECTORIES_TO_CLEANUP[dirPath]) + DIRECTORIES_TO_CLEANUP[dirPath] = {}; +} + +async function removeDirectory (dirPath) { + if (!DIRECTORIES_TO_CLEANUP[dirPath]) + return; + + let delPromise = DIRECTORIES_TO_CLEANUP[dirPath].delPromise; + + if (!delPromise) { + delPromise = killBrowserProcess(path.basename(dirPath)) + .then(() => del(dirPath, { force: true })); + + DIRECTORIES_TO_CLEANUP[dirPath].delPromise = delPromise; + } + + await DIRECTORIES_TO_CLEANUP[dirPath].delPromise; + + delete DIRECTORIES_TO_CLEANUP[dirPath].delPromise; +} + +async function dispatchCommand (message) { + switch (message.command) { + case COMMANDS.init: + return; + case COMMANDS.add: + addDirectory(message.path); + return; + case COMMANDS.remove: + addDirectory(message.path); + await removeDirectory(message.path); + return; + } +} + +process.on('message', async message => { + let error = ''; + + try { + await dispatchCommand(message); + } + catch (e) { + error = inspect(e); + } + + process.send({ id: message.id, error }); +}); + +process.on('disconnect', async () => { + const removePromises = Object + .keys(DIRECTORIES_TO_CLEANUP) + .map(dirPath => removeDirectory(dirPath).catch(noop)); + + await Promise.all(removePromises); + + process.exit(0); //eslint-disable-line no-process-exit +}); + + diff --git a/src/utils/temp-directory/index.js b/src/utils/temp-directory/index.js new file mode 100644 index 00000000..0df94003 --- /dev/null +++ b/src/utils/temp-directory/index.js @@ -0,0 +1,116 @@ +import debug from 'debug'; +import os from 'os'; +import path from 'path'; +import setupExitHook from 'async-exit-hook'; +import tmp from 'tmp'; +import LockFile from './lockfile'; +import cleanupProcess from './cleanup-process'; +import { ensureDir, readDir } from '../../utils/promisified-functions'; + + +// NOTE: mutable for testing purposes +const TESTCAFE_TMP_DIRS_ROOT = path.join(os.tmpdir(), 'testcafe'); +const DEFAULT_NAME_PREFIX = 'tmp'; +const USED_TEMP_DIRS = {}; +const DEBUG_LOGGER = debug('testcafe:utils:temp-directory'); + +export default class TempDirectory { + constructor (namePrefix) { + this.namePrefix = namePrefix || DEFAULT_NAME_PREFIX; + + this.path = ''; + this.lockFile = null; + } + + async _getTmpDirsList () { + const tmpDirNames = await readDir(TempDirectory.TEMP_DIRECTORIES_ROOT); + + return tmpDirNames + .filter(tmpDir => !USED_TEMP_DIRS[tmpDir]) + .filter(tmpDir => path.basename(tmpDir).startsWith(this.namePrefix)); + } + + async _findFreeTmpDir (tmpDirNames) { + for (const tmpDirName of tmpDirNames) { + const tmpDirPath = path.join(TempDirectory.TEMP_DIRECTORIES_ROOT, tmpDirName); + + const lockFile = new LockFile(tmpDirPath); + + if (lockFile.init()) { + this.path = tmpDirPath; + this.lockFile = lockFile; + + return true; + } + } + + return false; + } + + async _createNewTmpDir () { + this.path = tmp.tmpNameSync({ dir: TempDirectory.TEMP_DIRECTORIES_ROOT, prefix: this.namePrefix + '-' }); + + await ensureDir(this.path); + + this.lockFile = new LockFile(this.path); + + this.lockFile.init(); + } + + _disposeSync () { + if (!USED_TEMP_DIRS[this.path]) + return; + + this.lockFile.dispose(); + + delete USED_TEMP_DIRS[this.path]; + } + + static async createDirectory (prefix) { + const tmpDir = new TempDirectory(prefix); + + await tmpDir.init(); + + return tmpDir; + } + + static disposeDirectoriesSync () { + Object.values(USED_TEMP_DIRS).forEach(tmpDir => tmpDir._disposeSync()); + } + + async init () { + await ensureDir(TempDirectory.TEMP_DIRECTORIES_ROOT); + + const tmpDirNames = await this._getTmpDirsList(this.namePrefix); + + DEBUG_LOGGER('Found temp directories:', tmpDirNames); + + const existingTmpDirFound = await this._findFreeTmpDir(tmpDirNames); + + if (!existingTmpDirFound) + await this._createNewTmpDir(); + + DEBUG_LOGGER('Temp directory path: ', this.path); + + await cleanupProcess.init(); + await cleanupProcess.addDirectory(this.path); + + USED_TEMP_DIRS[this.path] = this; + } + + async dispose () { + if (!USED_TEMP_DIRS[this.path]) + return; + + this.lockFile.dispose(); + + await cleanupProcess.removeDirectory(this.path); + + delete USED_TEMP_DIRS[this.path]; + } +} + +// NOTE: exposed for testing purposes +TempDirectory.TEMP_DIRECTORIES_ROOT = TESTCAFE_TMP_DIRS_ROOT; + +setupExitHook(TempDirectory.disposeDirectoriesSync); diff --git a/src/utils/temp-directory/lockfile.js b/src/utils/temp-directory/lockfile.js new file mode 100644 index 00000000..fb9857a2 --- /dev/null +++ b/src/utils/temp-directory/lockfile.js @@ -0,0 +1,64 @@ +import path from 'path'; +import debug from 'debug'; +import fs from 'fs'; + + +const LOCKFILE_NAME = '.testcafe-lockfile'; +const STALE_LOCKFILE_AGE = 2 * 24 * 60 * 60 * 1000; +const DEBUG_LOGGER = debug('testcafe:utils:temp-directory:lockfile'); + +export default class LockFile { + constructor (dirPath) { + this.path = path.join(dirPath, LOCKFILE_NAME); + } + + _open ({ force = false } = {}) { + try { + fs.writeFileSync(this.path, '', { flag: force ? 'w' : 'wx' }); + + return true; + } + catch (e) { + DEBUG_LOGGER('Failed to init lockfile ' + this.path); + DEBUG_LOGGER(e); + + return false; + } + } + + _isStale () { + const currentMs = Date.now(); + + try { + const { mtimeMs } = fs.statSync(this.path); + + return currentMs - mtimeMs > STALE_LOCKFILE_AGE; + } + catch (e) { + DEBUG_LOGGER('Failed to check status of lockfile ' + this.path); + DEBUG_LOGGER(e); + + return false; + } + } + + init () { + if (this._open()) + return true; + + if (this._isStale()) + return this._open({ force: true }); + + return false; + } + + dispose () { + try { + fs.unlinkSync(this.path); + } + catch (e) { + DEBUG_LOGGER('Failed to dispose lockfile ' + this.path); + DEBUG_LOGGER(e); + } + } +} diff --git a/test/functional/assertion-helper.js b/test/functional/assertion-helper.js index 439c31b6..5b6291c1 100644 --- a/test/functional/assertion-helper.js +++ b/test/functional/assertion-helper.js @@ -311,7 +311,9 @@ exports.isScreenshotsEqual = function (customPath, referenceImagePathGetter) { exports.removeScreenshotDir = function () { if (isDirExists(SCREENSHOTS_PATH)) - del(SCREENSHOTS_PATH); + return del(SCREENSHOTS_PATH); + + return Promise.resolve(); }; exports.SCREENSHOTS_PATH = SCREENSHOTS_PATH; diff --git a/test/server/util-test.js b/test/server/util-test.js index 66138f4f..097e9ce7 100644 --- a/test/server/util-test.js +++ b/test/server/util-test.js @@ -1,8 +1,12 @@ const path = require('path'); +const fs = require('fs'); +const del = require('del'); const expect = require('chai').expect; const correctFilePath = require('../../lib/utils/correct-file-path'); const escapeUserAgent = require('../../lib/utils/escape-user-agent'); const parseFileList = require('../../lib/utils/parse-file-list'); +const TempDirectory = require('../../lib/utils/temp-directory'); + describe('Utils', () => { it('Correct File Path', () => { @@ -62,4 +66,58 @@ describe('Utils', () => { }); }); }); + + describe('Temp Directory', function () { + const TMP_ROOT = path.join(process.cwd(), '__tmp__'); + + const savedTmpRoot = TempDirectory.TEMP_DIRECTORIES_ROOT; + + beforeEach(() => { + TempDirectory.TEMP_DIRECTORIES_ROOT = TMP_ROOT; + + return del(TMP_ROOT); + }); + + afterEach(() => { + TempDirectory.TEMP_DIRECTORIES_ROOT = savedTmpRoot; + + return del(TMP_ROOT); + }); + + it('Should reuse existing temp directories after synchronous disposal', function () { + const tempDir1 = new TempDirectory(); + const tempDir2 = new TempDirectory(); + const tempDir3 = new TempDirectory(); + + return tempDir1 + .init() + .then(() => tempDir2.init()) + .then(() => tempDir1._disposeSync()) + .then(() => tempDir3.init()) + .then(() => { + const subDirs = fs.readdirSync(TempDirectory.TEMP_DIRECTORIES_ROOT); + + expect(subDirs.length).eql(2); + expect(tempDir3.path).eql(tempDir1.path); + }); + }); + + it('Should remove temp directories after asynchronous disposal', function () { + const tempDir = new TempDirectory(); + + return tempDir + .init() + .then(() => { + const subDirs = fs.readdirSync(TempDirectory.TEMP_DIRECTORIES_ROOT); + + expect(subDirs.length).eql(1); + }) + .then(() => tempDir.dispose()) + .then(() => { + const subDirs = fs.readdirSync(TempDirectory.TEMP_DIRECTORIES_ROOT); + + expect(subDirs.length).eql(0); + }); + }); + }); }); From 38453b3fea792270916db897761a6e8ae827a424 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 24 Aug 2018 11:41:22 +0300 Subject: [PATCH 067/184] Fix #2522 (#2769) --- .../attaching-hooks-to-tests-and-fixtures.md | 8 ++++---- .../specifying-which-requests-are-handled-by-the-hook.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/articles/documentation/test-api/intercepting-http-requests/attaching-hooks-to-tests-and-fixtures.md b/docs/articles/documentation/test-api/intercepting-http-requests/attaching-hooks-to-tests-and-fixtures.md index f8914d28..3ced586f 100644 --- a/docs/articles/documentation/test-api/intercepting-http-requests/attaching-hooks-to-tests-and-fixtures.md +++ b/docs/articles/documentation/test-api/intercepting-http-requests/attaching-hooks-to-tests-and-fixtures.md @@ -9,20 +9,20 @@ checked: true To attach a hook to a test or fixture, use the `fixture.requestHooks` and `test.requestHooks` methods. A hook attached to a fixture handles requests from all tests in the fixture. ```text -fixture.requestHooks(...hook) -test.requestHooks(...hook) +fixture.requestHooks(...hooks) +test.requestHooks(...hooks) ``` You can also attach and detach hooks during test run using the `t.addRequestHooks` and `t.removeRequestHooks` methods. ```text -t.addRequestHooks(...hook) +t.addRequestHooks(...hooks) t.removeRequestHooks(...hooks) ``` Parameter | Type | Description --------- | ---- | ------------ -`hook` | RequestHook subclass | A `RequestLogger`, `RequestMock` or custom user-defined hook. +`hooks` | RequestHook subclass | A `RequestLogger`, `RequestMock` or custom user-defined hook. The `fixture.requestHooks`, `test.requestHooks` `t.addRequestHooks` and `t.removeRequestHooks` methods use the rest operator which allows you to pass multiple hooks as parameters or arrays of hooks. diff --git a/docs/articles/documentation/test-api/intercepting-http-requests/specifying-which-requests-are-handled-by-the-hook.md b/docs/articles/documentation/test-api/intercepting-http-requests/specifying-which-requests-are-handled-by-the-hook.md index 0ff5616c..fb72cd3d 100644 --- a/docs/articles/documentation/test-api/intercepting-http-requests/specifying-which-requests-are-handled-by-the-hook.md +++ b/docs/articles/documentation/test-api/intercepting-http-requests/specifying-which-requests-are-handled-by-the-hook.md @@ -39,7 +39,7 @@ const logger = RequestLogger(/.co.uk/); ```js const mock = RequestMock() - .onRequestTo('/\/api\/users\//') + .onRequestTo(/\/api\/users\//) .respond(/*...*/); ``` From 5652bee6dd5896dc66b9701c97dd713ad5c7ced8 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 24 Aug 2018 12:29:34 +0300 Subject: [PATCH 068/184] Add a note about .NET requirements for browser actions (#2770) --- docs/articles/documentation/test-api/actions/resize-window.md | 4 ++-- .../documentation/test-api/actions/take-screenshot.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/articles/documentation/test-api/actions/resize-window.md b/docs/articles/documentation/test-api/actions/resize-window.md index ac8549cc..53266207 100644 --- a/docs/articles/documentation/test-api/actions/resize-window.md +++ b/docs/articles/documentation/test-api/actions/resize-window.md @@ -8,12 +8,12 @@ checked: true There are three ways of resizing a browser window. -**Note**: these actions require a [ICCCM/EWMH-compliant window manager](https://en.wikipedia.org/wiki/Comparison_of_X_window_managers) on Linux. - * [Setting the Window Size](#setting-the-window-size) * [Fitting the Window into a Particular Device](#fitting-the-window-into-a-particular-device) * [Maximizing the Window](#maximizing-the-window) +**Note**: these actions require .NET 4.0 or newer installed on Windows machines and an [ICCCM/EWMH-compliant window manager](https://en.wikipedia.org/wiki/Comparison_of_X_window_managers) on Linux. + ## Setting the Window Size ```text diff --git a/docs/articles/documentation/test-api/actions/take-screenshot.md b/docs/articles/documentation/test-api/actions/take-screenshot.md index de3c1268..44f9d15c 100644 --- a/docs/articles/documentation/test-api/actions/take-screenshot.md +++ b/docs/articles/documentation/test-api/actions/take-screenshot.md @@ -8,7 +8,7 @@ checked: true This topic describes how to take screenshots of the tested page. -**Note**: these actions require an [ICCCM/EWMH-compliant window manager](https://en.wikipedia.org/wiki/Comparison_of_X_window_managers) on Linux. +**Note**: these actions require .NET 4.0 or newer installed on Windows machines and an [ICCCM/EWMH-compliant window manager](https://en.wikipedia.org/wiki/Comparison_of_X_window_managers) on Linux. > Important! Screenshot actions are ignored if the screenshot directory is not specified with the [runner.screenshots](../../using-testcafe/programming-interface/runner.md#screenshots) API method or the [screenshots](../../using-testcafe/command-line-interface.md#-s-path---screenshots-path) command line option. From d2efee9ddbd2855acece030d82b52349039150a4 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Mon, 27 Aug 2018 14:35:53 +0300 Subject: [PATCH 069/184] Update the hooks parameter in TS definitions (#2772) --- ts-defs/index.d.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ts-defs/index.d.ts b/ts-defs/index.d.ts index 9d141a2d..0fecd4d1 100644 --- a/ts-defs/index.d.ts +++ b/ts-defs/index.d.ts @@ -1270,15 +1270,15 @@ interface TestController { /** * Attaches the hooks during a test run * - * @param hook - The set of RequestHook subclasses + * @param hooks - The set of RequestHook subclasses */ - addRequestHooks(...hook: object[]): TestControllerPromise; + addRequestHooks(...hooks: object[]): TestControllerPromise; /** * Detaches the hooks during a test run * - * @param hook - The set of RequestHook subclasses + * @param hooks - The set of RequestHook subclasses */ - removeRequestHooks(...hook: object[]): TestControllerPromise; + removeRequestHooks(...hooks: object[]): TestControllerPromise; } interface TestControllerPromise extends TestController, Promise { @@ -1709,9 +1709,9 @@ interface FixtureFn { /** * Attaches hooks to all tests in the fixture * - * @param hook - The set of the RequestHook subclasses + * @param hooks - The set of the RequestHook subclasses */ - requestHooks(...hook: object[]): this; + requestHooks(...hooks: object[]): this; } interface TestFn { @@ -1774,9 +1774,9 @@ interface TestFn { /** * Attaches hooks to the test * - * @param hook - The set of the RequestHook subclasses + * @param hooks - The set of the RequestHook subclasses */ - requestHooks(...hook: object[]): this; + requestHooks(...hooks: object[]): this; } declare var fixture: FixtureFn; From fd2bff35d1cc25f2d0211c2d92451d3fe54acf16 Mon Sep 17 00:00:00 2001 From: Vladimir Airikh Date: Tue, 28 Aug 2018 10:22:19 +0300 Subject: [PATCH 070/184] fix `Update testcafe-legacy-api version` (#2776) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 08b6da0f..35d7e1e1 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.5", "testcafe-hammerhead": "14.2.5", - "testcafe-legacy-api": "3.1.7", + "testcafe-legacy-api": "3.1.8", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", "testcafe-reporter-minimal": "^2.1.0", From f635a5842c2609d6f7b5c5a27a61978bb9bd7a09 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Tue, 28 Aug 2018 13:55:28 +0300 Subject: [PATCH 071/184] update hammerhead (#2779) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 35d7e1e1..0cdee323 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.5", - "testcafe-hammerhead": "14.2.5", + "testcafe-hammerhead": "14.2.6", "testcafe-legacy-api": "3.1.8", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", From 7971284e6aa9248632a711966fc6bfea9517e42a Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Tue, 28 Aug 2018 15:36:42 +0300 Subject: [PATCH 072/184] [docs] Add a TestCafe Studio top-level link (#2759) --- docs/nav/top-menu-items.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/nav/top-menu-items.yml b/docs/nav/top-menu-items.yml index 31b99bb0..7593ee1c 100644 --- a/docs/nav/top-menu-items.yml +++ b/docs/nav/top-menu-items.yml @@ -6,8 +6,8 @@ external: true - text: FAQ url: /faq/ -- text: Publications - url: /publications/ +# - text: Publications +# url: /publications/ - text: Release Notes url: /blog/ - text: Issues @@ -15,4 +15,8 @@ external: true - text: Q&A url: https://stackoverflow.com/questions/tagged/testcafe - external: true \ No newline at end of file + external: true +- text: TestCafe Studio + url: https://testcafe-studio.devexpress.com + external: true + id: studio-link \ No newline at end of file From 741f99422e8b4d5a583a10e559e8f9442209cbd8 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Tue, 28 Aug 2018 15:46:46 +0300 Subject: [PATCH 073/184] [docs] Introduce changelog for v0.22.0 (#2768) --- CHANGELOG.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a308236..69660304 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,74 @@ # Changelog +## v0.22.0 (2018-8-27) + +### Enhancements + +#### :gear: CoffeeScript Support ([#1556](https://github.com/DevExpress/testcafe/issues/1556)) by [@GeoffreyBooth](https://github.com/GeoffreyBooth) + +TestCafe now allows you to write tests in CoffeeScript. You do not need to compile CoffeeScript manually or make any customizations, everything works out-of-the-box. + +```coffee +import { Selector } from 'testcafe' + +fixture 'CoffeeScript Example' + .page 'https://devexpress.github.io/testcafe/example/' + +nameInput = Selector '#developer-name' + +test 'Test', (t) => + await t + .typeText(nameInput, 'Peter') + .typeText(nameInput, 'Paker', { replace: true }) + .typeText(nameInput, 'r', { caretPos: 2 }) + .expect(nameInput.value).eql 'Parker'; +``` + +#### :gear: Failed Selector Method Pinpointed in the Report ([#2568](https://github.com/DevExpress/testcafe/issues/2568)) + +When an incorrect call occurs in a chain of selector methods, the test run report now identifies the exact method that failed to match any DOM element. + +![Failed Selector Report](docs/articles/images/failed-selector-report.png) + +#### :gear: Fail on Uncaught Server Errors ([#2546](https://github.com/DevExpress/testcafe/issues/2546)) + +Previously, TestCafe ignored uncaught errors and unhandled promise rejections occurred on the server. Whenever an error or a promise rejection happened, test execution continued. + +Starting from v0.22.0, tests fail if a server error or a promise rejection is unhandled. To return to the previous behavior, we have introduced a `skipUncaughtErrors` option. Use the [--skipUncaughtErrors](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#-u---skip-uncaught-errors) flag +in the command line or the [skipUncaughtErrors](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#run) option in the API. + +```sh +testcafe chrome tests/fixture.js --skipUncaughtErrors +``` + +```js +runner.run({skipUncaughtErrors:true}) +``` + +#### :gear: Use Glob Patterns in `runner.src` ([#980](https://github.com/DevExpress/testcafe/issues/980)) + +You can now use [glob patterns](https://github.com/isaacs/node-glob#glob-primer) in the [runner.src](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#src) method to specify a set of test files. + +```js +runner.src(['/home/user/tests/**/*.js', '!/home/user/tests/foo.js']); +``` + +### Bug Fixes + +* The `RequestLogger` no longer fails when it tries to stringify a null request body ([#2718](https://github.com/DevExpress/testcafe/issues/2718)) +* Temporary directories are now correctly removed when the test run is finished ([#2735](https://github.com/DevExpress/testcafe/issues/2735)) +* TestCafe no longer throws `ECONNRESET` when run against a Webpack project ([#2711](https://github.com/DevExpress/testcafe/issues/2711)) +* An error is no longer thrown when TestCafe tests Sencha ExtJS applications in IE11 ([#2639](https://github.com/DevExpress/testcafe/issues/2639)) +* Firefox no longer waits for page elements to appear without necessity ([#2080](https://github.com/DevExpress/testcafe/issues/2080)) +* The `toString` function now returns a native string for overridden descriptor ancestors ([testcafe-hammerhead/#1713](https://github.com/DevExpress/testcafe-hammerhead/issues/1713)) +* The `iframe` flag is no longer added when a form with `target="_parent"` is submitted ([testcafe-hammerhead/#1680](https://github.com/DevExpress/testcafe-hammerhead/issues/1680)) +* Hammerhead no longer sends request headers in lower case ([testcafe-hammerhead/#1380](https://github.com/DevExpress/testcafe-hammerhead/issues/1380)) +* The overridden `createHTMLDocument` method has the right context now ([testcafe-hammerhead/#1722](https://github.com/DevExpress/testcafe-hammerhead/issues/1722)) +* Tests no longer lose connection ([testcafe-hammerhead/#1647](https://github.com/DevExpress/testcafe-hammerhead/issues/1647)) +* The case when both the `X-Frame-Options` header and a CSP with `frame-ancestors` are set is now handled correctly ([testcafe-hammerhead/#1666](https://github.com/DevExpress/testcafe-hammerhead/issues/1666)) +* A mechanism that resolves URLs on the client now works correctly ([testcafe-hammerhead/#1701](https://github.com/DevExpress/testcafe-hammerhead/issues/1701)) +* `LiveNodeListWrapper` now imitates native behavior correctly ([testcafe-hammerhead/#1376](https://github.com/DevExpress/testcafe-hammerhead/issues/1376)) + ## v0.21.1 (2018-8-8) ### Bug fixes From 1a64d8c40fd3377674170d1ca75d97dc1925b28b Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Tue, 28 Aug 2018 15:51:17 +0300 Subject: [PATCH 074/184] Edit v0.22.0 release date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69660304..71efb2c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## v0.22.0 (2018-8-27) +## v0.22.0 (2018-8-28) ### Enhancements From 3f7259510b3a805ffa9031a7669c88088fc45651 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 29 Aug 2018 11:51:46 +0300 Subject: [PATCH 075/184] Bump version (v0.22.0-alpha.1) (#2780) --- appveyor.yml | 48 +++++++++---------- package.json | 2 +- .../api/click/testcafe-fixtures/click.test.js | 2 +- 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index dcd22768..fb08b65b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,9 +5,31 @@ skip_commits: message: /^\[docs\]/ environment: - GULP_TASK: "test-functional-local-ie" NODEJS_VERSION: "stable" + matrix: + - GULP_TASK: "test-functional-local-ie" + +for: +- + branches: + only: + - master + + notifications: + - provider: Email + to: + - boris.kirov@devexpress.com + - andrey.belym@devexpress.com + - elena.dikareva@devexpress.com + on_build_success: false + on_build_status_changed: false + + environment: + matrix: + - GULP_TASK: "test-functional-local-chrome-firefox" + - GULP_TASK: "test-functional-local-legacy" + install: - ps: >- iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/set-screenresolution.ps1')) @@ -27,27 +49,3 @@ build: off test_script: - cmd: npm test - -for: -- - branches: - only: - - master - - notifications: - - provider: Email - to: - - boris.kirov@devexpress.com - - andrey.belym@devexpress.com - - elena.dikareva@devexpress.com - on_build_success: false - on_build_status_changed: false - - test_script: - - cmd: >- - node node_modules/gulp/bin/gulp test-functional-local-ie - - node node_modules/gulp/bin/gulp test-functional-local-chrome-firefox - - node node_modules/gulp/bin/gulp test-functional-local-legacy - diff --git a/package.json b/package.json index 0cdee323..b97878f4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.21.2-alpha.1", + "version": "0.22.0-alpha.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" diff --git a/test/functional/legacy-fixtures/api/click/testcafe-fixtures/click.test.js b/test/functional/legacy-fixtures/api/click/testcafe-fixtures/click.test.js index 8b497454..039b141d 100644 --- a/test/functional/legacy-fixtures/api/click/testcafe-fixtures/click.test.js +++ b/test/functional/legacy-fixtures/api/click/testcafe-fixtures/click.test.js @@ -21,7 +21,7 @@ var isIE11 = !!(navigator.appCodeName === 'Mozilla' && eq(e.pointerType, isIE11 || isMSEdge ? 'mouse' : 4); eq(e.button, 0); - eq(e.buttons, 1); + eq(e.buttons, e.type === 'pointerdown' ? 1 : 0); } if (isMSEdge) { From 5fbd334a3c71fcc1128760d8ad4f230660972912 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 29 Aug 2018 16:59:03 +0300 Subject: [PATCH 076/184] Add missing temp; Improve temp dir logs; Bump version (v0.22.0-alpha.2) (#2784) --- package.json | 4 +- .../temp-directory/cleanup-process/index.js | 49 ++++++++++++++++--- .../temp-directory/cleanup-process/worker.js | 2 - test/dependency-licenses-checker.js | 1 + 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index b97878f4..a52fd372 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.22.0-alpha.1", + "version": "0.22.0-alpha.2", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" @@ -73,6 +73,7 @@ "commander": "^2.8.1", "debug": "^2.2.0", "dedent": "^0.4.0", + "del": "^3.0.0", "elegant-spinner": "^1.0.1", "endpoint-utils": "^1.0.2", "error-stack-parser": "^1.3.6", @@ -131,7 +132,6 @@ "caller": "^1.0.1", "connect": "^3.4.0", "cross-spawn": "^4.0.0", - "del": "^2.2.0", "dom-walk": "^0.1.1", "eslint-plugin-hammerhead": "0.1.10", "express": "^4.13.3", diff --git a/src/utils/temp-directory/cleanup-process/index.js b/src/utils/temp-directory/cleanup-process/index.js index a7b30893..f7432756 100644 --- a/src/utils/temp-directory/cleanup-process/index.js +++ b/src/utils/temp-directory/cleanup-process/index.js @@ -7,7 +7,7 @@ import COMMANDS from './commands'; const WORKER_PATH = require.resolve('./worker'); -const WORKER_STDIO_CONFIG = ['ignore', 'ignore', 'ignore', 'ipc']; +const WORKER_STDIO_CONFIG = ['ignore', 'pipe', 'pipe', 'ipc']; const DEBUG_LOGGER = debug('testcafe:utils:temp-directory:cleanup-process'); @@ -23,7 +23,10 @@ class CleanupProcess { } _sendMessage (id, msg) { - return sendMessageToChildProcess(this.worker, { id, ...msg }); + return Promise.race([ + sendMessageToChildProcess(this.worker, { id, ...msg }), + promisifyEvent(this.worker, 'error') + ]); } _onResponse (response) { @@ -69,6 +72,34 @@ class CleanupProcess { await this._waitResponse(currentId); } + _waitProcessExit () { + return promisifyEvent(this.worker, 'exit') + .then(exitCode => Promise.reject(new Error(`Worker process terminated with code ${exitCode}`))); + } + + _setupWorkerEventHandlers () { + this.worker.on('message', message => this._onResponse(message)); + + this.worker.stdout.on('data', data => DEBUG_LOGGER('Worker process stdout:\n', String(data))); + this.worker.stderr.on('data', data => DEBUG_LOGGER('Worker process stderr:\n', String(data))); + } + + _unrefWorkerProcess () { + this.worker.unref(); + this.worker.stdout.unref(); + this.worker.stderr.unref(); + + const channel = this.worker.channel || this.worker._channel; + + channel.unref(); + } + + _handleProcessError (error) { + this.initialized = false; + + DEBUG_LOGGER(error); + } + init () { this.initPromise = this.initPromise .then(async initialized => { @@ -77,21 +108,23 @@ class CleanupProcess { this.worker = spawn(process.argv[0], [WORKER_PATH], { detached: true, stdio: WORKER_STDIO_CONFIG }); - this.worker.on('message', message => this._onResponse(message)); + this._setupWorkerEventHandlers(); + this._unrefWorkerProcess(); - this.worker.unref(); + const exitPromise = this._waitProcessExit(); try { await Promise.race([ this._waitResponseForMessage({ command: COMMANDS.init }), - promisifyEvent(this.worker, 'error') + promisifyEvent(this.worker, 'error'), + exitPromise ]); - const channel = this.worker.channel || this.worker._channel; + this.initialized = true; - channel.unref(); + exitPromise.catch(error => this._handleProcessError(error)); - this.initialized = true; + this.worker.on('error', error => this._handleProcessError(error)); } catch (e) { DEBUG_LOGGER('Failed to start cleanup process'); diff --git a/src/utils/temp-directory/cleanup-process/worker.js b/src/utils/temp-directory/cleanup-process/worker.js index 987eb119..338c0096 100644 --- a/src/utils/temp-directory/cleanup-process/worker.js +++ b/src/utils/temp-directory/cleanup-process/worker.js @@ -68,5 +68,3 @@ process.on('disconnect', async () => { process.exit(0); //eslint-disable-line no-process-exit }); - - diff --git a/test/dependency-licenses-checker.js b/test/dependency-licenses-checker.js index f4d58d33..4f696e0c 100644 --- a/test/dependency-licenses-checker.js +++ b/test/dependency-licenses-checker.js @@ -20,6 +20,7 @@ const PERMISSIVE_LICENSES = [ 'Unlicense', 'Apache 2.0', 'WTFPL OR ISC', + '(WTFPL OR MIT)', 'Public Domain', 'WTFPL', 'Apache-2.0' From 3e0338f9cf1ea28d1c269598d0c8c2d6e998fdb1 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Thu, 30 Aug 2018 11:02:44 +0300 Subject: [PATCH 077/184] Should find element with not-integer offset (closes #2080) (#2760) * Should find element with not-integer offset (closes #2080) * more tests * remove tests * remove excess element --- .../playback/visible-element-automation.js | 38 ++++----- .../automation/utils/get-automation-point.js | 10 ++- src/client/automation/utils/offsets.js | 15 ---- .../regression/gh-2080/pages/index.html | 82 +++++++++++++++++++ .../fixtures/regression/gh-2080/test.js | 5 ++ .../gh-2080/testcafe-fixtures/index.js | 15 ++++ 6 files changed, 128 insertions(+), 37 deletions(-) create mode 100644 test/functional/fixtures/regression/gh-2080/pages/index.html create mode 100644 test/functional/fixtures/regression/gh-2080/test.js create mode 100644 test/functional/fixtures/regression/gh-2080/testcafe-fixtures/index.js diff --git a/src/client/automation/playback/visible-element-automation.js b/src/client/automation/playback/visible-element-automation.js index c4a541c2..9bf8163e 100644 --- a/src/client/automation/playback/visible-element-automation.js +++ b/src/client/automation/playback/visible-element-automation.js @@ -10,7 +10,7 @@ import ScrollAutomation from './scroll'; import MoveAutomation from './move'; import { MoveOptions, ScrollOptions } from '../../../test-run/commands/options'; -var extend = hammerhead.utils.extend; +const extend = hammerhead.utils.extend; class ElementState { constructor ({ element = null, clientPoint = null, screenPoint = null, isTarget = false, inMoving = false }) { @@ -35,15 +35,15 @@ export default class VisibleElementAutomation extends serviceUtils.EventEmitter } _getElementForEvent (eventArgs) { - var { x, y } = eventArgs.point; - var expectedElement = positionUtils.containsOffset(this.element, this.options.offsetX, this.options.offsetY) ? this.element : null; + const { x, y } = eventArgs.point; + const expectedElement = positionUtils.containsOffset(this.element, this.options.offsetX, this.options.offsetY) ? this.element : null; return getElementFromPoint(x, y, expectedElement).then(({ element }) => element); } _moveToElement () { - var moveOptions = new MoveOptions(extend({ skipScrolling: true }, this.options), false); - var moveAutomation = new MoveAutomation(this.element, moveOptions); + const moveOptions = new MoveOptions(extend({ skipScrolling: true }, this.options), false); + const moveAutomation = new MoveAutomation(this.element, moveOptions); return moveAutomation .run() @@ -51,7 +51,7 @@ export default class VisibleElementAutomation extends serviceUtils.EventEmitter } _scrollToElement () { - var scrollAutomation = new ScrollAutomation(this.element, new ScrollOptions(this.options)); + const scrollAutomation = new ScrollAutomation(this.element, new ScrollOptions(this.options)); return scrollAutomation .run() @@ -59,42 +59,42 @@ export default class VisibleElementAutomation extends serviceUtils.EventEmitter } _wrapAction (action) { - var offsetX = this.options.offsetX; - var offsetY = this.options.offsetY; - var screenPointBeforeAction = getAutomationPoint(this.element, offsetX, offsetY); - var clientPositionBeforeAction = positionUtils.getClientPosition(this.element); + const offsetX = this.options.offsetX; + const offsetY = this.options.offsetY; + const screenPointBeforeAction = getAutomationPoint(this.element, offsetX, offsetY); + const clientPositionBeforeAction = positionUtils.getClientPosition(this.element); return action() .then(() => { - var screenPointAfterAction = getAutomationPoint(this.element, offsetX, offsetY); - var clientPositionAfterAction = positionUtils.getClientPosition(this.element); - var clientPoint = screenPointToClient(this.element, screenPointAfterAction); - var expectedElement = positionUtils.containsOffset(this.element, offsetX, offsetY) ? this.element : null; + const screenPointAfterAction = getAutomationPoint(this.element, offsetX, offsetY); + const clientPositionAfterAction = positionUtils.getClientPosition(this.element); + const clientPoint = screenPointToClient(this.element, screenPointAfterAction); + const expectedElement = positionUtils.containsOffset(this.element, offsetX, offsetY) ? this.element : null; return getElementFromPoint(clientPoint.x, clientPoint.y, expectedElement) .then(({ element, corrected }) => { - var foundElement = element; + const foundElement = element; if (!foundElement) return new ElementState({}); - var isTarget = !expectedElement || corrected || foundElement === this.element; + let isTarget = !expectedElement || corrected || foundElement === this.element; if (!isTarget) { // NOTE: perform an operation with searching in dom only if necessary isTarget = arrayUtils.indexOf(domUtils.getParents(foundElement), this.element) > -1; } - var offsetPositionChanged = screenPointBeforeAction.x !== screenPointAfterAction.x || + const offsetPositionChanged = screenPointBeforeAction.x !== screenPointAfterAction.x || screenPointBeforeAction.y !== screenPointAfterAction.y; - var clientPositionChanged = clientPositionBeforeAction.x !== clientPositionAfterAction.x || + const clientPositionChanged = clientPositionBeforeAction.x !== clientPositionAfterAction.x || clientPositionBeforeAction.y !== clientPositionAfterAction.y; // NOTE: We consider the element moved if its offset position and client position // are changed both. If only client position was changed it means the page was // scrolled and the element keeps its position on the page. If only offset position was // changed it means the element is fixed on the page (it can be implemented via script). - var targetElementIsMoving = offsetPositionChanged && clientPositionChanged; + const targetElementIsMoving = offsetPositionChanged && clientPositionChanged; return new ElementState({ element, diff --git a/src/client/automation/utils/get-automation-point.js b/src/client/automation/utils/get-automation-point.js index 9486af6c..192ea59c 100644 --- a/src/client/automation/utils/get-automation-point.js +++ b/src/client/automation/utils/get-automation-point.js @@ -1,9 +1,13 @@ import { positionUtils } from '../deps/testcafe-core'; +import hammerhead from '../deps/hammerhead'; + +const browserUtils = hammerhead.utils.browser; export default function getAutomationPoint (element, offsetX, offsetY) { - var elementOffset = positionUtils.getOffsetPosition(element); - var left = element === document.documentElement ? 0 : elementOffset.left; - var top = element === document.documentElement ? 0 : elementOffset.top; + const roundFn = browserUtils.isFirefox ? Math.ceil : Math.round; + const elementOffset = positionUtils.getOffsetPosition(element, roundFn); + const left = element === document.documentElement ? 0 : elementOffset.left; + const top = element === document.documentElement ? 0 : elementOffset.top; return { x: left + offsetX, diff --git a/src/client/automation/utils/offsets.js b/src/client/automation/utils/offsets.js index d51e36cb..ca81ce15 100644 --- a/src/client/automation/utils/offsets.js +++ b/src/client/automation/utils/offsets.js @@ -1,5 +1,4 @@ import { positionUtils } from '../deps/testcafe-core'; -import getAutomationPoint from './get-automation-point'; function calcOffset (size) { const offset = size / 2; @@ -35,17 +34,3 @@ export function getOffsetOptions (element, offsetX, offsetY) { offsetY: offsetY < 0 ? maxY + offsetY : offsetY }; } - -export function getMoveAutomationOffsets (element, offsetX, offsetY) { - var clickOnElement = positionUtils.containsOffset(element, offsetX, offsetY); - - if (clickOnElement) - return { offsetX, offsetY }; - - var actionPoint = getAutomationPoint(element, offsetX, offsetY); - - return { - offsetX: actionPoint.x, - offsetY: actionPoint.y - }; -} diff --git a/test/functional/fixtures/regression/gh-2080/pages/index.html b/test/functional/fixtures/regression/gh-2080/pages/index.html new file mode 100644 index 00000000..8127a45b --- /dev/null +++ b/test/functional/fixtures/regression/gh-2080/pages/index.html @@ -0,0 +1,82 @@ + + + + + Title + + + +
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+ + + \ No newline at end of file diff --git a/test/functional/fixtures/regression/gh-2080/test.js b/test/functional/fixtures/regression/gh-2080/test.js new file mode 100644 index 00000000..999dafe3 --- /dev/null +++ b/test/functional/fixtures/regression/gh-2080/test.js @@ -0,0 +1,5 @@ +describe('[Regression](GH-2080)', function () { + it('Should find element with not-integer offset', function () { + return runTests('testcafe-fixtures/index.js'); + }); +}); diff --git a/test/functional/fixtures/regression/gh-2080/testcafe-fixtures/index.js b/test/functional/fixtures/regression/gh-2080/testcafe-fixtures/index.js new file mode 100644 index 00000000..66200a15 --- /dev/null +++ b/test/functional/fixtures/regression/gh-2080/testcafe-fixtures/index.js @@ -0,0 +1,15 @@ +import { Selector } from 'testcafe'; + +fixture `GH-2080 - Should find element with not-integer offset` + .page `http://localhost:3000/fixtures/regression/gh-2080/pages/index.html`; + +const result = Selector('#result'); + +test('click', async t => { + await t + .click('#child1', { offsetX: 0, offsetY: 0 }) + .click('#child2', { offsetX: 0, offsetY: 0 }) + .click('#child3', { offsetX: 0, offsetY: 0 }) + .click('#child4', { offsetX: 0, offsetY: 0 }) + .expect(result.innerText).contains('leaf1 child1 parent leaf2 child2 parent leaf3 child3 parent leaf4 child4 parent'); +}); From 720d9590f821eaa7e6f95b757151c541b55de6f3 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Thu, 30 Aug 2018 12:06:44 +0300 Subject: [PATCH 078/184] fix absolute paths for source maps (fix bug for #2546) (#2785) --- Gulpfile.js | 132 ++++++++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 65 deletions(-) diff --git a/Gulpfile.js b/Gulpfile.js index cca9ad70..ece2f310 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -13,8 +13,8 @@ const rename = require('gulp-rename'); const webmake = require('gulp-webmake'); const uglify = require('gulp-uglify'); const ll = require('gulp-ll-next'); -const clone = require('gulp-clone'); -const mergeStreams = require('merge-stream'); +const clone = require('gulp-clone'); +const mergeStreams = require('merge-stream'); const del = require('del'); const fs = require('fs'); const path = require('path'); @@ -145,7 +145,7 @@ const PUBLISH_TAG = JSON.parse(fs.readFileSync(path.join(__dirname, '.publishrc' let websiteServer = null; -gulp.task('audit', function () { +gulp.task('audit', () => { return npmAuditor() .then(result => { process.stdout.write(result.report); @@ -156,13 +156,13 @@ gulp.task('audit', function () { }); }); -gulp.task('clean', function () { +gulp.task('clean', () => { return del('lib'); }); // Lint -gulp.task('lint', function () { +gulp.task('lint', () => { const eslint = require('gulp-eslint'); return gulp @@ -179,13 +179,13 @@ gulp.task('lint', function () { }); // License checker -gulp.task('check-licenses', function () { +gulp.task('check-licenses', () => { return checkLicenses(); }); // Build -gulp.step('client-scripts-bundle', function () { +gulp.step('client-scripts-bundle', () => { return gulp .src([ 'src/client/core/index.js', @@ -196,7 +196,7 @@ gulp.step('client-scripts-bundle', function () { ], { base: 'src' }) .pipe(webmake({ sourceMap: false, - transform: function (filename, code) { + transform: (filename, code) => { const transformed = babel.transform(code, { sourceMap: false, ast: false, @@ -217,7 +217,7 @@ gulp.step('client-scripts-bundle', function () { .pipe(gulp.dest('lib')); }); -gulp.step('client-scripts-templates-render', function () { +gulp.step('client-scripts-templates-render', () => { const scripts = gulp .src([ 'src/client/core/index.js.wrapper.mustache', @@ -254,7 +254,7 @@ gulp.step('client-scripts-templates-render', function () { gulp.step('client-scripts', gulp.series('client-scripts-bundle', 'client-scripts-templates-render')); -gulp.step('server-scripts', function () { +gulp.step('server-scripts', () => { return gulp .src([ 'src/**/*.js', @@ -262,21 +262,23 @@ gulp.step('server-scripts', function () { ]) .pipe(sourcemaps.init()) .pipe(gulpBabel()) - .pipe(sourcemaps.mapSources(function (sourcePath, file) { - return file.path; + .pipe(sourcemaps.mapSources(sourcePath => { + const libPath = path.join('src', sourcePath); + + return path.relative(sourcePath, libPath); })) .pipe(sourcemaps.write()) .pipe(gulp.dest('lib')); }); -gulp.step('styles', function () { +gulp.step('styles', () => { return gulp .src('src/**/*.less') .pipe(less()) .pipe(gulp.dest('lib')); }); -gulp.step('templates', function () { +gulp.step('templates', () => { return gulp .src([ 'src/**/*.mustache', @@ -285,7 +287,7 @@ gulp.step('templates', function () { .pipe(gulp.dest('lib')); }); -gulp.step('images', function () { +gulp.step('images', () => { return gulp .src([ 'src/**/*.png', @@ -302,7 +304,7 @@ gulp.task('fast-build', gulp.series('clean', 'package-content')); gulp.task('build', DEV_MODE ? gulp.registry().get('fast-build') : gulp.parallel('lint', 'fast-build')); // Test -gulp.step('test-server-run', function () { +gulp.step('test-server-run', () => { return gulp .src('test/server/*-test.js', { read: false }) .pipe(mocha({ @@ -324,11 +326,11 @@ function testClient (tests, settings, envSettings, cliMode) { if (!cliMode) return runTests(envSettings); - return listBrowsers().then(function (browsers) { + return listBrowsers().then(browsers => { const browserNames = Object.keys(browsers); const targetBrowsers = []; - browserNames.forEach(function (browserName) { + browserNames.forEach(browserName => { if (CLIENT_TEST_LOCAL_BROWSERS_ALIASES.includes(browserName)) targetBrowsers.push({ browserInfo: browsers[browserName], browserName: browserName }); }); @@ -337,25 +339,25 @@ function testClient (tests, settings, envSettings, cliMode) { }); } -gulp.step('test-client-run', function () { +gulp.step('test-client-run', () => { return testClient('test/client/fixtures/**/*-test.js', CLIENT_TESTS_SETTINGS); }); gulp.task('test-client', gulp.series('build', 'test-client-run')); -gulp.step('test-client-local-run', function () { +gulp.step('test-client-local-run', () => { return testClient('test/client/fixtures/**/*-test.js', CLIENT_TESTS_LOCAL_SETTINGS, {}, true); }); gulp.task('test-client-local', gulp.series('build', 'test-client-local-run')); -gulp.step('test-client-legacy-run', function () { +gulp.step('test-client-legacy-run', () => { return testClient('test/client/legacy-fixtures/**/*-test.js', CLIENT_TESTS_LEGACY_SETTINGS); }); gulp.task('test-client-legacy', gulp.series('build', 'test-client-legacy-run')); -gulp.step('test-client-travis-run', function () { +gulp.step('test-client-travis-run', () => { const saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; saucelabsSettings.browsers = CLIENT_TESTS_DESKTOP_BROWSERS; @@ -365,7 +367,7 @@ gulp.step('test-client-travis-run', function () { gulp.task('test-client-travis', gulp.series('build', 'test-client-travis-run')); -gulp.step('test-client-travis-mobile-run', function () { +gulp.step('test-client-travis-mobile-run', () => { const saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; saucelabsSettings.browsers = CLIENT_TESTS_MOBILE_BROWSERS; @@ -375,7 +377,7 @@ gulp.step('test-client-travis-mobile-run', function () { gulp.task('test-client-travis-mobile', gulp.series('build', 'test-client-travis-mobile-run')); -gulp.step('test-client-legacy-travis-run', function () { +gulp.step('test-client-legacy-travis-run', () => { const saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; saucelabsSettings.browsers = CLIENT_TESTS_DESKTOP_BROWSERS; @@ -385,7 +387,7 @@ gulp.step('test-client-legacy-travis-run', function () { gulp.task('test-client-legacy-travis', gulp.series('build', 'test-client-legacy-travis-run')); -gulp.step('test-client-legacy-travis-mobile-run', function () { +gulp.step('test-client-legacy-travis-mobile-run', () => { const saucelabsSettings = CLIENT_TESTS_SAUCELABS_SETTINGS; saucelabsSettings.browsers = CLIENT_TESTS_MOBILE_BROWSERS; @@ -396,7 +398,7 @@ gulp.step('test-client-legacy-travis-mobile-run', function () { gulp.task('test-client-legacy-travis-mobile', gulp.series('build', 'test-client-legacy-travis-mobile-run')); //Documentation -gulp.task('generate-docs-readme', function (done) { +gulp.task('generate-docs-readme', done => { function generateItem (name, url, level) { return ' '.repeat(level * 2) + '* [' + name + '](articles' + url + ')\n'; } @@ -404,7 +406,7 @@ gulp.task('generate-docs-readme', function (done) { function generateDirectory (tocItems, level) { let res = ''; - tocItems.forEach(function (item) { + tocItems.forEach(item => { res += generateItem(item.name ? item.name : item.url, item.url, level); if (item.content) @@ -432,10 +434,10 @@ gulp.task('generate-docs-readme', function (done) { done(); }); -gulp.task('lint-docs', function () { +gulp.task('lint-docs', () => { function lintFiles (files, config) { - return new Promise(function (resolve, reject) { - markdownlint({ files: files, config: config }, function (err, result) { + return new Promise((resolve, reject) => { + markdownlint({ files: files, config: config }, (err, result) => { const lintErr = err || result && result.toString(); if (lintErr) @@ -451,19 +453,19 @@ gulp.task('lint-docs', function () { '!docs/articles/faq/**/*.md', '!docs/articles/documentation/recipes/**/*.md', 'examples/**/*.md' - ]).then(function (files) { + ]).then(files => { return lintFiles(files, require('./.md-lint/docs.json')); }); const lintFaq = globby([ 'docs/articles/faq/**/*.md' - ]).then(function (files) { + ]).then(files => { return lintFiles(files, require('./.md-lint/faq.json')); }); const lintRecipes = globby([ 'docs/articles/documentation/recipes/**/*.md' - ]).then(function (files) { + ]).then(files => { return lintFiles(files, require('./.md-lint/recipes.json')); }); @@ -473,39 +475,39 @@ gulp.task('lint-docs', function () { return Promise.all([lintDocsAndExamples, lintReadme, lintChangelog, lintRecipes, lintFaq]); }); -gulp.task('clean-website', function () { +gulp.task('clean-website', () => { return del('site'); }); -gulp.step('fetch-assets-repo', function (cb) { +gulp.step('fetch-assets-repo', cb => { git.clone('https://github.com/DevExpress/testcafe-gh-page-assets.git', { args: 'site' }, cb); }); -gulp.step('put-in-articles', function () { +gulp.step('put-in-articles', () => { return gulp .src(['docs/articles/**/*', '!docs/articles/blog/**/*']) .pipe(gulp.dest('site/src')); }); -gulp.step('put-in-posts', function () { +gulp.step('put-in-posts', () => { return gulp .src('docs/articles/blog/**/*') .pipe(gulp.dest('site/src/_posts')); }); -gulp.step('put-in-navigation', function () { +gulp.step('put-in-navigation', () => { return gulp .src('docs/nav/**/*') .pipe(gulp.dest('site/src/_data')); }); -gulp.step('put-in-publications', function () { +gulp.step('put-in-publications', () => { return gulp .src('docs/publications/**/*') .pipe(gulp.dest('site/src/_data')); }); -gulp.step('put-in-tweets', function () { +gulp.step('put-in-tweets', () => { return gulp .src('docs/tweets/**/*') .pipe(gulp.dest('site/src/_data')); @@ -537,52 +539,52 @@ function buildWebsite (mode, cb) { // - In production mode, public comment threads are displayed. // * Google Analytics is enabled in production mode only. -gulp.step('build-website-production-run', function (cb) { +gulp.step('build-website-production-run', cb => { buildWebsite('production', cb); }); gulp.task('build-website-production', gulp.series('prepare-website', 'build-website-production-run')); -gulp.step('build-website-development-run', function (cb) { +gulp.step('build-website-development-run', cb => { buildWebsite('development', cb); }); gulp.task('build-website-development', gulp.series('prepare-website', 'build-website-development-run')); -gulp.step('build-website-testing-run', function (cb) { +gulp.step('build-website-testing-run', cb => { buildWebsite('testing', cb); }); gulp.task('build-website-testing', gulp.series('prepare-website', 'build-website-testing-run')); -gulp.step('build-website-run', function (cb) { +gulp.step('build-website-run', cb => { buildWebsite('', cb); }); gulp.task('build-website', gulp.series('prepare-website', 'build-website-run')); -gulp.task('serve-website', function (cb) { +gulp.task('serve-website', cb => { const app = connect() .use('/testcafe', serveStatic('site/deploy')); websiteServer = app.listen(8080, cb); }); -gulp.step('preview-website-open', function () { +gulp.step('preview-website-open', () => { return opn('http://localhost:8080/testcafe'); }); gulp.task('preview-website', gulp.series('build-website-development', 'serve-website', 'preview-website-open')); -gulp.step('test-website-run', function () { +gulp.step('test-website-run', () => { const WebsiteTester = require('./test/website/test.js'); const websiteTester = new WebsiteTester(); return websiteTester .checkLinks() - .then(function (failed) { - return new Promise(function (resolve, reject) { - websiteServer.close(function () { + .then(failed => { + return new Promise((resolve, reject) => { + websiteServer.close(() => { if (failed) reject('Broken links found!'); else @@ -596,10 +598,10 @@ gulp.task('test-website', gulp.series('build-website-testing', 'serve-website', gulp.task('test-website-travis', gulp.series('build-website', 'serve-website', 'test-website-run')); -gulp.step('website-publish-run', function () { +gulp.step('website-publish-run', () => { return gulp .src('site/deploy/**/*') - .pipe(rename(function (filePath) { + .pipe(rename(filePath => { filePath.dirname = filePath.dirname.toLowerCase(); return filePath; @@ -629,49 +631,49 @@ function testFunctional (fixturesDir, testingEnvironmentName, browserProviderNam })); } -gulp.step('test-functional-travis-desktop-osx-and-ms-edge-run', function () { +gulp.step('test-functional-travis-desktop-osx-and-ms-edge-run', () => { return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.osXDesktopAndMSEdgeBrowsers, functionalTestConfig.browserProviderNames.browserstack); }); gulp.task('test-functional-travis-desktop-osx-and-ms-edge', gulp.series('build', 'test-functional-travis-desktop-osx-and-ms-edge-run')); -gulp.step('test-functional-travis-mobile-run', function () { +gulp.step('test-functional-travis-mobile-run', () => { return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.mobileBrowsers, functionalTestConfig.browserProviderNames.browserstack); }); gulp.task('test-functional-travis-mobile', gulp.series('build', 'test-functional-travis-mobile-run')); -gulp.step('test-functional-local-run', function () { +gulp.step('test-functional-local-run', () => { return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.localBrowsers); }); gulp.task('test-functional-local', gulp.series('build', 'test-functional-local-run')); -gulp.step('test-functional-local-ie-run', function () { +gulp.step('test-functional-local-ie-run', () => { return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.localBrowsersIE); }); gulp.task('test-functional-local-ie', gulp.series('build', 'test-functional-local-ie-run')); -gulp.step('test-functional-local-chrome-firefox-run', function () { +gulp.step('test-functional-local-chrome-firefox-run', () => { return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.localBrowsersChromeFirefox); }); gulp.task('test-functional-local-chrome-firefox', gulp.series('build', 'test-functional-local-chrome-firefox-run')); -gulp.step('test-functional-local-headless-run', function () { +gulp.step('test-functional-local-headless-run', () => { return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.localHeadlessBrowsers); }); gulp.task('test-functional-local-headless', gulp.series('build', 'test-functional-local-headless-run')); -gulp.step('test-functional-local-legacy-run', function () { +gulp.step('test-functional-local-legacy-run', () => { return testFunctional('test/functional/legacy-fixtures', functionalTestConfig.testingEnvironmentNames.legacy); }); gulp.task('test-functional-local-legacy', gulp.series('build', 'test-functional-local-legacy-run')); -gulp.step('test-functional-travis-old-browsers-run', function () { +gulp.step('test-functional-travis-old-browsers-run', () => { return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.oldBrowsers, functionalTestConfig.browserProviderNames.sauceLabs); }); @@ -682,13 +684,13 @@ function getDockerEnv (machineName) { .execSync('docker-machine env --shell bash ' + machineName) .toString() .split('\n') - .map(function (line) { + .map(line => { return line.match(/export\s*(.*)="(.*)"$/); }) - .filter(function (match) { + .filter(match => { return !!match; }) - .reduce(function (env, match) { + .reduce((env, match) => { env[match[1]] = match[2]; return env; }, {}); @@ -727,7 +729,7 @@ function startDocker () { assignIn(process.env, dockerEnv); } -gulp.task('docker-build', function (done) { +gulp.task('docker-build', done => { if (!process.env['DOCKER_HOST']) { try { startDocker(); @@ -751,7 +753,7 @@ gulp.task('docker-build', function (done) { done(); }); -gulp.step('docker-publish-run', function (done) { +gulp.step('docker-publish-run', done => { childProcess.execSync('docker push testcafe/testcafe:' + PUBLISH_TAG, { stdio: 'inherit', env: process.env }); done(); From e0f5ebb888dc428be12bead2dc9a7b2b91666884 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Thu, 30 Aug 2018 13:46:24 +0300 Subject: [PATCH 079/184] Bump version (v0.22.0-alpha.3) (#2790) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a52fd372..186ef4c4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.22.0-alpha.2", + "version": "0.22.0-alpha.3", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From 279422fbc5a4d09c938bef921fa026f0d927d7c8 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Fri, 31 Aug 2018 10:32:10 +0300 Subject: [PATCH 080/184] fix Incorrect selector error highlighting for nth (closes #2792) (#2793) --- .../client-functions/selector-executor/filter.js | 15 ++++++++------- .../fixtures/regression/gh-2568/test.js | 16 ++++++++++++++++ .../gh-2568/testcafe-fixtures/index.js | 12 ++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/client/driver/command-executors/client-functions/selector-executor/filter.js b/src/client/driver/command-executors/client-functions/selector-executor/filter.js index 939cc637..048ae863 100644 --- a/src/client/driver/command-executors/client-functions/selector-executor/filter.js +++ b/src/client/driver/command-executors/client-functions/selector-executor/filter.js @@ -54,15 +54,16 @@ class SelectorFilter { else filtered = filtered.length; } - else if (options.collectionMode) { - if (options.index !== null) { - const nodeOnIndex = this.getNodeByIndex(filtered, options.index); + else { + if (options.collectionMode) { + if (options.index !== null) { + const nodeOnIndex = this.getNodeByIndex(filtered, options.index); - filtered = nodeOnIndex ? [nodeOnIndex] : []; + filtered = nodeOnIndex ? [nodeOnIndex] : []; + } } - } - else { - filtered = this.getNodeByIndex(filtered, options.index || 0); + else + filtered = this.getNodeByIndex(filtered, options.index || 0); if (typeof options.index === 'number') this.assertFilterError(filtered, apiInfo, SELECTOR_FILTER_ERROR.nth); diff --git a/test/functional/fixtures/regression/gh-2568/test.js b/test/functional/fixtures/regression/gh-2568/test.js index 0ea2c20e..4da7c1d8 100644 --- a/test/functional/fixtures/regression/gh-2568/test.js +++ b/test/functional/fixtures/regression/gh-2568/test.js @@ -62,6 +62,22 @@ describe('[Regression](GH-2568)', function () { }); }); + it('nth in collectionMode', function () { + return runTests('testcafe-fixtures/index.js', 'nth in collectionMode', { selectorTimeout: 100, shouldFail: true }) + .catch(function (errs) { + assertSelectorCallstack(errs[0], ` + The specified selector does not match any element in the DOM tree. + | Selector('div') + > | .nth(500) + | .filter('.filtered') + | .withText('loren') + | .withExactText('loren ipsum') + | .withAttribute('attr', '3') + | .filterVisible() + `); + }); + }); + it('filterVisible', function () { return runTests('testcafe-fixtures/index.js', 'filterVisible', { selectorTimeout: 100, shouldFail: true }) .catch(function (errs) { diff --git a/test/functional/fixtures/regression/gh-2568/testcafe-fixtures/index.js b/test/functional/fixtures/regression/gh-2568/testcafe-fixtures/index.js index e108dd4a..36f2635e 100644 --- a/test/functional/fixtures/regression/gh-2568/testcafe-fixtures/index.js +++ b/test/functional/fixtures/regression/gh-2568/testcafe-fixtures/index.js @@ -39,6 +39,18 @@ test('nth', async t => { await t.click(selector); }); +test('nth in collectionMode', async t => { + const selector = Selector('div') + .nth(500) + .filter('.filtered') + .withText('loren') + .withExactText('loren ipsum') + .withAttribute('attr', '3') + .filterVisible(); + + await t.click(selector); +}); + test('filterVisible', async t => { const selector = Selector('div') .filter('.filtered') From cf5780bfc09b96c67aca1fce06ac5b5521c237f5 Mon Sep 17 00:00:00 2001 From: Vladimir Airikh Date: Fri, 31 Aug 2018 14:33:59 +0300 Subject: [PATCH 081/184] Babel: use `for...of` transform for client scripts (#2783) --- package.json | 1 + src/client/.babelrc | 10 ++++++++-- src/compiler/compile-client-function.js | 18 +++--------------- src/compiler/load-babel-libs.js | 10 +++++++++- test/server/compiler-test.js | 4 ---- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 186ef4c4..13b8d28b 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "async-exit-hook": "^1.1.2", "babel-core": "^6.22.1", "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-for-of-as-array": "^1.1.1", "babel-plugin-transform-runtime": "^6.22.0", "babel-preset-env": "^1.1.8", "babel-preset-flow": "^6.23.0", diff --git a/src/client/.babelrc b/src/client/.babelrc index c1e2c3a3..689ed471 100644 --- a/src/client/.babelrc +++ b/src/client/.babelrc @@ -1,9 +1,15 @@ { "compact": false, "presets": [ - ["env", { "loose": true }] + ["env", { + "loose": true, + "exclude": [ + "transform-es2015-typeof-symbol" + ] + }] ], "plugins": [ - "add-module-exports" + "add-module-exports", + "transform-for-of-as-array" ] } diff --git a/src/compiler/compile-client-function.js b/src/compiler/compile-client-function.js index d2b535cc..588d79ba 100644 --- a/src/compiler/compile-client-function.js +++ b/src/compiler/compile-client-function.js @@ -1,6 +1,6 @@ import hammerhead from 'testcafe-hammerhead'; import asyncToGenerator from 'babel-runtime/helpers/asyncToGenerator'; -import { noop, escapeRegExp as escapeRe } from 'lodash'; +import { noop } from 'lodash'; import loadBabelLibs from './load-babel-libs'; import { ClientFunctionAPIError } from '../errors/runtime'; import MESSAGE from '../errors/runtime/message'; @@ -29,27 +29,15 @@ var babelArtifactPolyfills = { re: /_stringify(\d+)\.default/, getCode: match => `var _stringify${match[1]} = { default: JSON.stringify };`, removeMatchingCode: false - }, - - 'typeof': { - re: new RegExp(escapeRe( - 'var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? ' + - 'function (obj) {return typeof obj;} : ' + - 'function (obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol ' + - '&& obj !== Symbol.prototype ? "symbol" : typeof obj;};' - ), 'g'), - - getCode: () => 'var _typeof = function(obj) { return typeof obj; };', - removeMatchingCode: true } }; function getBabelOptions () { - var { presetFallback } = loadBabelLibs(); + var { presetFallback, transformForOfAsArray } = loadBabelLibs(); return { - presets: [presetFallback], + presets: [{ plugins: [transformForOfAsArray] }, presetFallback], sourceMaps: false, retainLines: true, ast: false, diff --git a/src/compiler/load-babel-libs.js b/src/compiler/load-babel-libs.js index ea2bdd69..5ed02982 100644 --- a/src/compiler/load-babel-libs.js +++ b/src/compiler/load-babel-libs.js @@ -6,6 +6,13 @@ function getOptsForPresetEnv () { }; } +function getOptsForPresetFallback () { + return { + loose: true, + exclude: ['transform-es2015-typeof-symbol'] + }; +} + // NOTE: lazy load heavy dependencies export default function loadBabelLibs () { return { @@ -14,7 +21,8 @@ export default function loadBabelLibs () { presetFlow: require('babel-preset-flow'), transformClassProperties: require('babel-plugin-transform-class-properties'), transformRuntime: require('babel-plugin-transform-runtime'), - presetFallback: require('babel-preset-env').default(null, { loose: true }), + transformForOfAsArray: require('babel-plugin-transform-for-of-as-array').default, + presetFallback: require('babel-preset-env').default(null, getOptsForPresetFallback()), presetEnv: require('babel-preset-env').default(null, getOptsForPresetEnv()) }; } diff --git a/test/server/compiler-test.js b/test/server/compiler-test.js index 5f8a3cf5..50362506 100644 --- a/test/server/compiler-test.js +++ b/test/server/compiler-test.js @@ -455,10 +455,6 @@ describe('Compiler', function () { return testClientFnCompilation('json-stringify'); }); - it('Should polyfill Babel `typeof` artifacts', function () { - return testClientFnCompilation('typeof'); - }); - describe('Regression', function () { it('Should compile ES6 object method (GH-1279)', function () { return testClientFnCompilation('gh1279'); From fa6dd2ee4448aa14dd3ae1dbf66dad9128b4fb8e Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Fri, 31 Aug 2018 17:12:28 +0300 Subject: [PATCH 082/184] fix '${BROWSER} resolves to undefined in screenshot pattern' (close #2742) (#2794) * fix '${BROWSER} resolves to undefined in screenshot pattern' (close #2742) * fix review issue --- src/api/structure/testing-unit.js | 2 +- src/api/test-controller/assertion.js | 4 +-- src/api/test-controller/index.js | 22 ++++++------ src/api/test-controller/proxy.js | 6 ++-- src/api/test-page-url.js | 10 +++--- src/api/test-run-tracker.js | 22 ++++++------ src/api/wrap-test-function.js | 6 ++-- src/assertions/executor.js | 6 ++-- src/screenshots/crop.js | 22 ++++++------ src/screenshots/generate-mark.js | 12 +++---- src/screenshots/path-pattern.js | 8 ++--- test/server/path-pattern-test.js | 51 ++++++++++++++-------------- 12 files changed, 85 insertions(+), 86 deletions(-) diff --git a/src/api/structure/testing-unit.js b/src/api/structure/testing-unit.js index e1d79a59..1b3866bb 100644 --- a/src/api/structure/testing-unit.js +++ b/src/api/structure/testing-unit.js @@ -18,7 +18,7 @@ export default class TestingUnit { this.disablePageReloads = void 0; - var unit = this; + const unit = this; this.apiOrigin = function apiOrigin (...args) { return unit._add(...args); diff --git a/src/api/test-controller/assertion.js b/src/api/test-controller/assertion.js index cd35f6c9..2a8e1451 100644 --- a/src/api/test-controller/assertion.js +++ b/src/api/test-controller/assertion.js @@ -7,8 +7,8 @@ export default class Assertion { } _enqueueAssertion (apiMethodName, assertionArgs) { - var options = assertionArgs.opts || {}; - var message = assertionArgs.message; + let options = assertionArgs.opts || {}; + let message = assertionArgs.message; if (typeof message === 'object') { options = assertionArgs.message; diff --git a/src/api/test-controller/index.js b/src/api/test-controller/index.js index 735e0c84..24023553 100644 --- a/src/api/test-controller/index.js +++ b/src/api/test-controller/index.js @@ -61,9 +61,9 @@ export default class TestController { // t.click('#btn2'); // <-- stores new callsiteWithoutAwait // await t2.click('#btn3'); // <-- without check it will set callsiteWithoutAwait = null, so we will lost tracking _createExtendedPromise (promise, callsite) { - var extendedPromise = promise.then(identity); - var originalThen = extendedPromise.then; - var markCallsiteAwaited = () => this.callsitesWithoutAwait.delete(callsite); + const extendedPromise = promise.then(identity); + const originalThen = extendedPromise.then; + const markCallsiteAwaited = () => this.callsitesWithoutAwait.delete(callsite); extendedPromise.then = function () { @@ -80,8 +80,8 @@ export default class TestController { } _enqueueTask (apiMethodName, createTaskExecutor) { - var callsite = getCallsiteForMethod(apiMethodName); - var executor = createTaskExecutor(callsite); + const callsite = getCallsiteForMethod(apiMethodName); + const executor = createTaskExecutor(callsite); this.executionChain = this.executionChain.then(executor); @@ -92,7 +92,7 @@ export default class TestController { _enqueueCommand (apiMethodName, CmdCtor, cmdArgs) { return this._enqueueTask(apiMethodName, callsite => { - var command = null; + let command = null; try { command = new CmdCtor(cmdArgs, this.testRun); @@ -200,7 +200,7 @@ export default class TestController { } _takeElementScreenshot$ (selector, ...args) { - var commandArgs = { selector }; + const commandArgs = { selector }; if (args[1]) { commandArgs.path = args[0]; @@ -238,8 +238,8 @@ export default class TestController { if (!isNullOrUndefined(options)) options = assign({}, options, { boundTestRun: this }); - var builder = new ClientFunctionBuilder(fn, options, { instantiation: 'eval', execution: 'eval' }); - var clientFn = builder.getFunction(); + const builder = new ClientFunctionBuilder(fn, options, { instantiation: 'eval', execution: 'eval' }); + const clientFn = builder.getFunction(); return clientFn(); } @@ -251,13 +251,13 @@ export default class TestController { } _getNativeDialogHistory$ () { - var callsite = getCallsiteForMethod('getNativeDialogHistory'); + const callsite = getCallsiteForMethod('getNativeDialogHistory'); return this.testRun.executeCommand(new GetNativeDialogHistoryCommand(), callsite); } _getBrowserConsoleMessages$ () { - var callsite = getCallsiteForMethod('getBrowserConsoleMessages'); + const callsite = getCallsiteForMethod('getBrowserConsoleMessages'); return this.testRun.executeCommand(new GetBrowserConsoleMessagesCommand(), callsite); } diff --git a/src/api/test-controller/proxy.js b/src/api/test-controller/proxy.js index d2544833..13b13c96 100644 --- a/src/api/test-controller/proxy.js +++ b/src/api/test-controller/proxy.js @@ -4,14 +4,14 @@ import testRunTracker from '../test-run-tracker'; import { APIError } from '../../errors/runtime'; import MESSAGE from '../../errors/runtime/message'; -var testControllerProxy = Object.create(null); +const testControllerProxy = Object.create(null); delegateAPI(testControllerProxy, TestController.API_LIST, { getHandler (propName, accessor) { - var testRun = testRunTracker.resolveContextTestRun(); + const testRun = testRunTracker.resolveContextTestRun(); if (!testRun) { - var callsiteName = null; + let callsiteName = null; if (accessor === 'getter') callsiteName = 'get'; diff --git a/src/api/test-page-url.js b/src/api/test-page-url.js index 82376157..2ffd162f 100644 --- a/src/api/test-page-url.js +++ b/src/api/test-page-url.js @@ -16,7 +16,7 @@ function isAbsolutePath (url) { } function resolveFileUrl (url, testFileName) { - var testFileDir = path.dirname(testFileName); + const testFileDir = path.dirname(testFileName); if (RELATIVE_PATH_RE.test(url)) url = path.join(testFileDir, url); @@ -25,9 +25,9 @@ function resolveFileUrl (url, testFileName) { } export function assertUrl (url, callsiteName) { - var protocol = url.match(PROTOCOL_RE); - var hasUnsupportedProtocol = protocol && !SUPPORTED_PROTOCOL_RE.test(url); - var isWinAbsolutePath = OS.win && WIN_ABSOLUTE_PATH_RE.test(url); + const protocol = url.match(PROTOCOL_RE); + const hasUnsupportedProtocol = protocol && !SUPPORTED_PROTOCOL_RE.test(url); + const isWinAbsolutePath = OS.win && WIN_ABSOLUTE_PATH_RE.test(url); if (hasUnsupportedProtocol && !isWinAbsolutePath && url !== 'about:blank') throw new APIError(callsiteName, MESSAGE.unsupportedUrlProtocol, url, protocol[0]); @@ -40,7 +40,7 @@ export function resolvePageUrl (url, testFileName) { if (isAbsolutePath(url) || RELATIVE_PATH_RE.test(url)) return resolveFileUrl(url, testFileName); - var protocol = IMPLICIT_PROTOCOL_RE.test(url) ? 'http:' : 'http://'; + const protocol = IMPLICIT_PROTOCOL_RE.test(url) ? 'http:' : 'http://'; return protocol + url; } diff --git a/src/api/test-run-tracker.js b/src/api/test-run-tracker.js index cadfff4c..fdd90db5 100644 --- a/src/api/test-run-tracker.js +++ b/src/api/test-run-tracker.js @@ -11,13 +11,13 @@ export default { activeTestRuns: {}, _createContextSwitchingFunctionHook (ctxSwitchingFn, patchedArgsCount) { - var tracker = this; + const tracker = this; return function () { - var testRunId = tracker.getContextTestRunId(); + const testRunId = tracker.getContextTestRunId(); if (testRunId) { - for (var i = 0; i < patchedArgsCount; i++) { + for (let i = 0; i < patchedArgsCount; i++) { if (typeof arguments[i] === 'function') arguments[i] = tracker.addTrackingMarkerToFunction(testRunId, arguments[i]); } @@ -29,11 +29,11 @@ export default { _getStackFrames () { // NOTE: increase stack capacity to seek deep stack entries - var savedLimit = Error.stackTraceLimit; + const savedLimit = Error.stackTraceLimit; Error.stackTraceLimit = STACK_CAPACITY; - var frames = getStackFrames(); + const frames = getStackFrames(); Error.stackTraceLimit = savedLimit; @@ -60,7 +60,7 @@ export default { }, addTrackingMarkerToFunction (testRunId, fn) { - var markerFactoryBody = ` + const markerFactoryBody = ` return function $$testcafe_test_run$$${testRunId}$$ () { switch (arguments.length) { case 0: return fn.call(this); @@ -77,16 +77,16 @@ export default { }, getContextTestRunId () { - var frames = this._getStackFrames(); + const frames = this._getStackFrames(); // OPTIMIZATION: we start traversing from the bottom of the stack, // because we'll more likely encounter a marker there. // Async/await and Promise machinery executes lots of intrinsics // on timers (where we have a marker). And, since a timer initiates a new // stack, the marker will be at the very bottom of it. - for (var i = frames.length - 1; i >= 0; i--) { - var fnName = frames[i].getFunctionName(); - var match = fnName && fnName.match(TRACKING_MARK_RE); + for (let i = frames.length - 1; i >= 0; i--) { + const fnName = frames[i].getFunctionName(); + const match = fnName && fnName.match(TRACKING_MARK_RE); if (match) return match[1]; @@ -96,7 +96,7 @@ export default { }, resolveContextTestRun () { - var testRunId = this.getContextTestRunId(); + const testRunId = this.getContextTestRunId(); return this.activeTestRuns[testRunId]; } diff --git a/src/api/wrap-test-function.js b/src/api/wrap-test-function.js index 167f6c7f..5c1b0623 100644 --- a/src/api/wrap-test-function.js +++ b/src/api/wrap-test-function.js @@ -6,9 +6,9 @@ import { MissingAwaitError } from '../errors/test-run'; export default function wrapTestFunction (fn) { return async testRun => { - var result = null; - var errList = new TestCafeErrorList(); - var markeredfn = testRunTracker.addTrackingMarkerToFunction(testRun.id, fn); + let result = null; + const errList = new TestCafeErrorList(); + const markeredfn = testRunTracker.addTrackingMarkerToFunction(testRun.id, fn); testRun.controller = new TestController(testRun); diff --git a/src/assertions/executor.js b/src/assertions/executor.js index fe506b62..6382fc73 100644 --- a/src/assertions/executor.js +++ b/src/assertions/executor.js @@ -19,8 +19,8 @@ export default class AssertionExecutor extends EventEmitter { this.passed = false; this.inRetry = false; - var fn = getFn(this.command); - var actualCommand = this.command.actual; + const fn = getFn(this.command); + const actualCommand = this.command.actual; if (actualCommand instanceof ReExecutablePromise) this.fn = this._wrapFunction(fn); @@ -41,7 +41,7 @@ export default class AssertionExecutor extends EventEmitter { _wrapFunction (fn) { return async () => { - var resultPromise = this.command.actual; + const resultPromise = this.command.actual; while (!this.passed) { this.command.actual = await resultPromise._reExecute(); diff --git a/src/screenshots/crop.js b/src/screenshots/crop.js index be614674..498b2f59 100644 --- a/src/screenshots/crop.js +++ b/src/screenshots/crop.js @@ -11,8 +11,8 @@ import WARNING_MESSAGES from '../notifications/warning-message'; function readPng (filePath) { - var png = new PNG(); - var parsedPromise = Promise.race([ + const png = new PNG(); + const parsedPromise = Promise.race([ promisifyEvent(png, 'parsed'), promisifyEvent(png, 'error') ]); @@ -24,8 +24,8 @@ function readPng (filePath) { } function writePng (filePath, png) { - var outStream = fs.createWriteStream(filePath); - var finishPromise = Promise.race([ + const outStream = fs.createWriteStream(filePath); + const finishPromise = Promise.race([ promisifyEvent(outStream, 'finish'), promisifyEvent(outStream, 'error') ]); @@ -53,14 +53,14 @@ function detectClippingArea (srcImage, { markSeed, clientAreaDimensions, cropDim let clipHeight = srcImage.height; if (markSeed && clientAreaDimensions) { - var mark = Buffer.from(markSeed); + const mark = Buffer.from(markSeed); - var markIndex = srcImage.data.indexOf(mark); + const markIndex = srcImage.data.indexOf(mark); if (markIndex < 0) throw new Error(renderTemplate(WARNING_MESSAGES.screenshotMarkNotFound, screenshotPath, markSeedToId(markSeed))); - var endPosition = markIndex / MARK_BYTES_PER_PIXEL + MARK_LENGTH + MARK_RIGHT_MARGIN; + const endPosition = markIndex / MARK_BYTES_PER_PIXEL + MARK_LENGTH + MARK_RIGHT_MARGIN; clipRight = endPosition % srcImage.width || srcImage.width; clipBottom = (endPosition - clipRight) / srcImage.width + 1; @@ -94,11 +94,11 @@ function detectClippingArea (srcImage, { markSeed, clientAreaDimensions, cropDim } function copyImagePart (srcImage, { left, top, width, height }) { - var dstImage = new PNG({ width, height }); - var stride = dstImage.width * MARK_BYTES_PER_PIXEL; + const dstImage = new PNG({ width, height }); + const stride = dstImage.width * MARK_BYTES_PER_PIXEL; for (let i = 0; i < height; i++) { - var srcStartIndex = (srcImage.width * (i + top) + left) * MARK_BYTES_PER_PIXEL; + const srcStartIndex = (srcImage.width * (i + top) + left) * MARK_BYTES_PER_PIXEL; srcImage.data.copy(dstImage.data, stride * i, srcStartIndex, srcStartIndex + stride); } @@ -107,7 +107,7 @@ function copyImagePart (srcImage, { left, top, width, height }) { } export default async function (screenshotPath, markSeed, clientAreaDimensions, cropDimensions) { - var srcImage = await readPng(screenshotPath); + const srcImage = await readPng(screenshotPath); const clippingArea = detectClippingArea(srcImage, { markSeed, clientAreaDimensions, cropDimensions, screenshotPath }); diff --git a/src/screenshots/generate-mark.js b/src/screenshots/generate-mark.js index cd2478b8..c95d52a9 100644 --- a/src/screenshots/generate-mark.js +++ b/src/screenshots/generate-mark.js @@ -8,21 +8,21 @@ const ALPHABET = '01'; export default function () { // NOTE: 32-bit id - var id = generateId(ALPHABET, MARK_LENGTH); + const id = generateId(ALPHABET, MARK_LENGTH); // NOTE: array of RGB values - var markSeed = flatten(map(id, bit => bit === '0' ? [0, 0, 0, 255] : [255, 255, 255, 255])); + const markSeed = flatten(map(id, bit => bit === '0' ? [0, 0, 0, 255] : [255, 255, 255, 255])); // NOTE: macOS browsers can't display an element, if it's CSS height is lesser than 1. // It happens on Retina displays, because they have more than 1 physical pixel in a CSS pixel. // So increase mark size by prepending transparent pixels before the actual mark. - var imageData = times(MARK_BYTES_PER_PIXEL * MARK_LENGTH * (MARK_HEIGHT - 1), constant(0)).concat(markSeed); - var imageDataBuffer = Buffer.from(imageData); - var pngImage = new PNG({ width: MARK_LENGTH, height: MARK_HEIGHT }); + const imageData = times(MARK_BYTES_PER_PIXEL * MARK_LENGTH * (MARK_HEIGHT - 1), constant(0)).concat(markSeed); + const imageDataBuffer = Buffer.from(imageData); + const pngImage = new PNG({ width: MARK_LENGTH, height: MARK_HEIGHT }); imageDataBuffer.copy(pngImage.data); - var markData = 'data:image/png;base64,' + PNG.sync.write(pngImage).toString('base64'); + const markData = 'data:image/png;base64,' + PNG.sync.write(pngImage).toString('base64'); return { markSeed, markData }; } diff --git a/src/screenshots/path-pattern.js b/src/screenshots/path-pattern.js index fd241d32..59bc880b 100644 --- a/src/screenshots/path-pattern.js +++ b/src/screenshots/path-pattern.js @@ -63,10 +63,10 @@ export default class PathPattern { [PLACEHOLDERS.TEST]: this.data.test, [PLACEHOLDERS.FILE_INDEX]: forError => forError ? this.data.errorFileIndex : this.data.fileIndex, [PLACEHOLDERS.USERAGENT]: this.data.parsedUserAgent.toString(), - [PLACEHOLDERS.BROWSER]: this.data.parsedUserAgent.browser, - [PLACEHOLDERS.BROWSER_VERSION]: this.data.parsedUserAgent.browserVersion, - [PLACEHOLDERS.OS]: this.data.parsedUserAgent.os, - [PLACEHOLDERS.OS_VERSION]: this.data.parsedUserAgent.osVersion + [PLACEHOLDERS.BROWSER]: this.data.parsedUserAgent.family, + [PLACEHOLDERS.BROWSER_VERSION]: this.data.parsedUserAgent.toVersion(), + [PLACEHOLDERS.OS]: this.data.parsedUserAgent.os.family, + [PLACEHOLDERS.OS_VERSION]: this.data.parsedUserAgent.os.toVersion() }; } diff --git a/test/server/path-pattern-test.js b/test/server/path-pattern-test.js index e9310a9a..867769d9 100644 --- a/test/server/path-pattern-test.js +++ b/test/server/path-pattern-test.js @@ -1,12 +1,18 @@ const PathPattern = require('../../lib/screenshots/path-pattern'); const expect = require('chai').expect; const moment = require('moment'); +const userAgent = require('useragent'); describe('Screenshot path pattern', () => { + const parsedUserAgentMock = { + toVersion: () => {}, + os: { toVersion: () => {} } + }; + const createPathPattern = (pattern, data) => { data = data || {}; data.now = data.now || moment(); - data.parsedUserAgent = data.parsedUserAgent || {}; + data.parsedUserAgent = data.parsedUserAgent || parsedUserAgentMock; data.quarantineAttempt = data.quarantineAttempt || null; return new PathPattern(pattern, data); @@ -27,39 +33,32 @@ describe('Screenshot path pattern', () => { }); it('Should replace all placeholders', () => { - const pattern = Object.getOwnPropertyNames(PathPattern.PLACEHOLDERS).map(name => PathPattern.PLACEHOLDERS[name]).join('#'); - const dateStr = '2010-01-02'; - const timeStr = '11:12:13'; + const pattern = Object.getOwnPropertyNames(PathPattern.PLACEHOLDERS).map(name => PathPattern.PLACEHOLDERS[name]).join('#'); + const dateStr = '2010-01-02'; + const timeStr = '11:12:13'; + const parsedUserAgent = userAgent.parse('Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'); const data = { now: moment(dateStr + ' ' + timeStr), testIndex: 12, fileIndex: 34, - quarantineAttempt: 56, + quarantineAttempt: 2, fixture: 'fixture', test: 'test', - parsedUserAgent: { - browser: 'Chrome', - browserVersion: '67.0.3396', - os: 'Windows', - osVersion: '8.1.0.0', - toString: function () { - return 'full_user_agent'; - } - } + parsedUserAgent }; const expectedParsedPattern = [ - dateStr, - timeStr.replace(/:/g, '-'), - data.testIndex, - data.fileIndex, - data.quarantineAttempt, - data.fixture, - data.test, - data.parsedUserAgent.toString(), - data.parsedUserAgent.browser, - data.parsedUserAgent.browserVersion, - data.parsedUserAgent.os, - data.parsedUserAgent.osVersion + '2010-01-02', + '11-12-13', + '12', + '34', + '2', + 'fixture', + 'test', + 'Chrome_68.0.3440_Windows_8.1.0.0', + 'Chrome', + '68.0.3440', + 'Windows', + '8.1.0.0' ].join('#') + '.png'; const pathPattern = createPathPattern(pattern, data); From cac637bd776d0c459fe11053df076e26a9ae79ce Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Mon, 3 Sep 2018 15:26:06 +0300 Subject: [PATCH 083/184] Bump version (v0.22.0-alpha.4) (#2802) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 13b8d28b..86307cc2 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.22.0-alpha.3", + "version": "0.22.0-alpha.4", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From 3f5f84b05333e8de2c20e4e4ab12f6cb9d86202e Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Mon, 3 Sep 2018 19:30:32 +0300 Subject: [PATCH 084/184] [docs] Add an announcement blog post for v0.22.0 (#2781) --- CHANGELOG.md | 18 ++--- .../2018-09-03-testcafe-v0-22-0-released.md | 77 +++++++++++++++++++ 2 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 docs/articles/blog/2018-09-03-testcafe-v0-22-0-released.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 71efb2c3..c9cc3a95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,12 @@ # Changelog -## v0.22.0 (2018-8-28) +## v0.22.0 (2018-9-3) ### Enhancements #### :gear: CoffeeScript Support ([#1556](https://github.com/DevExpress/testcafe/issues/1556)) by [@GeoffreyBooth](https://github.com/GeoffreyBooth) -TestCafe now allows you to write tests in CoffeeScript. You do not need to compile CoffeeScript manually or make any customizations, everything works out-of-the-box. +TestCafe now allows you to write tests in CoffeeScript. You do not need to compile CoffeeScript manually or make any customizations - everything works out of the box. ```coffee import { Selector } from 'testcafe' @@ -26,16 +26,15 @@ test 'Test', (t) => #### :gear: Failed Selector Method Pinpointed in the Report ([#2568](https://github.com/DevExpress/testcafe/issues/2568)) -When an incorrect call occurs in a chain of selector methods, the test run report now identifies the exact method that failed to match any DOM element. +Now the test run report can identify which selector's method does not match any DOM element. ![Failed Selector Report](docs/articles/images/failed-selector-report.png) #### :gear: Fail on Uncaught Server Errors ([#2546](https://github.com/DevExpress/testcafe/issues/2546)) -Previously, TestCafe ignored uncaught errors and unhandled promise rejections occurred on the server. Whenever an error or a promise rejection happened, test execution continued. +Previously, TestCafe ignored uncaught errors and unhandled promise rejections that occurred on the server. Whenever an error or a promise rejection happened, test execution continued. -Starting from v0.22.0, tests fail if a server error or a promise rejection is unhandled. To return to the previous behavior, we have introduced a `skipUncaughtErrors` option. Use the [--skipUncaughtErrors](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#-u---skip-uncaught-errors) flag -in the command line or the [skipUncaughtErrors](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#run) option in the API. +Starting from v0.22.0, tests fail if a server error or promise rejection is unhandled. To return to the previous behavior, we have introduced the `skipUncaughtErrors` option. Use the [--skip-uncaught-errors](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#-u---skip-uncaught-errors) flag in the command line or the [skipUncaughtErrors](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#run) option in the API. ```sh testcafe chrome tests/fixture.js --skipUncaughtErrors @@ -55,19 +54,20 @@ runner.src(['/home/user/tests/**/*.js', '!/home/user/tests/foo.js']); ### Bug Fixes -* The `RequestLogger` no longer fails when it tries to stringify a null request body ([#2718](https://github.com/DevExpress/testcafe/issues/2718)) +* `RequestLogger` no longer fails when it tries to stringify a null request body ([#2718](https://github.com/DevExpress/testcafe/issues/2718)) * Temporary directories are now correctly removed when the test run is finished ([#2735](https://github.com/DevExpress/testcafe/issues/2735)) * TestCafe no longer throws `ECONNRESET` when run against a Webpack project ([#2711](https://github.com/DevExpress/testcafe/issues/2711)) * An error is no longer thrown when TestCafe tests Sencha ExtJS applications in IE11 ([#2639](https://github.com/DevExpress/testcafe/issues/2639)) * Firefox no longer waits for page elements to appear without necessity ([#2080](https://github.com/DevExpress/testcafe/issues/2080)) +* `${BROWSER}` in the screenshot pattern now correctly resolves to the browser name ([#2742](https://github.com/DevExpress/testcafe/issues/2742)) * The `toString` function now returns a native string for overridden descriptor ancestors ([testcafe-hammerhead/#1713](https://github.com/DevExpress/testcafe-hammerhead/issues/1713)) * The `iframe` flag is no longer added when a form with `target="_parent"` is submitted ([testcafe-hammerhead/#1680](https://github.com/DevExpress/testcafe-hammerhead/issues/1680)) * Hammerhead no longer sends request headers in lower case ([testcafe-hammerhead/#1380](https://github.com/DevExpress/testcafe-hammerhead/issues/1380)) * The overridden `createHTMLDocument` method has the right context now ([testcafe-hammerhead/#1722](https://github.com/DevExpress/testcafe-hammerhead/issues/1722)) * Tests no longer lose connection ([testcafe-hammerhead/#1647](https://github.com/DevExpress/testcafe-hammerhead/issues/1647)) * The case when both the `X-Frame-Options` header and a CSP with `frame-ancestors` are set is now handled correctly ([testcafe-hammerhead/#1666](https://github.com/DevExpress/testcafe-hammerhead/issues/1666)) -* A mechanism that resolves URLs on the client now works correctly ([testcafe-hammerhead/#1701](https://github.com/DevExpress/testcafe-hammerhead/issues/1701)) -* `LiveNodeListWrapper` now imitates native behavior correctly ([testcafe-hammerhead/#1376](https://github.com/DevExpress/testcafe-hammerhead/issues/1376)) +* The mechanism that resolves URLs on the client now works correctly ([testcafe-hammerhead/#1701](https://github.com/DevExpress/testcafe-hammerhead/issues/1701)) +* `LiveNodeListWrapper` now imitates the native behavior correctly ([testcafe-hammerhead/#1376](https://github.com/DevExpress/testcafe-hammerhead/issues/1376)) ## v0.21.1 (2018-8-8) diff --git a/docs/articles/blog/2018-09-03-testcafe-v0-22-0-released.md b/docs/articles/blog/2018-09-03-testcafe-v0-22-0-released.md new file mode 100644 index 00000000..773abb90 --- /dev/null +++ b/docs/articles/blog/2018-09-03-testcafe-v0-22-0-released.md @@ -0,0 +1,77 @@ +--- +layout: post +title: TestCafe v0.22.0 Released +permalink: /blog/:title.html +--- +# TestCafe v0.22.0 Released + +Write tests in CoffeeScript, view failed selector methods in test run reports and detect server-side errors and unhandled promise rejections. + + + +## Enhancements + +### ⚙ CoffeeScript Support ([#1556](https://github.com/DevExpress/testcafe/issues/1556)) by [@GeoffreyBooth](https://github.com/GeoffreyBooth) + +TestCafe now allows you to write tests in CoffeeScript. You do not need to compile CoffeeScript manually or make any customizations - everything works out of the box. + +```coffee +import { Selector } from 'testcafe' + +fixture 'CoffeeScript Example' + .page 'https://devexpress.github.io/testcafe/example/' + +nameInput = Selector '#developer-name' + +test 'Test', (t) => + await t + .typeText(nameInput, 'Peter') + .typeText(nameInput, 'Paker', { replace: true }) + .typeText(nameInput, 'r', { caretPos: 2 }) + .expect(nameInput.value).eql 'Parker'; +``` + +### ⚙ Failed Selector Method Pinpointed in the Report ([#2568](https://github.com/DevExpress/testcafe/issues/2568)) + +Now the test run report can identify which selector's method does not match any DOM element. + +![Failed Selector Report](../images/failed-selector-report.png) + +### ⚙ Fail on Uncaught Server Errors ([#2546](https://github.com/DevExpress/testcafe/issues/2546)) + +Previously, TestCafe ignored uncaught errors and unhandled promise rejections that occurred on the server. Whenever an error or a promise rejection happened, test execution continued. + +Starting from v0.22.0, tests fail if a server error or promise rejection is unhandled. To return to the previous behavior, we have introduced the `skipUncaughtErrors` option. Use the [--skip-uncaught-errors](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#-u---skip-uncaught-errors) flag in the command line or the [skipUncaughtErrors](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#run) option in the API. + +```sh +testcafe chrome tests/fixture.js --skipUncaughtErrors +``` + +```js +runner.run({skipUncaughtErrors:true}) +``` + +### ⚙ Use Glob Patterns in `runner.src` ([#980](https://github.com/DevExpress/testcafe/issues/980)) + +You can now use [glob patterns](https://github.com/isaacs/node-glob#glob-primer) in the [runner.src](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#src) method to specify a set of test files. + +```js +runner.src(['/home/user/tests/**/*.js', '!/home/user/tests/foo.js']); +``` + +## Bug Fixes + +* `RequestLogger` no longer fails when it tries to stringify a null request body ([#2718](https://github.com/DevExpress/testcafe/issues/2718)) +* Temporary directories are now correctly removed when the test run is finished ([#2735](https://github.com/DevExpress/testcafe/issues/2735)) +* TestCafe no longer throws `ECONNRESET` when run against a Webpack project ([#2711](https://github.com/DevExpress/testcafe/issues/2711)) +* An error is no longer thrown when TestCafe tests Sencha ExtJS applications in IE11 ([#2639](https://github.com/DevExpress/testcafe/issues/2639)) +* Firefox no longer waits for page elements to appear without necessity ([#2080](https://github.com/DevExpress/testcafe/issues/2080)) +* `${BROWSER}` in the screenshot pattern now correctly resolves to the browser name ([#2742](https://github.com/DevExpress/testcafe/issues/2742)) +* The `toString` function now returns a native string for overridden descriptor ancestors ([testcafe-hammerhead/#1713](https://github.com/DevExpress/testcafe-hammerhead/issues/1713)) +* The `iframe` flag is no longer added when a form with `target="_parent"` is submitted ([testcafe-hammerhead/#1680](https://github.com/DevExpress/testcafe-hammerhead/issues/1680)) +* Hammerhead no longer sends request headers in lower case ([testcafe-hammerhead/#1380](https://github.com/DevExpress/testcafe-hammerhead/issues/1380)) +* The overridden `createHTMLDocument` method has the right context now ([testcafe-hammerhead/#1722](https://github.com/DevExpress/testcafe-hammerhead/issues/1722)) +* Tests no longer lose connection ([testcafe-hammerhead/#1647](https://github.com/DevExpress/testcafe-hammerhead/issues/1647)) +* The case when both the `X-Frame-Options` header and a CSP with `frame-ancestors` are set is now handled correctly ([testcafe-hammerhead/#1666](https://github.com/DevExpress/testcafe-hammerhead/issues/1666)) +* The mechanism that resolves URLs on the client now works correctly ([testcafe-hammerhead/#1701](https://github.com/DevExpress/testcafe-hammerhead/issues/1701)) +* `LiveNodeListWrapper` now imitates the native behavior correctly ([testcafe-hammerhead/#1376](https://github.com/DevExpress/testcafe-hammerhead/issues/1376)) From 111289de4eacfaf4544620179c8e05ed6718eaf5 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Tue, 4 Sep 2018 10:49:05 +0300 Subject: [PATCH 085/184] Bump version (v0.22.0) (#2804) --- .publishrc | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.publishrc b/.publishrc index 2414a453..5727c783 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "alpha", + "publishTag": "latest", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index 86307cc2..209cefb7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.22.0-alpha.4", + "version": "0.22.0", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From 69afb62966c5ea709d015e8009ac0fde493e42b4 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Tue, 4 Sep 2018 12:17:54 +0300 Subject: [PATCH 086/184] Implemented '--stop-on-first-fail' option (close #1323) (#2738) --- src/cli/argument-parser.js | 7 +- src/reporter/index.js | 35 ++--- src/runner/index.js | 54 ++++---- src/runner/task.js | 16 ++- src/runner/test-run-controller.js | 6 +- .../browser-provider/chrome-emulation/test.js | 14 +- .../browser-provider/custom-profile/test.js | 12 +- test/functional/fixtures/reporter/test.js | 41 ++---- .../run-options/stop-on-first-fail/test.js | 50 +++++++ .../stop-on-first-fail-test.js | 25 ++++ test/functional/setup.js | 82 ++++++------ test/functional/utils/null-stream.js | 1 - test/functional/utils/stream.js | 20 +++ test/server/cli-argument-parser-test.js | 20 +-- test/server/reporter-test.js | 123 ++++++++---------- 15 files changed, 297 insertions(+), 209 deletions(-) create mode 100644 test/functional/fixtures/run-options/stop-on-first-fail/test.js create mode 100644 test/functional/fixtures/run-options/stop-on-first-fail/testcafe-fixtures/stop-on-first-fail-test.js delete mode 100644 test/functional/utils/null-stream.js create mode 100644 test/functional/utils/stream.js diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index 50ea9165..2db4ad97 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -67,7 +67,7 @@ export default class CLIArgumentParser { } _describeProgram () { - var version = JSON.parse(read('../../package.json')).version; + const version = JSON.parse(read('../../package.json')).version; this.program @@ -104,6 +104,7 @@ export default class CLIArgumentParser { .option('--disable-page-reloads', 'disable page reloads between tests') .option('--dev', 'enables mechanisms to log and diagnose errors') .option('--qr-code', 'outputs QR-code that repeats URLs used to connect the remote browsers') + .option('--sf, --stop-on-first-fail', 'stop an entire test run if any test fails') // NOTE: these options will be handled by chalk internally .option('--color', 'force colors in command line') @@ -111,7 +112,7 @@ export default class CLIArgumentParser { } _filterAndCountRemotes (browser) { - var remoteMatch = browser.match(REMOTE_ALIAS_RE); + const remoteMatch = browser.match(REMOTE_ALIAS_RE); if (remoteMatch) { this.remoteCount += parseInt(remoteMatch[1], 10) || 1; @@ -197,7 +198,7 @@ export default class CLIArgumentParser { } _parseBrowserList () { - var browsersArg = this.program.args[0] || ''; + const browsersArg = this.program.args[0] || ''; this.browsers = splitQuotedText(browsersArg, ',') .filter(browser => browser && this._filterAndCountRemotes(browser)); diff --git a/src/reporter/index.js b/src/reporter/index.js index 626d242a..efa4bba5 100644 --- a/src/reporter/index.js +++ b/src/reporter/index.js @@ -5,17 +5,17 @@ export default class Reporter { constructor (plugin, task, outStream) { this.plugin = new ReporterPluginHost(plugin, outStream); - this.passed = 0; - this.skipped = task.tests.filter(test => test.skip).length; - this.testCount = task.tests.length - this.skipped; - this.reportQueue = Reporter._createReportQueue(task); + this.passed = 0; + this.skipped = task.tests.filter(test => test.skip).length; + this.testCount = task.tests.length - this.skipped; + this.reportQueue = Reporter._createReportQueue(task); + this.stopOnFirstFail = task.opts.stopOnFirstFail; this._assignTaskEventHandlers(task); } - // Static static _createReportQueue (task) { - var runsPerTest = task.browserConnectionGroups.length; + const runsPerTest = task.browserConnectionGroups.length; return task.tests.map(test => Reporter._createReportItem(test, runsPerTest)); } @@ -52,8 +52,8 @@ export default class Reporter { } _shiftReportQueue (reportItem) { - var currentFixture = null; - var nextReportItem = null; + let currentFixture = null; + let nextReportItem = null; while (this.reportQueue.length && this.reportQueue[0].testRunInfo) { reportItem = this.reportQueue.shift(); @@ -73,27 +73,28 @@ export default class Reporter { _assignTaskEventHandlers (task) { task.once('start', () => { - var startTime = new Date(); - var userAgents = task.browserConnectionGroups.map(group => group[0].userAgent); - var first = this.reportQueue[0]; + const startTime = new Date(); + const userAgents = task.browserConnectionGroups.map(group => group[0].userAgent); + const first = this.reportQueue[0]; this.plugin.reportTaskStart(startTime, userAgents, this.testCount); this.plugin.reportFixtureStart(first.fixture.name, first.fixture.path, first.fixture.meta); }); task.on('test-run-start', testRun => { - var reportItem = this._getReportItemForTestRun(testRun); + const reportItem = this._getReportItemForTestRun(testRun); if (!reportItem.startTime) reportItem.startTime = new Date(); }); task.on('test-run-done', testRun => { - var reportItem = this._getReportItemForTestRun(testRun); + const reportItem = this._getReportItemForTestRun(testRun); + const isTestRunStoppedTaskExecution = !!testRun.errs.length && this.stopOnFirstFail; - reportItem.pendingRuns--; - reportItem.unstable = reportItem.unstable || testRun.unstable; - reportItem.errs = reportItem.errs.concat(testRun.errs); + reportItem.pendingRuns = isTestRunStoppedTaskExecution ? 0 : reportItem.pendingRuns - 1; + reportItem.unstable = reportItem.unstable || testRun.unstable; + reportItem.errs = reportItem.errs.concat(testRun.errs); if (!reportItem.pendingRuns) { if (task.screenshots.hasCapturedFor(testRun.test)) { @@ -124,7 +125,7 @@ export default class Reporter { }); task.once('done', () => { - var endTime = new Date(); + const endTime = new Date(); this.plugin.reportTaskDone(endTime, this.passed, task.warningLog.messages); }); diff --git a/src/runner/index.js b/src/runner/index.js index 57918ea4..618a8fac 100644 --- a/src/runner/index.js +++ b/src/runner/index.js @@ -52,8 +52,8 @@ export default class Runner extends EventEmitter { } _createCancelablePromise (taskPromise) { - var promise = taskPromise.then(({ completionPromise }) => completionPromise); - var removeFromPending = () => remove(this.pendingTaskPromises, promise); + const promise = taskPromise.then(({ completionPromise }) => completionPromise); + const removeFromPending = () => remove(this.pendingTaskPromises, promise); promise .then(removeFromPending) @@ -68,10 +68,19 @@ export default class Runner extends EventEmitter { } // Run task + _getFailedTestCount (task, reporter) { + let failedTestCount = reporter.testCount - reporter.passed; + + if (task.opts.stopOnFirstFail && !!failedTestCount) + failedTestCount = 1; + + return failedTestCount; + } + async _getTaskResult (task, browserSet, reporter, testedApp) { task.on('browser-job-done', job => browserSet.releaseConnection(job.browserConnection)); - var promises = [ + const promises = [ promisifyEvent(task, 'done'), promisifyEvent(browserSet, 'error') ]; @@ -90,14 +99,14 @@ export default class Runner extends EventEmitter { await Runner._disposeBrowserSetAndTestedApp(browserSet, testedApp); - return reporter.testCount - reporter.passed; + return this._getFailedTestCount(task, reporter); } _runTask (reporterPlugins, browserSet, tests, testedApp) { - var completed = false; - var task = new Task(tests, browserSet.browserConnectionGroups, this.proxy, this.opts); - var reporters = reporterPlugins.map(reporter => new Reporter(reporter.plugin, task, reporter.outStream)); - var completionPromise = this._getTaskResult(task, browserSet, reporters[0], testedApp); + let completed = false; + const task = new Task(tests, browserSet.browserConnectionGroups, this.proxy, this.opts); + const reporters = reporterPlugins.map(reporter => new Reporter(reporter.plugin, task, reporter.outStream)); + const completionPromise = this._getTaskResult(task, browserSet, reporters[0], testedApp); task.once('start', startHandlingTestErrors); @@ -108,7 +117,7 @@ export default class Runner extends EventEmitter { task.once('done', stopHandlingTestErrors); - var setCompleted = () => { + const setCompleted = () => { completed = true; }; @@ -116,7 +125,7 @@ export default class Runner extends EventEmitter { .then(setCompleted) .catch(setCompleted); - var cancelTask = async () => { + const cancelTask = async () => { if (!completed) await Runner._disposeTaskAndRelatedAssets(task, browserSet, testedApp); }; @@ -218,19 +227,20 @@ export default class Runner extends EventEmitter { return this; } - run ({ skipJsErrors, disablePageReloads, quarantineMode, debugMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed = 1, debugOnFail, skipUncaughtErrors } = {}) { - this.opts.skipJsErrors = !!skipJsErrors; - this.opts.disablePageReloads = !!disablePageReloads; - this.opts.quarantineMode = !!quarantineMode; - this.opts.debugMode = !!debugMode; - this.opts.debugOnFail = !!debugOnFail; - this.opts.selectorTimeout = selectorTimeout === void 0 ? DEFAULT_SELECTOR_TIMEOUT : selectorTimeout; - this.opts.assertionTimeout = assertionTimeout === void 0 ? DEFAULT_ASSERTION_TIMEOUT : assertionTimeout; - this.opts.pageLoadTimeout = pageLoadTimeout === void 0 ? DEFAULT_PAGE_LOAD_TIMEOUT : pageLoadTimeout; - this.opts.speed = speed; + run ({ skipJsErrors, disablePageReloads, quarantineMode, debugMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed = 1, debugOnFail, skipUncaughtErrors, stopOnFirstFail } = {}) { + this.opts.skipJsErrors = !!skipJsErrors; + this.opts.disablePageReloads = !!disablePageReloads; + this.opts.quarantineMode = !!quarantineMode; + this.opts.debugMode = !!debugMode; + this.opts.debugOnFail = !!debugOnFail; + this.opts.selectorTimeout = selectorTimeout === void 0 ? DEFAULT_SELECTOR_TIMEOUT : selectorTimeout; + this.opts.assertionTimeout = assertionTimeout === void 0 ? DEFAULT_ASSERTION_TIMEOUT : assertionTimeout; + this.opts.pageLoadTimeout = pageLoadTimeout === void 0 ? DEFAULT_PAGE_LOAD_TIMEOUT : pageLoadTimeout; + this.opts.speed = speed; this.opts.skipUncaughtErrors = !!skipUncaughtErrors; + this.opts.stopOnFirstFail = !!stopOnFirstFail; - var runTaskPromise = Promise.resolve() + const runTaskPromise = Promise.resolve() .then(() => { this._validateRunOptions(); @@ -250,7 +260,7 @@ export default class Runner extends EventEmitter { // the pendingTaskPromises array, which leads to shifting indexes // towards the beginning. So, we must copy the array in order to iterate it, // or we can perform iteration from the end to the beginning. - var cancellationPromises = mapReverse(this.pendingTaskPromises, taskPromise => taskPromise.cancel()); + const cancellationPromises = mapReverse(this.pendingTaskPromises, taskPromise => taskPromise.cancel()); await Promise.all(cancellationPromises); } diff --git a/src/runner/task.js b/src/runner/task.js index 554e1d1d..e269d948 100644 --- a/src/runner/task.js +++ b/src/runner/task.js @@ -12,16 +12,24 @@ export default class Task extends EventEmitter { this.running = false; this.browserConnectionGroups = browserConnectionGroups; this.tests = tests; - this.screenshots = new Screenshots(opts.screenshotPath, opts.screenshotPathPattern); + this.opts = opts; + this.screenshots = new Screenshots(this.opts.screenshotPath, this.opts.screenshotPathPattern); this.warningLog = new WarningLog(); this.fixtureHookController = new FixtureHookController(tests, browserConnectionGroups.length); - this.pendingBrowserJobs = this._createBrowserJobs(proxy, opts); + this.pendingBrowserJobs = this._createBrowserJobs(proxy, this.opts); } _assignBrowserJobEventHandlers (job) { job.on('test-run-start', testRun => this.emit('test-run-start', testRun)); - job.on('test-run-done', testRun => this.emit('test-run-done', testRun)); + job.on('test-run-done', testRun => { + this.emit('test-run-done', testRun); + + if (this.opts.stopOnFirstFail && testRun.errs.length) { + this.abort(); + this.emit('done'); + } + }); job.once('start', () => { if (!this.running) { @@ -41,7 +49,7 @@ export default class Task extends EventEmitter { _createBrowserJobs (proxy, opts) { return this.browserConnectionGroups.map(browserConnectionGroup => { - var job = new BrowserJob(this.tests, browserConnectionGroup, proxy, this.screenshots, this.warningLog, this.fixtureHookController, opts); + const job = new BrowserJob(this.tests, browserConnectionGroup, proxy, this.screenshots, this.warningLog, this.fixtureHookController, opts); this._assignBrowserJobEventHandlers(job); browserConnectionGroup.map(bc => bc.addJob(job)); diff --git a/src/runner/test-run-controller.js b/src/runner/test-run-controller.js index 184cb820..cff54d92 100644 --- a/src/runner/test-run-controller.js +++ b/src/runner/test-run-controller.js @@ -3,8 +3,6 @@ import { TestRun as LegacyTestRun } from 'testcafe-legacy-api'; import TestRun from '../test-run'; import SessionController from '../test-run/session-controller'; - -// Const const QUARANTINE_THRESHOLD = 3; class Quarantine { @@ -123,9 +121,9 @@ export default class TestRunController extends EventEmitter { } async start (connection) { - var testRun = this._createTestRun(connection); + const testRun = this._createTestRun(connection); - var hookOk = await this.fixtureHookController.runFixtureBeforeHookIfNecessary(testRun); + const hookOk = await this.fixtureHookController.runFixtureBeforeHookIfNecessary(testRun); if (this.test.skip || !hookOk) { this.emit('test-run-start'); diff --git a/test/functional/fixtures/browser-provider/chrome-emulation/test.js b/test/functional/fixtures/browser-provider/chrome-emulation/test.js index adebabe8..50764a70 100644 --- a/test/functional/fixtures/browser-provider/chrome-emulation/test.js +++ b/test/functional/fixtures/browser-provider/chrome-emulation/test.js @@ -1,17 +1,17 @@ -const path = require('path'); -const expect = require('chai').expect; -const config = require('../../../config'); -const nullStream = require('../../../utils/null-stream'); +const path = require('path'); +const expect = require('chai').expect; +const config = require('../../../config'); +const { createNullStream } = require('../../../utils/stream'); if (config.useLocalBrowsers) { - describe('Browser Provider - Chrome Emulation Mode', function () { - it('Should emulate touch event handlers', function () { + describe('Browser Provider - Chrome Emulation Mode', () => { + it('Should emulate touch event handlers', () => { return testCafe .createRunner() .src(path.join(__dirname, './testcafe-fixtures/index-test.js')) .filter(fixtureName => fixtureName === 'Check presence of touch event handlers') - .reporter('minimal', nullStream) + .reporter('minimal', createNullStream()) .browsers('chrome:headless:emulation:device=iphone 6 --no-sandbox') .run() .then(failedCount => { diff --git a/test/functional/fixtures/browser-provider/custom-profile/test.js b/test/functional/fixtures/browser-provider/custom-profile/test.js index 05cda3a4..572caf99 100644 --- a/test/functional/fixtures/browser-provider/custom-profile/test.js +++ b/test/functional/fixtures/browser-provider/custom-profile/test.js @@ -2,18 +2,18 @@ const path = require('path'); const { expect } = require('chai'); const Promise = require('pinkie'); const config = require('../../../config'); -const nullStream = require('../../../utils/null-stream'); +const { createNullStream } = require('../../../utils/stream'); const createChromeProfile = require('../../../../../lib/browser/provider/built-in/chrome/create-temp-profile'); const createFirefoxProfile = require('../../../../../lib/browser/provider/built-in/firefox/create-temp-profile'); if (config.useLocalBrowsers && !config.isTravisEnvironment) { - describe('Browser Provider - Custom User Profile', function () { - it('Should run tests in userProfile mode', function () { + describe('Browser Provider - Custom User Profile', () => { + it('Should run tests in userProfile mode', () => { return testCafe .createRunner() .src(path.join(__dirname, './testcafe-fixtures/index-test.js')) - .reporter('minimal', nullStream) + .reporter('minimal', createNullStream()) .browsers('chrome:userProfile', 'firefox:userProfile') .run() .then(failedCount => { @@ -21,14 +21,14 @@ if (config.useLocalBrowsers && !config.isTravisEnvironment) { }); }); - it('Should run tests with the explicitly specified profile', function () { + it('Should run tests with the explicitly specified profile', () => { return Promise .all([createChromeProfile('localhost'), createFirefoxProfile({ config: {} })]) .then(([chromeProfile, firefoxProfile]) => { return testCafe .createRunner() .src(path.join(__dirname, './testcafe-fixtures/index-test.js')) - .reporter('minimal', nullStream) + .reporter('minimal', createNullStream()) .browsers(`chrome --user-data-dir=${chromeProfile.name}`, `firefox -profile ${firefoxProfile.name}`) .run(); }) diff --git a/test/functional/fixtures/reporter/test.js b/test/functional/fixtures/reporter/test.js index 888010cf..1f8276b4 100644 --- a/test/functional/fixtures/reporter/test.js +++ b/test/functional/fixtures/reporter/test.js @@ -1,27 +1,10 @@ -var expect = require('chai').expect; +const expect = require('chai').expect; +const { createTestStream } = require('../../utils/stream'); -describe('Reporter', function () { +describe('Reporter', () => { it('Should support several different reporters for a test run', function () { - var data1 = ''; - var data2 = ''; - var stream1 = { - write: function (data) { - data1 += data; - }, - - end: function (data) { - data1 += data; - } - }; - var stream2 = { - write: function (data) { - data2 += data; - }, - - end: function (data) { - data2 += data; - } - }; + const stream1 = createTestStream(); + const stream2 = createTestStream(); return runTests('testcafe-fixtures/index-test.js', 'Simple test', { only: ['chrome'], @@ -36,13 +19,13 @@ describe('Reporter', function () { } ] }) - .then(function () { - expect(data1).to.contains('Chrome'); - expect(data1).to.contains('Reporter'); - expect(data1).to.contains('Simple test'); - expect(data2).to.contains('Chrome'); - expect(data2).to.contains('Reporter'); - expect(data2).to.contains('Simple test'); + .then(() => { + expect(stream1.data).to.contains('Chrome'); + expect(stream1.data).to.contains('Reporter'); + expect(stream1.data).to.contains('Simple test'); + expect(stream2.data).to.contains('Chrome'); + expect(stream2.data).to.contains('Reporter'); + expect(stream2.data).to.contains('Simple test'); }); }); }); diff --git a/test/functional/fixtures/run-options/stop-on-first-fail/test.js b/test/functional/fixtures/run-options/stop-on-first-fail/test.js new file mode 100644 index 00000000..df1fe2ea --- /dev/null +++ b/test/functional/fixtures/run-options/stop-on-first-fail/test.js @@ -0,0 +1,50 @@ +const expect = require('chai').expect; +const fs = require('fs'); +const { createTestStream } = require('../../../utils/stream'); +const ReporterPluginHost = require('../../../../../lib/reporter/plugin-host'); + +const TEST_RUN_COUNT_FILENAME = 'testRunCount.txt'; + +const getTestRunCount = () => { + const content = fs.readFileSync(TEST_RUN_COUNT_FILENAME).toString(); + + return parseInt(content, 10); +}; + +describe('Stop test task on first failed test', () => { + afterEach(() => { + fs.unlinkSync(TEST_RUN_COUNT_FILENAME); + }); + + it('Basic', () => { + return runTests('./testcafe-fixtures/stop-on-first-fail-test.js', void 0, { + shouldFail: true, + stopOnFirstFail: true, + only: 'chrome' + }).catch(() => { + expect(getTestRunCount()).eql(2); + expect(testReport.failedCount).eql(1); + }); + }); + + it('Reporting', () => { + const stream = createTestStream(); + + return runTests('./testcafe-fixtures/stop-on-first-fail-test.js', void 0, { + shouldFail: true, + stopOnFirstFail: true, + reporters: [{ + reporter: 'spec', + outStream: stream + }] + }).catch(() => { + const pluginHost = new ReporterPluginHost({ noColors: true }); + const { ok, err } = pluginHost.symbols; + + expect(stream.data).contains(`${ok} test1`); + expect(stream.data).contains(`${err} test2`); + expect(stream.data).to.not.contains(`${ok} test3`); + expect(stream.data).contains('2/3 failed'); + }); + }); +}); diff --git a/test/functional/fixtures/run-options/stop-on-first-fail/testcafe-fixtures/stop-on-first-fail-test.js b/test/functional/fixtures/run-options/stop-on-first-fail/testcafe-fixtures/stop-on-first-fail-test.js new file mode 100644 index 00000000..a603dff0 --- /dev/null +++ b/test/functional/fixtures/run-options/stop-on-first-fail/testcafe-fixtures/stop-on-first-fail-test.js @@ -0,0 +1,25 @@ +import fs from 'fs'; + +fixture `Stop on first fail test`; + +let testRunCount = 0; + +const updateTestRunCount = () => { + testRunCount++; + + fs.writeFileSync('testRunCount.txt', testRunCount); +}; + +test('test1', async () => { + updateTestRunCount(); +}); + +test('test2', async t => { + updateTestRunCount(); + + await t.expect(false).ok(); +}); + +test('test3', async () => { + updateTestRunCount(); +}); diff --git a/test/functional/setup.js b/test/functional/setup.js index 350c8962..21c36f6b 100644 --- a/test/functional/setup.js +++ b/test/functional/setup.js @@ -1,15 +1,16 @@ -var SlConnector = require('saucelabs-connector'); -var BsConnector = require('browserstack-connector'); -var Promise = require('pinkie'); -var caller = require('caller'); -var path = require('path'); -var promisifyEvent = require('promisify-event'); -var createTestCafe = require('../../lib'); -var browserProviderPool = require('../../lib/browser/provider/pool'); -var BrowserConnection = require('../../lib/browser/connection'); -var config = require('./config.js'); -var site = require('./site'); -var getTestError = require('./get-test-error.js'); +const SlConnector = require('saucelabs-connector'); +const BsConnector = require('browserstack-connector'); +const Promise = require('pinkie'); +const caller = require('caller'); +const path = require('path'); +const promisifyEvent = require('promisify-event'); +const createTestCafe = require('../../lib'); +const browserProviderPool = require('../../lib/browser/provider/pool'); +const BrowserConnection = require('../../lib/browser/connection'); +const config = require('./config.js'); +const site = require('./site'); +const getTestError = require('./get-test-error.js'); +const { createTestStream } = require('./utils/stream'); var testCafe = null; var browsersInfo = null; @@ -157,8 +158,8 @@ before(function () { global.testReport = null; global.testCafe = testCafe; - global.runTests = function (fixture, testName, opts) { - let report = ''; + global.runTests = (fixture, testName, opts) => { + const stream = createTestStream(); const runner = testCafe.createRunner(); const fixturePath = typeof fixture !== 'string' || path.isAbsolute(fixture) ? fixture : path.join(path.dirname(caller()), fixture); const skipJsErrors = opts && opts.skipJsErrors; @@ -179,12 +180,13 @@ before(function () { const proxyBypass = opts && opts.proxyBypass; const customReporters = opts && opts.reporters; const skipUncaughtErrors = opts && opts.skipUncaughtErrors; + const stopOnFirstFail = opts && opts.stopOnFirstFail; - var actualBrowsers = browsersInfo.filter(function (browserInfo) { - var { alias, userAgent } = browserInfo.settings; + const actualBrowsers = browsersInfo.filter(browserInfo => { + const { alias, userAgent } = browserInfo.settings; - var only = onlyOption ? [alias, userAgent].some(prop => onlyOption.indexOf(prop) > -1) : true; - var skip = skipOption ? [alias, userAgent].some(prop => skipOption.indexOf(prop) > -1) : false; + const only = onlyOption ? [alias, userAgent].some(prop => onlyOption.includes(prop)) : true; + const skip = skipOption ? [alias, userAgent].some(prop => skipOption.includes(prop)) : false; return only && !skip; }); @@ -194,12 +196,12 @@ before(function () { return Promise.resolve(); } - var connections = actualBrowsers.map(function (browserInfo) { + const connections = actualBrowsers.map(browserInfo => { return browserInfo.connection; }); - var handleError = function (err) { - var shouldFail = opts && opts.shouldFail; + const handleError = (err) => { + const shouldFail = opts && opts.shouldFail; if (shouldFail && !err) throw new Error('Test should have failed but it succeeded'); @@ -210,39 +212,41 @@ before(function () { if (customReporters) customReporters.forEach(r => runner.reporter(r.reporter, r.outStream)); - else { - runner.reporter('json', { - write: function (data) { - report += data; - }, - - end: function (data) { - report += data; - } - }); - } + else + runner.reporter('json', stream); return runner .useProxy(externalProxyHost, proxyBypass) .browsers(connections) - .filter(function (test) { + .filter(test => { return testName ? test === testName : true; }) .src(fixturePath) .screenshots(screenshotPath, screenshotsOnFails, screenshotPathPattern) .startApp(appCommand, appInitDelay) - .run({ skipJsErrors, disablePageReloads, quarantineMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed, skipUncaughtErrors: skipUncaughtErrors }) - .then(function () { + .run({ + skipJsErrors, + disablePageReloads, + quarantineMode, + selectorTimeout, + assertionTimeout, + pageLoadTimeout, + speed, + stopOnFirstFail, + skipUncaughtErrors + }) + .then(failedCount => { if (customReporters) return; - var taskReport = JSON.parse(report); - var errorDescr = getTestError(taskReport, actualBrowsers); - var testReport = taskReport.fixtures.length === 1 ? + const taskReport = JSON.parse(stream.data); + const errorDescr = getTestError(taskReport, actualBrowsers); + const testReport = taskReport.fixtures.length === 1 ? taskReport.fixtures[0].tests[0] : taskReport; - testReport.warnings = taskReport.warnings; + testReport.warnings = taskReport.warnings; + testReport.failedCount = failedCount; global.testReport = testReport; diff --git a/test/functional/utils/null-stream.js b/test/functional/utils/null-stream.js deleted file mode 100644 index 5d7269ce..00000000 --- a/test/functional/utils/null-stream.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { write: () => {}, end: () => {} }; diff --git a/test/functional/utils/stream.js b/test/functional/utils/stream.js new file mode 100644 index 00000000..8416bf0d --- /dev/null +++ b/test/functional/utils/stream.js @@ -0,0 +1,20 @@ +module.exports.createTestStream = () => { + const stream = { + data: '', + write: function (val) { + this.data += val; + }, + end: function (val) { + this.data += val; + } + }; + + return stream; +}; + +module.exports.createNullStream = () => { + return { + write: () => {}, + end: () => {} + }; +}; diff --git a/test/server/cli-argument-parser-test.js b/test/server/cli-argument-parser-test.js index bc024334..359d94ce 100644 --- a/test/server/cli-argument-parser-test.js +++ b/test/server/cli-argument-parser-test.js @@ -337,8 +337,8 @@ describe('CLI argument parser', function () { }); it('Should parse command line arguments', function () { - return parse('-r list -S -q -e --hostname myhost --proxy localhost:1234 --proxy-bypass localhost:5678 --qr-code --app run-app --speed 0.5 --debug-on-fail --disable-page-reloads --dev ie test/server/data/file-list/file-1.js') - .then(function (parser) { + return parse('-r list -S -q -e --hostname myhost --proxy localhost:1234 --proxy-bypass localhost:5678 --qr-code --app run-app --speed 0.5 --debug-on-fail --disable-page-reloads --dev --sf ie test/server/data/file-list/file-1.js') + .then(parser => { expect(parser.browsers).eql(['ie']); expect(parser.src).eql(['test/server/data/file-list/file-1.js']); expect(parser.opts.reporters[0].name).eql('list'); @@ -355,12 +355,13 @@ describe('CLI argument parser', function () { expect(parser.opts.proxy).to.be.ok; expect(parser.opts.proxyBypass).to.be.ok; expect(parser.opts.debugOnFail).to.be.ok; + expect(parser.opts.stopOnFirstFail).to.be.ok; }); }); - it('Should has static CLI', function () { - var WARNING = 'IMPORTANT: Please be sure what you want to change CLI if this test is failing!'; - var EXPECTED_OPTIONS = [ + it('Should has static CLI', () => { + const WARNING = 'IMPORTANT: Please be sure what you want to change CLI if this test is failing!'; + const EXPECTED_OPTIONS = [ { long: '--version', short: '-v' }, { long: '--list-browsers', short: '-b' }, { long: '--reporter', short: '-r' }, @@ -392,15 +393,16 @@ describe('CLI argument parser', function () { { long: '--qr-code' }, { long: '--skip-uncaught-errors' }, { long: '--color' }, - { long: '--no-color' } + { long: '--no-color' }, + { long: '--stop-on-first-fail', short: '--sf' } ]; - var parser = new CliArgumentParser(''); - var options = parser.program.options; + const parser = new CliArgumentParser(''); + const options = parser.program.options; expect(options.length).eql(EXPECTED_OPTIONS.length, WARNING); - for (var i = 0; i < EXPECTED_OPTIONS.length; i++) + for (let i = 0; i < EXPECTED_OPTIONS.length; i++) expect(find(options, EXPECTED_OPTIONS[i])).not.eql(void 0, WARNING); }); }); diff --git a/test/server/reporter-test.js b/test/server/reporter-test.js index a022fabe..ecd87d01 100644 --- a/test/server/reporter-test.js +++ b/test/server/reporter-test.js @@ -1,21 +1,19 @@ -var expect = require('chai').expect; -var EventEmitter = require('events').EventEmitter; -var util = require('util'); -var Promise = require('pinkie'); -var chunk = require('lodash').chunk; -var Reporter = require('../../lib/reporter'); +const expect = require('chai').expect; +const EventEmitter = require('events').EventEmitter; +const Promise = require('pinkie'); +const { chunk, random } = require('lodash'); +const Reporter = require('../../lib/reporter'); - -describe('Reporter', function () { +describe('Reporter', () => { // Runnable configuration mocks - var screenshotDir = '/screenshots/1445437598847'; + const screenshotDir = '/screenshots/1445437598847'; - var browserConnectionMocks = [ + const browserConnectionMocks = [ { userAgent: 'Chrome' }, { userAgent: 'Firefox' } ]; - var fixtureMocks = [ + const fixtureMocks = [ { name: 'fixture1', path: './file1.js', @@ -37,7 +35,7 @@ describe('Reporter', function () { } ]; - var testMocks = [ + const testMocks = [ { name: 'fixture1test1', fixture: fixtureMocks[0], @@ -108,9 +106,8 @@ describe('Reporter', function () { } ]; - // Test run mocks - var chromeTestRunMocks = [ + const chromeTestRunMocks = [ //fixture1test1 { test: testMocks[0], @@ -168,8 +165,7 @@ describe('Reporter', function () { } ]; - - var firefoxTestRunMocks = [ + const firefoxTestRunMocks = [ //fixture1test1 { test: testMocks[0], @@ -223,74 +219,71 @@ describe('Reporter', function () { } ]; - chromeTestRunMocks.concat(firefoxTestRunMocks).forEach(function (testRunMock) { - testRunMock.errs.forEach(function (err) { + chromeTestRunMocks.concat(firefoxTestRunMocks).forEach(testRunMock => { + testRunMock.errs.forEach(err => { err.userAgent = testRunMock.browserConnection.userAgent; }); }); - var ScreenshotsMock = function () { - this.getScreenshotsInfo = function (testMock) { + class ScreenshotsMock { + constructor () {} + + getScreenshotsInfo (testMock) { return testMock.screenshots; - }; + } - this.hasCapturedFor = function (testMock) { + hasCapturedFor (testMock) { return this.getScreenshotsInfo(testMock); - }; + } - this.getPathFor = function () { + getPathFor () { return screenshotDir; - }; - }; - - - // Task mock - var TaskMock = function () { - EventEmitter.call(this); + } + } - this.tests = testMocks; - this.browserConnectionGroups = chunk(browserConnectionMocks, 1); - this.screenshots = new ScreenshotsMock(); + class TaskMock extends EventEmitter { + constructor () { + super(); - this.warningLog = { - messages: [ - 'warning1', - 'warning2' - ] - }; - }; + this.tests = testMocks; + this.opts = { stopOnFirstFail: false }; + this.browserConnectionGroups = chunk(browserConnectionMocks, 1); + this.screenshots = new ScreenshotsMock(); - util.inherits(TaskMock, EventEmitter); + this.warningLog = { + messages: [ + 'warning1', + 'warning2' + ] + }; + } + } // Browser job emulation function delay () { - var MIN = 0; - var MAX = 10; - var duration = Math.floor(Math.random() * (MAX - MIN + 1)) + MIN; - - return new Promise(function (resolve) { - setTimeout(resolve, duration); + return new Promise(resolve => { + setTimeout(resolve, random(0, 10)); }); } function emulateBrowserJob (taskMock, testRunMocks) { - return testRunMocks.reduce(function (chain, testRun) { + return testRunMocks.reduce((chain, testRun) => { return chain - .then(function () { + .then(() => { taskMock.emit('test-run-start', testRun); }) .then(delay) - .then(function () { + .then(() => { taskMock.emit('test-run-done', testRun); }) .then(delay); }, delay()); } - it('Should analyze task progress and call appropriate plugin methods', function () { - var taskMock = new TaskMock(); + it('Should analyze task progress and call appropriate plugin methods', () => { + const taskMock = new TaskMock(); - var expectedCalls = [ + const expectedCalls = [ { method: 'reportTaskStart', args: [ @@ -489,12 +482,10 @@ describe('Reporter', function () { } ]; - var reporter = new Reporter({ + const reporter = new Reporter({ calls: [], - reportTaskStart: function () { - var args = Array.prototype.slice.call(arguments); - + reportTaskStart: function (...args) { expect(args[0]).to.be.a('date'); // NOTE: replace startTime @@ -507,9 +498,7 @@ describe('Reporter', function () { this.calls.push({ method: 'reportFixtureStart', args: Array.prototype.slice.call(arguments) }); }, - reportTestDone: function () { - var args = Array.prototype.slice.call(arguments); - + reportTestDone: function (...args) { expect(args[1].durationMs).to.be.an('number'); // NOTE: replace durationMs @@ -518,9 +507,7 @@ describe('Reporter', function () { this.calls.push({ method: 'reportTestDone', args: args }); }, - reportTaskDone: function () { - var args = Array.prototype.slice.call(arguments); - + reportTaskDone: function (...args) { expect(args[0]).to.be.a('date'); // NOTE: replace endTime @@ -537,16 +524,16 @@ describe('Reporter', function () { emulateBrowserJob(taskMock, chromeTestRunMocks), emulateBrowserJob(taskMock, firefoxTestRunMocks) ]) - .then(function () { + .then(() => { taskMock.emit('done'); expect(reporter.plugin.calls).eql(expectedCalls); }); }); - it('Should disable colors if plugin has "noColors" flag', function () { - var taskMock = new TaskMock(); - var reporter = new Reporter({ noColors: true }, taskMock); + it('Should disable colors if plugin has "noColors" flag', () => { + const taskMock = new TaskMock(); + const reporter = new Reporter({ noColors: true }, taskMock); expect(reporter.plugin.chalk.enabled).to.be.false; }); From f501e34203cafe2df0761a592cf336966d03501a Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Tue, 4 Sep 2018 17:21:40 +0300 Subject: [PATCH 087/184] [docs] Update the Debugging in VS Code recipe (#2713) * Update the Debugging in VS Code recipe * Fix broken links * Add a couple of images * Address Margarita's remark --- docs/README.md | 4 +- docs/articles/documentation/recipes/README.md | 4 +- ...-tools.md => debug-in-chrome-dev-tools.md} | 6 +- .../recipes/debug-in-visual-studio-code.md | 70 ++++++++++++++++++ .../debugging-with-visual-studio-code.md | 58 --------------- .../documentation/test-api/debugging.md | 4 +- .../recipe-vscode-configuration-file.png | Bin 0 -> 102298 bytes .../recipe-vscode-debugging-breakpoint.png | Bin 0 -> 153820 bytes .../recipe-vscode-select-configuration.png | Bin 0 -> 14024 bytes docs/nav/nav-menu.yml | 8 +- 10 files changed, 83 insertions(+), 71 deletions(-) rename docs/articles/documentation/recipes/{debugging-with-chrome-dev-tools.md => debug-in-chrome-dev-tools.md} (89%) create mode 100644 docs/articles/documentation/recipes/debug-in-visual-studio-code.md delete mode 100644 docs/articles/documentation/recipes/debugging-with-visual-studio-code.md create mode 100644 docs/articles/images/recipe-vscode-configuration-file.png create mode 100644 docs/articles/images/recipe-vscode-debugging-breakpoint.png create mode 100644 docs/articles/images/recipe-vscode-select-configuration.png diff --git a/docs/README.md b/docs/README.md index 5afa119d..5413e97e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -87,8 +87,8 @@ * [Browser Provider Plugin](articles/documentation/extending-testcafe/browser-provider-plugin/README.md) * [Browser Provider Methods](articles/documentation/extending-testcafe/browser-provider-plugin/browser-provider-methods.md) * [RECIPES](articles/documentation/recipes/README.md) - * [Debugging with Chrome Developer Tools](articles/documentation/recipes/debugging-with-chrome-dev-tools.md) - * [Debugging with Visual Studio Code](articles/documentation/recipes/debugging-with-visual-studio-code.md) + * [Debug in Chrome Developer Tools](articles/documentation/recipes/debug-in-chrome-dev-tools.md) + * [Debug in Visual Studio Code](articles/documentation/recipes/debug-in-visual-studio-code.md) * [Integrating TestCafe with CI Systems](articles/documentation/recipes/integrating-testcafe-with-ci-systems/README.md) * [AppVeyor](articles/documentation/recipes/integrating-testcafe-with-ci-systems/appveyor.md) * [CircleCI](articles/documentation/recipes/integrating-testcafe-with-ci-systems/circleci.md) diff --git a/docs/articles/documentation/recipes/README.md b/docs/articles/documentation/recipes/README.md index df329452..5858819f 100644 --- a/docs/articles/documentation/recipes/README.md +++ b/docs/articles/documentation/recipes/README.md @@ -7,8 +7,8 @@ permalink: /documentation/recipes/ This section provides examples and recipes of how to use TestCafe in different scenarios. -* [Debugging with Chrome Developer Tools](debugging-with-chrome-dev-tools.md) -* [Debugging with Visual Studio Code](debugging-with-visual-studio-code.md) +* [Debug in Chrome Developer Tools](debug-in-chrome-dev-tools.md) +* [Debug in Visual Studio Code](debug-in-visual-studio-code.md) * [Finding Code Issues with Flow Type Checker](finding-code-issues-with-flow-type-checker.md) * [Integrating TestCafe with CI Systems](integrating-testcafe-with-ci-systems/README.md) * [Running Tests Using Travis CI and Sauce Labs](running-tests-using-travis-ci-and-sauce-labs.md) diff --git a/docs/articles/documentation/recipes/debugging-with-chrome-dev-tools.md b/docs/articles/documentation/recipes/debug-in-chrome-dev-tools.md similarity index 89% rename from docs/articles/documentation/recipes/debugging-with-chrome-dev-tools.md rename to docs/articles/documentation/recipes/debug-in-chrome-dev-tools.md index 7e71284e..872af677 100644 --- a/docs/articles/documentation/recipes/debugging-with-chrome-dev-tools.md +++ b/docs/articles/documentation/recipes/debug-in-chrome-dev-tools.md @@ -1,9 +1,9 @@ --- layout: docs -title: Debugging with Chrome Developer Tools -permalink: /documentation/recipes/debugging-with-chrome-dev-tools.html +title: Debug in Chrome Developer Tools +permalink: /documentation/recipes/debug-in-chrome-dev-tools.html --- -# Debugging with Chrome Developer Tools +# Debug in Chrome Developer Tools Starting with version 6.3.0, Node.js allows you to debug applications in Chrome Developer Tools. If you have Chrome and an appropriate version of Node.js installed on your machine, diff --git a/docs/articles/documentation/recipes/debug-in-visual-studio-code.md b/docs/articles/documentation/recipes/debug-in-visual-studio-code.md new file mode 100644 index 00000000..fad881fa --- /dev/null +++ b/docs/articles/documentation/recipes/debug-in-visual-studio-code.md @@ -0,0 +1,70 @@ +--- +layout: docs +title: Debug in Visual Studio Code +permalink: /documentation/recipes/debug-in-visual-studio-code.html +--- +# Debug in Visual Studio Code + +Before you debug in Visual Studio Code, ensure that your root test directory contains a `package.json` file that includes `testcafe` in the `devDependencies` section. + +```json +{ + "devDependencies": { + "testcafe": "x.y.z" + } +} +``` + +where `x.y.z` is the TestCafe version you use. + +Then you need to install TestCafe locally in the test directory. + +```sh +npm install +``` + +The next step adds a launch configuration used to run TestCafe tests. + +![Configuration File](../../images/recipe-vscode-configuration-file.png) + +See the [Visual Studio Code documentation](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations) to learn how to create a configuration. + +You need to add the following configuration to the `launch.json` file. + +```json +{ + "type": "node", + "protocol": "inspector", + "request": "launch", + "name": "Launch test files with TestCafe", + "program": "${workspaceRoot}/node_modules/testcafe/bin/testcafe.js", + "args": [ + "firefox", + "${file}" + ], + "console": "integratedTerminal", + "cwd": "${workspaceRoot}" +} +``` + +This configuration contains the following attributes: + +* `type` - specifies the configuration type. Set to `node` for a Node.js configuration. +* `protocol` - specifies the Node.js [debugger wire protocol](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_supported-nodelike-runtimes). Note that the inspector protocol is supported in Node.js v6.3 (or v6.9 for Windows) or later. For early versions, omit this property. In that case, Node.js uses a legacy debugger protocol. The legacy protocol has issues with source map support, therefore newer versions of Node.js are recommended. +* `request` - specifies the request type. Set to `launch` since this configuration launches a program. +* `name` - specifies the configuration name. +* `program` - path to the executed JS file. In this case, this file is the TestCafe module. +* `args` - [command line arguments](../using-testcafe/command-line-interface.md) passed to the launched program. In this case, they specify the browser in which the tests should run and the test file. +* `console` - the console where the test run report is printed. In this case, the report is output to the integrated terminal. You can learn about other available values in the [Launch.json attributes](https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes) topic. +* `cwd` - the current working directory. Set to the workspace root. + +Save the `launch.json` file. The new configuration then appears in the configuration drop-down. + +![Select Configuration](../../images/recipe-vscode-select-configuration.png) + +Now you can open a file with TestCafe tests, select the `"Launch test files with TestCafe"` configuration and click the **Run** button. +Tests run with the debugger attached. You can put breakpoints in test code and the debugger stops at them. + +![Stop at a Breakpoint](../../images/recipe-vscode-debugging-breakpoint.png) + +> Important! If you do not select the `"Launch test files with TestCafe"` configuration, Visual Studio Code tries to run the test file as a program and throws an error. \ No newline at end of file diff --git a/docs/articles/documentation/recipes/debugging-with-visual-studio-code.md b/docs/articles/documentation/recipes/debugging-with-visual-studio-code.md deleted file mode 100644 index 4b2dfc0a..00000000 --- a/docs/articles/documentation/recipes/debugging-with-visual-studio-code.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -layout: docs -title: Debugging with Visual Studio Code -permalink: /documentation/recipes/debugging-with-visual-studio-code.html ---- -# Debugging with Visual Studio Code - -Before debugging in Visual Studio Code, ensure that your root test directory contains a `package.json` file that includes `testcafe` in the `devDependencies` section. - -```json -{ - "devDependencies": { - "testcafe": "x.y.z" - } -} -``` - -where `x.y.z` is the TestCafe version you use. - -Then you need to install TestCafe locally in the tests directory via `npm`. - -```sh -npm install -``` - -The next step is adding a launch configuration that runs TestCafe tests. See the [Visual Studio Code documentation](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations) to learn how to create a configuration. - -You will need to add the following configuration to the `launch.json` file. - -```json -{ - "type": "node", - "protocol": "inspector", - "request": "launch", - "name": "Launch test files with TestCafe", - "program": "${workspaceRoot}/node_modules/testcafe/bin/testcafe.js", - "args": [ - "firefox", - "${file}" - ], - "cwd": "${workspaceRoot}" -} -``` - -This configuration contains the following attributes: - -* `type` - specifies the type of the configuration. Set to `node` for a Node.js configuration. -* `protocol` - specifies the Node.js [debugger wire protocol](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_supported-nodelike-runtimes). Note that the inspector protocol is supported in Node.js v6.3 (or v6.9 for Windows) or later. For early versions, omit this property. In that case, a legacy debugger protocol will be used. Legacy protocol is well known for its issues with source map support, therefore newer versions of Node.js are recommended. -* `request` - specifies the request type. Set to `launch` since this configuration launches a program. -* `name` - specifies the name of the configuration. -* `program` - path to a JS file that will be executed. In this case, it is the TestCafe module. -* `args` - [command line arguments](../using-testcafe/command-line-interface.md) passed to the launched program. In this case, they specify the browser in which the tests should run and the test file. -* `cwd` - the current working directory. Set to the workspace root. - -Save the `launch.json` file. The new configuration will appear in the configuration drop-down. - -Now you can open a file with TestCafe tests, select the configuration you have just created and click the Run button. -Tests will run with the debugger attached. You can put breakpoints in test code and the debugger will stop at them. diff --git a/docs/articles/documentation/test-api/debugging.md b/docs/articles/documentation/test-api/debugging.md index 47db5aa2..ef44e6fc 100644 --- a/docs/articles/documentation/test-api/debugging.md +++ b/docs/articles/documentation/test-api/debugging.md @@ -16,8 +16,8 @@ TestCafe allows you to debug server-side test code and test behavior on the clie You can debug test code in Chrome Developer Tools and popular IDEs. See the following recipes for details. -* [Debugging with Chrome Developer Tools](../recipes/debugging-with-chrome-dev-tools.md) -* [Debugging with Visual Studio Code](../recipes/debugging-with-visual-studio-code.md) +* [Debug in Chrome Developer Tools](../recipes/debug-in-chrome-dev-tools.md) +* [Debug in Visual Studio Code](../recipes/debug-in-visual-studio-code.md) ## Client-Side Debugging diff --git a/docs/articles/images/recipe-vscode-configuration-file.png b/docs/articles/images/recipe-vscode-configuration-file.png new file mode 100644 index 0000000000000000000000000000000000000000..c5cc5d211e69345fcb805732f6a821f3b889003a GIT binary patch literal 102298 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�d=Yt&0b3ZT_AX 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%0DOggGj995h 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 literal 0 HcmV?d00001 diff --git a/docs/articles/images/recipe-vscode-debugging-breakpoint.png b/docs/articles/images/recipe-vscode-debugging-breakpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..397ed4b37240211a31e3da55b2a80fee37ca637b GIT binary patch literal 153820 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
!r`_&Oa?k3~;w8A_akbNJ8if>0U_Dae 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 literal 0 HcmV?d00001 diff --git a/docs/articles/images/recipe-vscode-select-configuration.png b/docs/articles/images/recipe-vscode-select-configuration.png new file mode 100644 index 0000000000000000000000000000000000000000..48e0f3979e6adeb26bd5aa66339b3a2c0d4dffed GIT binary patch literal 14024 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

P@qKeSLOTjESS#lHNXtfHRyp z?wL*O(ref5g~l}y!RJrw8~xi-IqxAQ!Bk)wPoFdExG#9wtv ziC}*oZ!Lvz_+U-CS0ofyXLpSXGGOdi#YXw(peVue=iLgEJgwv)6B+3ncPE}n<8err zFK*{%G(mDUS~GX#%vQ$p)Gq~F-y#YUMT?sKK=YhUw~PoyxJ(}hT}tE|lWph`F@;M5 z=KxCc5;@x2MJ*F5R?~+of~b zH$pB7mpo$qHGUDVKTRe4;yH8w-y~KxO-*|!3lLlQeXL4nx#Mt|Pll|>(HgjIs(fO#B>p%8q zZh`- z`3S;u(NC(&3q3QQ-)A-KQaF>NqY@Phr0L_sf9-h@nThFJ^h)-M`m<6E|NUE1g>}H2 zESjM|whj8XP2)R$(DAiSf%0)5M}tUZc$DUcY!pGU0%=1m<2Ur{X&z0PBQEBJ*!ZR#a;l2U5e&1wSnMZ- z?Sn|(tKqk(qB?)WZy_(!zvCtkDvIy-56k$RePqoIFT)3*_Ns4osvAh@uvfS`5s}@K zTQ5pXn{t##sGY&!xWyGbK))zi-FiyHJ&l@^TbrA=H^BXWrYRJnx?7C6XyLQ}F0Nf9 zAwdd)YNBCK=t!gwmd;;F)LpgY&a7sy~EL^4}|GcS}v0QAuVm~WG8FY2|UW;)i zec~t`f4B(Gj#P2gpZ@}_={xynjOK}?Ix$i)-4wfa`1k0viY9XLE6Qmu3byh^cp4Fqf%GdX``jzqcS8hrAcel#Ko0nM#jH2nKKo4 zJN-C-&z&LsbO-UqIWh{d)Vw>s%doCJF#h+=n9A}_?3C}T@jgc29pX}rtqw9r418ai zi{n*FWfUmET29iWQd9&VGPZ~-Qx3IGfpofH;8(DMoiCG0zy9T~n~Qj_0%$T+Zk&N% zg@uYXnvDULjwl9oQ6*t;8HsvA3<4d_#TD9kE~2#f@I_Wt+}Y@(*s|{V6WnTY3_LN< ztsQr6l!Ey)Ocyd}14#T8ME0T;>vZ<|IpfK^6Af_><*osh^iCN2gfz|r+6jGQh88Wm z9ivjUs#7PDtJ5@`*}7O>gW7q5kESND$VQemvFs!697DPpT;v(+dn-BRgC>@2sU@0= zdF`hrkJ8W+L1t+I`6CruIfaJtLOjP9_D4%Oj8soI{i|xm`HGYT5Ps`|Q8CgW?`9K8 z9#{pkwLI&KkBN)+683yS6nV{JIXM@^c7N`{l*Z$J3>u5vIBQ-EmM84~^2vJfaShaq zU*3ID{n@JRx4+wI^JPmxEKh!x&`AcD;9Sct^P|)laOdU%@5LFJ9v((F8;*A=p?cA~ zgu!K8sOHKfODeqgxrevR`eVE6ju{BL2VD8O8eVuiIYA<*btDB``4H}@y<4|62-ha>RlPDx ztN88$uN4s>sAiDT7&=tI4sOe1K@+UOWZkKuZsPdAQeG$XYm6$;$mq_ApS!cjcmvS_ zE@+J&EV6iL&Wn3fnB=)XS6S=Mly1rQniH+7-m$M68I7}({!eu82COG&jC@njp6arK zZgG7P7DUXIY9Lg;a(wNhBQr_hWhagbk$<5_O|Zb>oYd>Hr+d3Th=xDvJg=H-{bo$2 z?{$zG+pC2NF}r{$RY6huyS%JCsBdR~epnuh&o0nFht3=tW8<2KkzU~YK02)%l5CnO z>6@wZjlKyq$nLVG?^Z5;ka$SP2U|ZY6D+j&m?M5mDb4gve*O=iT6&y}*ZKFu zOYT~!x->jY3TM6{FAeTl-#w|vrj4rfv4MqU=wG1+(_$gJ#>uLBZt)WaXT%`7J{7gl zWG|V{lFGKLGYx2}O2lNMC>6h)(!c5ME2A`JZR!4X1s66b9|C4o56#2W0^P1^?i4hp z<_FF{Kuf;QSDyB|&Jig&^^L?dy6~}nmBA?CgEykq?4CY8#Y?CB{e`>74jkFBs-*3Z z@)e~a8pTGN9bPdCa;9^8F0J?HrnAljqz)lmZ1%1^^x)v&=$M#E>FI_>*)gN`6oCbQ zNTg9IlOvyRK_+atD{Nkv&2$R8YJsFIk`bbN18Zy9y}cq)(WgxXPNxJbAf16Mo%H%N zhhIFoWE)CWWz*bUbT{WB>jt$Mn3$Ney_!z#KMyCe!zGG${;?|Ffb#g4&)M5cDeY~u z&Z9C$S7D}4@3rU_;ni*-(-XsB%Z(;;xI3N?v-Q5=MgLwjfypw5f_Jhcr*zSWDo~$^ z(2MJ?vTVkUSgE(To#efouD4KZSZ(7~KAg&*>J5eej|4cptS_Cu@%}CkF8VS?@t*TF z)9M$NPWEDa#iF(dUy=$<3)xXr5q(%ZEY=B zNJt1U_mo6B=e@uo3L0A9PjHB<$H(gHwwM?Mf#-cRI?U+rg$pP+IFSma6ciK(InYUK zhD&Kbr2^b5pJG{u>L#gU&M)}~dMCI$>Q4CEo-{j4yBnDj!w2d2kK?y~nfwbCOfZ|0 zbdfsy{DS;orF_mFr7}LmdSSNFQ^&IO940;f0)qK+kLVIqpvIW{3RehYQ)mzo7e`4< z{FAZkDafX(HH_BhVSkF>$B~EsbT!vwQ&>t0=KA`&!Fplz{rPIA?`Y)~4&b5TbYmU& zi)&{q^`!>0P0j~VE^U`xuapLDyG)MTLT_(x)}0J|d^tvaVYT)fZL)RSkkHV#z3@{$ zPh{}~yo1>e487Kk8qb{@_7*R9IO`r;op(nweebOk=6knO-NXzGai>-7aclN?Jux_} zwJWw4Er;V?flGz~xqadBDA?G;4OWWZP*9X+T{KrZUpWQduKHZO(+V_%*PqT%+$)#m zXB9^*+#K9zKebw(nH({M2Unw_L!;Tbl`gSjnrk0&^ zO{?^}eprS-N8xd>5q5Ov%2l}Y=7)er+Fx_%K1kEGH`?h9%@Od!EuD+purC$AJ;Ya( z{^R^EQf<)5x2~9&m`G@xn3SYaee8D?7?8Jce;H77H`|22>3v#>+Z}LLJG8z#Qz!}z zg@7%jr?*a_ok1>b+!uz3&+i>mrQgnEI*elAx#ML%m3RK(|Ne5H!{Y`godle`R;32; zM^;u==nT8?9UO=T;|Tg{jGF6QKuDUu)BiU8#m|o+mzK+ZKnJ9cj@OHJaw;NYKzF&j z*oY>RL_))QyyX_0N;NTIep>Q7wiKtp3RXCAr4pPVPXF6L+PgjO@bpweqk^*zmm-bcZdIh%}R(JrTJAekic@Li2LIs z@aYx#NAG!smz^YP6W*81$A9?y7lCiJtdTw-dNVOzsxc5>UmC>9&q!Fs&fyFj-Y+$m z6=vh!77%5WVO#t`$s#c2LI?H)tH;3_;|tv!$d}mc0oA=K;Zp`GmC9g=r0F=^zYI$ZK|l0uUGgG1wH!{w@_uS70SXZ2GxI%B?l5KssOqTxvC zwuL;7+r-k+(tiy-+hR z{9i<#Nnx*AKqNMFTTp*`eZB30CQ3-CL5?2i9ZjX>c0EdvWIWJ|Y@?}Ly|m?+>U|sv zNWYOy6uHIw&BF3~g?qq)mS?gpKEUjx*UWagCM&W3`eP{o0*PhBMHkoIg|Kz#27Gu* zj>K)sNJ8M1&?aq4a*WV1-}$6c5yU6TY=ea z05^>>t0z$2p_aF?#+p{Nl=>MFKWB1Ok_a=#xH&=DGYfy~)bq1X9pMspFzu6XK=FgK z-ghFv3v>Xj#r{d%L^MV9`Q&cic}t;c;2+*-gGusP8`w$VbYSs2!JjUc*HEi}=#oF; z{K~<01*>;A{$mVOv030br)#S?DPF59H6=yDX$h16@kn-o@D`kY=sz}ZMpVC_D*0qK zp@Ia`rqx0)Hr>gIsZ45n*a;_^ZTE0+c6PxL^ykaW%=CTS@VGnK$i}4CK|#fjnK3PA zdqBa&g!*@~VDogpWZ3$0QqlUbYO_*n0-f*Q*3=(mIf9|t&mr}~>wY#IeS26mr@x#E z4I8LC~m3Rj<$hVna{4dPU3U$LrYhMOb@x`}}u(CxojZq5u~Ab*`Y` z;EntZmnnX942;5swn3=H>QB`0KH+H0iA8NpuAKop1$1pOgIWzMBVm z9-dbuG#qO&F?;o*kbaTZf=9l+Hx!pMV98M;LUZj7l&&3Hc{u$haxb`t_KL#k>Hu5b ze-uttxAU2#@3Xu@|AgF`51uO%vhIK~CAbp9&)alkV}$f9R67v$>nl7ZWz1P@^N3V< z(}dN`4N_a!*B|#MQYa~{M;c@I*GJ=F0^D4%^n)Dv^q3LS`)c zE!n&>YLUVrq6cK0oR~EY{V*t#N8a`AC>^axa=Bfg>MaDvg1+8nGMh;B-J|;IhnM)) zZd)}`zD;B;VL~ung#Kx`Ss85l3Io%vRZd_7~)o96de zv`1*_I{xwpz3xB28?x$J?j&%cHv%;*{v8X@iHNJ~nMmS#th$v^*uCtW%eFq&f~4w? zBjfCYLD!;`@fN?cJ|RKj3Z-P!+?nTsA5uz6D2KboMa9K9Oh3TdJuc0GU>Fh}-p;wm zYpCfe+SbbW>)vxSP4xJwXN<91@0?vx@V!AdFdPA=7XWgR@$rmKGYD5oAlb}_2pGWK z-F;Ss$;Z+e$@n+sc4w>`b9hoG+b?3ZcgOA(!d6(>Rr`$xi!>9VSCgkHgvD z6<(7&T&yud?i~d*g2|=vdEF5L1O@M)AQVcI_o%7Iv)H3|`oiZbbvc1l!=*YQ;SEHv z{~%_kkH_xrZi3m;@^(C6nr{DhFe!O?v%av{dk)<{eD5!hCjAjce6Qm!ja7$TzxsD< zBO@b8SXq++_eaCRlGM}7(dA=M7yeF1R{&(87(#yBiiOd|%C)Qe`>zH1?GI8(F+D&2 znb$kr>`SYu4~&h$8yXt=`uet9w4Excr;d-$0qCDt8ufAg7Fpx3Rv=*AV#)YHTaM&B z|EOdtMHb_J$KMLMy}Aya@-i}T%^Ms+<`Y=}P6UD8`KY@~MNZ4R+jl1eoC0=*)6RJi z8_WkyIDPJBZQLS_4of7dQZcG(jC`Lir0h={(x4?bz%yV(3PX`x+hFVie!#dK%I~Na z^s#HA5?c4dTDnP;Z3oUt7jQQ1W@?tQ_`S$+Fgo6M5cwaweUTlHyMc~5?yTU5a{Jje zYB6hkcT|Fd&HreIN~LHq-sAy}ee>^jeU<~}XdAHNr?0PXczE~@ zd!NDYGd|VCi3dFgsnmz&G@Qs!EqIJB+>Un1_{a}0xNU(0M&Dz{aoM(DP8}6*!Mran z#=!8=KdPLEDLeN_{-qwZ+U3m0xPC>+j35jZOH29CfAR0yROREQa7cO@nbYNUwI==F zjVrB^73GrS#x?E=i@&5e7+dqcD+A}%hVyGSv}sXAN?KYGtu5Hm3sLd$$dt)r?0O3# zE&ajJ01E1{WGh;*2ExK{U5rGrlkT@VI#$1z81L-bhX0sI)~L61wM!W-8l~Kio*-Ed zSZ@stOx53V{DGdOPGDe|(*N}WlwNLmfi`gaK29pCpI=TLECIxa6dr6c6zAoepO^O^ z?XX&)feY>t(piO#ik^CpSwGubaWjA{oq=?odq>VUqp#`=Ts*1B6QMo6xA0@AC%3x3 zX>$}`;-@a$cZwCB*cpcB<2p2XWKTBlRxe>n`K?(k=@>~o#sXOC$d%_!X8qrSJR{@O z#YXoxf{m!MvhQHCv$ImNyu#i7e&7*NQRPd=fA2f(cj~@D2lq_x`xOGHqWn5*Z)hq& zS^nms?@X_@JrMcRs(*;GJeA-BSDqNT;{nIy#<_;}$JOo|%oqy>i_T zTpu=8j@Wue)$sFQ^!DJl;<@{@WH(o7N-C;UEzCL}@Em}HS9gDiB#{FgyDyW~qMx}i zNOlhH&*|jfFM-={o+p1wE#cr%L+RIHYF2EqW1$ki1<7u$qry0$=y63wMO|HA_l%9r zmm%|Ydq(hK^iJQQ*q2EB+_)g7qJnmCaPaljqs^7omn#8DSCmK19lKsa(v}IXpvV`Y zKmjtVEM|D0w7vbx%UazvG={p{d-Zpj;Ho-I7-bYTLI#{>6@UM(Cw9p6%KK?HabcL? z8hnPIOmBB{in~iFdZhfif6n4pfwl)2$n++zd3T|N?b*TOnxx#+XqpB42p)VSa&orS z)%XK7by!#`I8gEKMlV913q+SZrBsGy=CjW3P+I)9*Gc|O@R zgH;438t*{rU!@n(FmYXBVXK59f(u4SMp!5rtCJ{;4>c5&^$<%ns-h)TMbvYp+)xPA zm6er+l4Nns8p9;Cg_YG!P06*(Tc1@a(ACAs7CN*ebQrCwj#p>dWEXy~kP#$Fpv(0P zV1&QD`2uu%(tDvE+r*M@xDJWPP#;kqG$2%&k1}6QeoA^*vd}i*Z1i%MeuYoJ^V#m& zzf+p;Z@m34@WO@Qga+ZBe-H&9fBsj%aJjoFy&@uZ;sF1!0-^XUTChm5w zuN{nysI)+eiNFM-KnJ2kLfOeJ$Wl)+a5D6Ag`j)|%r{7iN@@klNf;|M3;7Z@4K&Y#8`@OJ*hK5Qdi7i#>AFsE%#7-%D=TDgTSvSIs6()KFimy?l z>^c(mGWk55=~TZSm*xYj8<4tI8>~bvEx!i_1_J7d`^7r!&z>Iz00Fx25fK%Ig@?a| z0qu_@{|8=xSOKI6CTs*(AXANUnHU@Eb*iX~m(I;p8w$o>R%+0?9F7|uj%Na3qOCG^ z)sYK-JexCK)4*%M?yJ5WdP&B-2@Y2|*W$d6XI6viLUo>|I`s4N^FEgLNy*yfcfN@& zpIzy(#sr^T;_i39-J<=WkBtE5HZ9xIi$Z4=#7{ujV+&yd*wm7D<%;cLe8Fdo^d>xr*?L60Y6%6W`qh3B$JFwNJ#-2WAr>W+z5A$?!5t&+Ub2SQtWi@k(`>U zPTe&yM-~i|)5nul(@d&F@STxA;&CecD{i{R_w&6x`_I?? z9yiwc-Pt?@9-zWq#z71SajYF2_Nc6RKH2-@A|D?wg5$ZhiM#MW^mDo2c)O{7L;PS= zFguK%y4{becqGEb((A=S8UzehjF7~x_7x?@L!&MKA3Ch4b*LGsPJMSU$HAX z3{7q*`^&2DS}8aatrR$XDfSP|Gs`)TL)M?$(E$&;xyiGgz7r4NV>nSBW6*P?3U_1!v#8TPIol2*ljTD%_m3&1PFtBw%x@8ZT_{>oVoK(34Ze39!{9d z6p16IO_f_8v@3GXIIQ!FncE*usfu4*J_NMq0H~eS_sLOUy#+$Q>`#A*%D>+ObFy98 zqnzDTCM;_9IcUuR5*$l6qs7g;70K7IRzrP^f{J+5v3I1rQS}*@njhIaePOJ=%Z`VC z-|~!0gDS7MrnWx6!((-6p$>K0t|SLFUNKF@WrtYPhY(AZx^ zrnOo_r4)RmVZH3m1ioRgYLgwjkd98) zS_vCK$QyL%0WR}bza10cN`rs`Bk}q1{(L<|1pb|d#ux}w|FxpIpRY1I?TQ(AA5+A8 z0&XS^gdM=RK&&xpUOV1s=L95oKvNE;*KGnTm^;p3vqG(-YagPgOJmvc0pejqOpKVi zI-uYI^WC;g**E*h^;A00WxhV`wjft`a|AV@8QzR=z8(o4q%g z_E$!G`RRYV-7*x1JnneeW-~yB1&#RY%(AMCw7(!}1aRaA8%|kVxZq*8>@er~gT8)n zKV#%+-C=5qg(b9CN8I^pisrnXt8A`SS$y26hiJ#$-0ZJ#U3RP$Nv9+bEqe}*|Y<|Fpw1~(T-DZ1nW%U0t1`?8c zs~#J!_rsYqFvzlAPcw5{@`CV-= z<)lpM9^c5qjBOU=vwv0a7>HBvrZ)<@oTmg#GxrjGM#RbGup|g}ug0ot)ci2rE%SfE zMRYw4KobzCI-H}O#zT|vh45pxq(FwZylgUTbsrVu341|1Qb_N_92-H>8$0T$g?xG4 zK0upDzRed>cnyxl>prw>f^ez*s{KGZJOypoP3#++hwQe$WJlqJ5t**}z3B3U=DRgqhULK)q6wdZ=4VCn(@`HU;t!60T zcs)bNjuF0_<5d-!p_M>SNkfr=FWY$GE)A4#Xq&kyN2A}BI9bsUmKT@aCHE$Gvs~og zwwU*8RYhA#iY26-S?Aa6yR?^x7+8VR#wGc5Aez#2e22JzZZ?v3ME&$?4s@!3fH=4$JT2Xs}t9GeP4= zPmW6lWA}1+dSPAU^!aa}X|pO&tXq3cIgNq~QZ^>vcnnBDbSCRa@J+^pD=mnPgYG?z zf%Bn?kND#6yEeJ>SZXuEekldf)oX3?FM^o8%J{u&7AdKuykRW|{|_%g4Rs3o4@Hk) z!`cDH|Dz(c@HAmO|1q<$DqA#$yQ%+UN$%Ei_}ke_eSC7_bh;T=s3E-zDtbV;*CYSd zFUUsy{ZFuyZ`VB|ez}a3JE@JP9mUXLhY*Eu21~Cq3e0GGN|OW7epT5(vvhjyJqHO# z_?nRu&^h_n>AHi>4Hc|5_yz5xqzBfuea|WE^8qG4<`bNW*-{BX27@&|riWka?PO0b z|AVDiz`0Sl&V%lD(bA(#p|kx7kJ(!- zXtq_)uF5CGqJGQdA|;^6W+6NvhN!>l3v|-2l1u$$t=l^h2|I&`u7%WwTPFgx684kC z&aqj-`Fo!KSE3P*ylBMnqg3{4Q}Xyl zTisEoEY+z{YBMXizmfyF1klK~ZAUGqqQ|St_U`%>p;A%ZHSN*z)Sw*W>7(n4-pbvY z6{Uokd{DzQnorlxnn_m-ffu5;^ltXjg?Zy;F_5DTJ$S~=uWriytQ|MsTD3Rht}}6W~`n-lE)YDg>hhXK!76S$z9x=Z>x_e zxjxV(izsv|Iqltc<)R*DB&KGLRMZIQjb96JZBM3YOUmly5-ZjQCFC0t&;L9bA`lw5 zU%b~;$3QP}MGR57(Ozk+@)7rk!*u~g%H&c>f01^M45X8#xYS=t`LLteB{rvJ7qKbq z5K4JBk)3SDriG@x65?y#SMv1u{ zbk#0}dSitLLO_2>$j_f@vRkw66riS#Y-!>8uSl+@hEBlaN=!{How5mq4xjuPuWjf@ORj9C#v6WRh zQ;)Hc-W$4q-p-2a3A7k;|DY2RGRPc>)7-Il0$V0jkS7~+qQQ^7(Ie}7EM0T&vh(v9 zWgH>k`&-AkP`{9%5LEmY?*zKrODo)urg#2c(02;(^XsP!!Y})v!ax?qv9)le81`%U zzZG(fGDe`C;xklb(xXIp6Q6+3*XvRP9+r}V4(yeQ00epgfi8vE_vu2>jmy2gy@6^{ zImumvJS3pP^{Q5fzhlQrNW|d- zf(-9pXv`D9NQKmi!rEI1Ypl^uk zF9h(uC58*MBIAbfKf9sWzB!@v0zU(UJQ`-#BP9}qFTjxgLhleJU>}w6-d+yWFIh!T zR&0d+fdN>f|M^9UPWqtsWuO-x7^)O7O#0u&0KOyqzo+^Cd=ne-32j7K8lTZx^9bxY P1Cth45UUdT5%j+RN$I7+ literal 0 HcmV?d00001 diff --git a/docs/nav/nav-menu.yml b/docs/nav/nav-menu.yml index ad927fea..c04499d0 100644 --- a/docs/nav/nav-menu.yml +++ b/docs/nav/nav-menu.yml @@ -195,10 +195,10 @@ - name: RECIPES url: /documentation/recipes/README.md content: - - name: Debugging with Chrome Developer Tools - url: /documentation/recipes/debugging-with-chrome-dev-tools.md - - name: Debugging with Visual Studio Code - url: /documentation/recipes/debugging-with-visual-studio-code.md + - name: Debug in Chrome Developer Tools + url: /documentation/recipes/debug-in-chrome-dev-tools.md + - name: Debug in Visual Studio Code + url: /documentation/recipes/debug-in-visual-studio-code.md - name: Integrating TestCafe with CI Systems url: /documentation/recipes/integrating-testcafe-with-ci-systems/README.md content: From d7ff3b225d00a482f4837b7bf5cb217238c28e0f Mon Sep 17 00:00:00 2001 From: MargaritaLoseva Date: Thu, 6 Sep 2018 12:17:14 +0300 Subject: [PATCH 088/184] [docs] describe stopOnFirstFail option (#2810) --- .../using-testcafe/command-line-interface.md | 9 +++++++++ .../using-testcafe/programming-interface/runner.md | 8 +++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 31662b62..cee0f33f 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -50,6 +50,7 @@ testcafe [options] * [--proxy-bypass \](#--proxy-bypass-rules) * [--dev](#--dev) * [--qr-code](#--qr-code) + * [--sf, --stop-on-first-fail](#--sf---stop-on-first-fail) * [--color](#--color) * [--no-color](#--no-color) @@ -604,6 +605,14 @@ Outputs a QR-code that represents URLs used to connect the [remote browsers](#re testcafe remote my-tests --qr-code ``` +### --sf, --stop-on-first-fail + +Stops an entire test run if any test fails. This allows you not to wait for all the tests included in the test task to finish and allows focusing on the first error. + +```sh +testcafe chrome my-tests --sf +``` + ### --color Enables colors in the command line. diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index ac254ae9..388686b3 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -411,12 +411,13 @@ Parameter | Type | Description `skipJsErrors` | Boolean | Defines whether to continue running a test after a JavaScript error occurs on a page (`true`), or consider such a test failed (`false`). | `false` `skipUncaughtErrors` | Boolean | Defines whether to continue running a test after an uncaught error or unhandled promise rejection occurs on the server (`true`), or consider such a test failed (`false`). | `false` `quarantineMode` | Boolean | Defines whether to enable the [quarantine mode](#quarantine-mode). | `false` +`debugMode` | Boolean | Specifies if tests run in the debug mode. If this option is enabled, test execution is paused before the first action or assertion allowing you to invoke the developer tools and debug. In the debug mode, you can execute the test step-by-step to reproduce its incorrect behavior. You can also use the **Unlock page** switch in the footer to unlock the tested page and interact with its elements. | `false` +`debugOnFail` | Boolean | Specifies whether to enter the debug mode when a test fails. If enabled, the test is paused at the moment it fails, so that you can explore the tested page to determine what caused the failure. | `false` `selectorTimeout` | Number | Specifies the time (in milliseconds) within which [selectors](../../test-api/selecting-page-elements/selectors/README.md) make attempts to obtain a node to be returned. See [Selector Timeout](../../test-api/selecting-page-elements/selectors/using-selectors.md#selector-timeout). | `10000` `assertionTimeout` | Number | Specifies the time (in milliseconds) within which TestCafe makes attempts to successfully execute an [assertion](../../test-api/assertions/README.md) if [a selector property](../../test-api/selecting-page-elements/selectors/using-selectors.md#define-assertion-actual-value) or a [client function](../../test-api/obtaining-data-from-the-client/README.md) was passed as an actual value. See [Smart Assertion Query Mechanism](../../test-api/assertions/README.md#smart-assertion-query-mechanism). | `3000` `pageLoadTimeout` | Number | Specifies the time (in milliseconds) passed after the `DOMContentLoaded` event, within which TestCafe waits for the `window.load` event to fire. After the timeout passes or the `window.load` event is raised (whichever happens first), TestCafe starts the test. You can set this timeout to `0` to skip waiting for `window.load`. | `3000` `speed` | Number | Specifies the test execution speed. Should be a number between `1` (the fastest) and `0.01` (the slowest). If speed is also specified for an [individual action](../../test-api/actions/action-options.md#basic-action-options), the action speed setting overrides test speed. | `1` -`debugMode` | Boolean | Specifies if tests run in the debug mode. If this option is enabled, test execution is paused before the first action or assertion allowing you to invoke the developer tools and debug. In the debug mode, you can execute the test step-by-step to reproduce its incorrect behavior. You can also use the **Unlock page** switch in the footer to unlock the tested page and interact with its elements. | `false` -`debugOnFail` | Boolean | Specifies whether to enter the debug mode when a test fails. If enabled, the test is paused at the moment it fails, so that you can explore the tested page to determine what caused the failure. | `false` +`stopOnFirstFail` | Boolean | Defines whether to stop an entire test run if any test fails. This allows you not to wait for all the tests included in the test task to finish and allows focusing on the first error. | `false` After all tests are finished, call the [testcafe.close](testcafe.md#close) function to stop the TestCafe server. @@ -437,7 +438,8 @@ createTestCafe('localhost', 1337, 1338) selectorTimeout: 50000, assertionTimeout: 7000, pageLoadTimeout: 8000, - speed: 0.1 + speed: 0.1, + stopOnFirstFail: true }); }) .then(failed => { From d3efce8320f637ebcc56cf0edf069967c41c54fb Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Fri, 7 Sep 2018 16:15:25 +0300 Subject: [PATCH 089/184] Don't track unawaited promises if uncaught error is occured (close #2557) (#2827) --- src/api/test-controller/index.js | 1 + src/api/wrap-test-function.js | 9 +-- .../provider/built-in/locally-installed.js | 12 ++-- src/browser/provider/built-in/path.js | 15 +++-- src/browser/provider/built-in/remote.js | 4 +- .../provider/utils/argument-parsing.js | 17 +++-- src/errors/error-list.js | 5 ++ .../api/es-next/test-controller/test.js | 62 +++++++++---------- .../testcafe-fixtures/test-controller-test.js | 16 +++-- 9 files changed, 74 insertions(+), 67 deletions(-) diff --git a/src/api/test-controller/index.js b/src/api/test-controller/index.js index 24023553..52419dd5 100644 --- a/src/api/test-controller/index.js +++ b/src/api/test-controller/index.js @@ -68,6 +68,7 @@ export default class TestController { extendedPromise.then = function () { markCallsiteAwaited(); + return originalThen.apply(this, arguments); }; diff --git a/src/api/wrap-test-function.js b/src/api/wrap-test-function.js index 5c1b0623..82c93f60 100644 --- a/src/api/wrap-test-function.js +++ b/src/api/wrap-test-function.js @@ -3,7 +3,6 @@ import testRunTracker from './test-run-tracker'; import TestCafeErrorList from '../errors/error-list'; import { MissingAwaitError } from '../errors/test-run'; - export default function wrapTestFunction (fn) { return async testRun => { let result = null; @@ -21,9 +20,11 @@ export default function wrapTestFunction (fn) { errList.addError(err); } - testRun.controller.callsitesWithoutAwait.forEach(callsite => { - errList.addError(new MissingAwaitError(callsite)); - }); + if (!errList.hasUncaughtErrorsInTestCode) { + testRun.controller.callsitesWithoutAwait.forEach(callsite => { + errList.addError(new MissingAwaitError(callsite)); + }); + } if (errList.hasErrors) throw errList; diff --git a/src/browser/provider/built-in/locally-installed.js b/src/browser/provider/built-in/locally-installed.js index 229a8c64..4445096b 100644 --- a/src/browser/provider/built-in/locally-installed.js +++ b/src/browser/provider/built-in/locally-installed.js @@ -5,11 +5,11 @@ export default { isMultiBrowser: true, async openBrowser (browserId, pageUrl, browserName) { - var args = browserName.split(' '); - var alias = args.shift(); + const args = browserName.split(' '); + const alias = args.shift(); - var browserInfo = await browserTools.getBrowserInfo(alias); - var openParameters = Object.assign({}, browserInfo); + const browserInfo = await browserTools.getBrowserInfo(alias); + const openParameters = Object.assign({}, browserInfo); if (args.length) openParameters.cmd = args.join(' ') + (openParameters.cmd ? ' ' + openParameters.cmd : ''); @@ -22,13 +22,13 @@ export default { }, async getBrowserList () { - var installations = await browserTools.getInstallations(); + const installations = await browserTools.getInstallations(); return Object.keys(installations); }, async isValidBrowserName (browserName) { - var browserNames = await this.getBrowserList(); + const browserNames = await this.getBrowserList(); browserName = browserName.toLowerCase().split(' ')[0]; diff --git a/src/browser/provider/built-in/path.js b/src/browser/provider/built-in/path.js index c74ff402..694f0449 100644 --- a/src/browser/provider/built-in/path.js +++ b/src/browser/provider/built-in/path.js @@ -1,20 +1,19 @@ import browserTools from 'testcafe-browser-tools'; import { splitQuotedText } from '../../../utils/string'; - export default { isMultiBrowser: true, async _handleString (str) { - var args = splitQuotedText(str, ' ', '`"\''); - var path = args.shift(); + const args = splitQuotedText(str, ' ', '`"\''); + const path = args.shift(); - var browserInfo = await browserTools.getBrowserInfo(path); + const browserInfo = await browserTools.getBrowserInfo(path); if (!browserInfo) return null; - var params = Object.assign({}, browserInfo); + const params = Object.assign({}, browserInfo); if (args.length) params.cmd = args.join(' ') + (params.cmd ? ' ' + params.cmd : ''); @@ -23,7 +22,7 @@ export default { }, async _handleJSON (str) { - var params = null; + let params = null; try { params = JSON.parse(str); @@ -35,7 +34,7 @@ export default { if (!params.path) return null; - var openParameters = await browserTools.getBrowserInfo(params.path); + const openParameters = await browserTools.getBrowserInfo(params.path); if (!openParameters) return null; @@ -47,7 +46,7 @@ export default { }, async openBrowser (browserId, pageUrl, browserName) { - var openParameters = await this._handleString(browserName) || await this._handleJSON(browserName); + const openParameters = await this._handleString(browserName) || await this._handleJSON(browserName); if (!openParameters) throw new Error('The specified browser name is not valid!'); diff --git a/src/browser/provider/built-in/remote.js b/src/browser/provider/built-in/remote.js index 66048ee9..16bc2e35 100644 --- a/src/browser/provider/built-in/remote.js +++ b/src/browser/provider/built-in/remote.js @@ -8,7 +8,7 @@ export default { async openBrowser (browserId) { await this.waitForConnectionReady(browserId); - var localBrowserWindow = await findWindow(browserId); + const localBrowserWindow = await findWindow(browserId); this.localBrowsersFlags[browserId] = localBrowserWindow !== null; }, @@ -23,7 +23,7 @@ export default { // NOTE: we must try to do a local screenshot or resize, if browser is accessible, and emit warning otherwise async hasCustomActionForBrowser (browserId) { - var isLocalBrowser = this.localBrowsersFlags[browserId]; + const isLocalBrowser = this.localBrowsersFlags[browserId]; return { hasCloseBrowser: true, diff --git a/src/browser/provider/utils/argument-parsing.js b/src/browser/provider/utils/argument-parsing.js index ac3cda80..389087de 100644 --- a/src/browser/provider/utils/argument-parsing.js +++ b/src/browser/provider/utils/argument-parsing.js @@ -1,29 +1,28 @@ import { find as findElement } from 'lodash'; import OS from 'os-family'; - -const CONFIG_TERMINATOR_RE = /(\s+|^)-/; +const CONFIG_TERMINATOR_RE = /(\s+|^)-/; export function hasMatch (array, re) { return !!findElement(array, el => el.match(re)); } export function findMatch (array, re) { - var element = findElement(array, el => el.match(re)); + const element = findElement(array, el => el.match(re)); return element ? element.match(re)[1] : ''; } export function isMatchTrue (array, re) { - var match = findMatch(array, re); + const match = findMatch(array, re); return match && match !== '0' && match !== 'false'; } export function splitEscaped (str, splitterChar) { - var result = ['']; + const result = ['']; - for (var i = 0; i < str.length; i++) { + for (let i = 0; i < str.length; i++) { if (str[i] === splitterChar) { result.push(''); continue; @@ -45,7 +44,7 @@ export function getPathFromParsedModes (modes, availableModes = []) { if (availableModes.some(mode => mode === modes[0])) return ''; - var path = modes.shift(); + let path = modes.shift(); if (OS.win && modes.length && path.match(/^[A-Za-z]$/)) path += ':' + modes.shift(); @@ -54,7 +53,7 @@ export function getPathFromParsedModes (modes, availableModes = []) { } export function getModes (modes, availableModes = []) { - var result = {}; + const result = {}; availableModes = availableModes.slice(); @@ -76,7 +75,7 @@ export function getModes (modes, availableModes = []) { } export function parseConfig (str) { - var configTerminatorMatch = str.match(CONFIG_TERMINATOR_RE); + const configTerminatorMatch = str.match(CONFIG_TERMINATOR_RE); if (!configTerminatorMatch) return { modesString: str, userArgs: '' }; diff --git a/src/errors/error-list.js b/src/errors/error-list.js index 40c7ce3d..c27f522b 100644 --- a/src/errors/error-list.js +++ b/src/errors/error-list.js @@ -1,4 +1,5 @@ import processTestFnError from './process-test-fn-error'; +import { UncaughtErrorInTestCode } from './test-run'; export default class TestCafeErrorList { constructor () { @@ -9,6 +10,10 @@ export default class TestCafeErrorList { return !!this.items.length; } + get hasUncaughtErrorsInTestCode () { + return this.items.some(item => item instanceof UncaughtErrorInTestCode); + } + addError (err) { if (err instanceof TestCafeErrorList) this.items = this.items.concat(err.items); diff --git a/test/functional/fixtures/api/es-next/test-controller/test.js b/test/functional/fixtures/api/es-next/test-controller/test.js index 81f84239..8224b842 100644 --- a/test/functional/fixtures/api/es-next/test-controller/test.js +++ b/test/functional/fixtures/api/es-next/test-controller/test.js @@ -1,21 +1,21 @@ -var expect = require('chai').expect; +const { expect } = require('chai'); // NOTE: we run tests in chrome only, because we mainly test server API functionality. // Actions functionality is tested in lower-level raw API. -describe('[API] TestController', function () { - it('Should support chaining', function () { +describe('[API] TestController', () => { + it('Should support chaining', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'Chaining', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).to.contains('-btn1-btn2-btn3-page2-btn1-page2-btn2'); }); }); - it('Should produce correct callsites for chained calls', function () { + it('Should produce correct callsites for chained calls', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'Chaining callsites', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).to.contains( ' 16 |' + ' 17 |test(\'Chaining callsites\', async t => {' + @@ -29,87 +29,85 @@ describe('[API] TestController', function () { }); }); - describe('Proxy object', function () { - it('Should provide importable proxy object', function () { + describe('Proxy object', () => { + it('Should provide importable proxy object', () => { return runTests('./testcafe-fixtures/proxy-test.js', 'Proxy object'); }); }); - describe('Missing `await` tracking', function () { - var missingAwaitErrMsg = 'A call to an async function is not awaited. Use the "await" keyword before actions, ' + + describe('Missing `await` tracking', () => { + const missingAwaitErrMsg = 'A call to an async function is not awaited. Use the "await" keyword before actions, ' + 'assertions or chains of them to ensure that they run in the right sequence.'; - it('Should track missing `await`', function () { + it('Should track missing `await`', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'Missing await', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).to.contains(missingAwaitErrMsg); expect(errs[0]).to.contains('> 28 | t.click(\'#page2-btn1\');'); }); }); - it('Should track missing `await` in chain', function () { + it('Should track missing `await` in chain', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'Missing await in chain', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).to.contains(missingAwaitErrMsg); expect(errs[0]).to.contains("> 38 | .click('#page2-btn2');"); }); }); - it('Should track missing `await` in the end of test', function () { + it('Should track missing `await` in the end of test', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'Missing await in the end of the test', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).to.contains(missingAwaitErrMsg); expect(errs[0]).to.contains("> 44 | t.click('#btn3');"); }); }); - it('Should track missing `await` for actions with error', function () { + it('Should track missing `await` for actions with error', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'Error caused by action with missing await', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).to.contains(missingAwaitErrMsg); expect(errs[0]).to.contains("> 48 | t.click('#error');"); - expect(errs[1]).to.contains('Uncaught Error: Error callsite test'); + expect(errs[1]).to.contains('Error callsite test'); expect(errs[1]).to.contains("> 48 | t.click('#error');"); }); }); - it('Should track missing `await` with disrupted chain', function () { + it('Should track missing `await` with disrupted chain', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'Missing await with disrupted chain', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).to.contains(missingAwaitErrMsg); expect(errs[0]).to.contains("> 58 | t.click('#btn2');"); }); }); - it('Should track missing `await` in helper', function () { + it('Should track missing `await` in helper', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'Missing await in helper', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).to.contains(missingAwaitErrMsg); expect(errs[0]).to.contains("> 2 | t.click('#yo');"); }); }); - it('Should track missing `await` before error', function () { - return runTests('./testcafe-fixtures/test-controller-test.js', 'Missing await before error', + it('Should not track missing `await` when uncaught error is occurred (GH-2557)', () => { + return runTests('./testcafe-fixtures/test-controller-test.js', 'GH-2557', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { - expect(errs[0]).to.contains(missingAwaitErrMsg); - expect(errs[0]).to.contains("> 68 | t.click('#btn2'); "); - expect(errs[1]).to.contains('Error: Hey!'); - expect(errs[1]).to.contains("> 70 | throw new Error('Hey!');"); + .catch(errs => { + expect(errs.length).eql(1); + expect(errs[0]).contains("TypeError: Cannot read property 'someProperty' of undefined [[user-agent]]"); }); }); - describe('Regression', function () { - it('Should allow chains within chain (GH-1285)', function () { + describe('Regression', () => { + it('Should allow chains within chain (GH-1285)', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'GH-1285', { only: 'chrome' }); }); }); diff --git a/test/functional/fixtures/api/es-next/test-controller/testcafe-fixtures/test-controller-test.js b/test/functional/fixtures/api/es-next/test-controller/testcafe-fixtures/test-controller-test.js index 46f64a9c..2bd4e9a0 100644 --- a/test/functional/fixtures/api/es-next/test-controller/testcafe-fixtures/test-controller-test.js +++ b/test/functional/fixtures/api/es-next/test-controller/testcafe-fixtures/test-controller-test.js @@ -64,14 +64,18 @@ test('Missing await in helper', async t => { await missingAwaitFn(t); }); -test('Missing await before error', async t => { - t.click('#btn2'); - - throw new Error('Hey!'); -}); - test('GH-1285', async t => { await t .click('#btn2') .expect(await t.click('#btn3')).notEql('Hey ya!'); }); + +test('GH-2557', async t => { + let undefinedVariable; + + await t + .click('body') + .click(undefinedVariable.someProperty) + .click('body'); +}); + From 79bf79bc1599ad343a52f3471660e553160ca3dd Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Fri, 7 Sep 2018 18:00:02 +0300 Subject: [PATCH 090/184] Implemented 'Print stack of client-side JS errors' (close #2043) (#2791) * Implemented 'Print stack of client-side JS errors' (close #2043) * update hammerhead * revert testcafe-legacy-api module --- package.json | 2 +- src/client/driver/driver.js | 54 +++--- src/errors/test-run/index.js | 4 +- src/errors/test-run/templates.js | 5 +- src/index.js | 5 +- src/reporter/plugin-host.js | 16 +- src/test-run/index.js | 8 - src/testcafe.js | 10 +- src/utils/string.js | 7 + .../fixtures/api/es-next/hooks/test.js | 78 ++++----- .../api/es-next/test-controller/test.js | 2 +- .../functional/fixtures/api/raw/click/test.js | 56 +++---- .../functional/fixtures/api/raw/hooks/test.js | 38 ++--- .../fixtures/page-js-errors/test.js | 40 ++--- test/functional/setup.js | 48 +++--- test/server/create-testcafe-test.js | 2 +- .../uncaught-js-error-on-page | 5 +- .../legacy-test-run-error-formatting-test.js | 43 ++--- test/server/test-run-error-formatting-test.js | 158 +++++++++--------- test/server/util-test.js | 28 ++-- 20 files changed, 298 insertions(+), 311 deletions(-) diff --git a/package.json b/package.json index 209cefb7..adf9dc87 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.5", - "testcafe-hammerhead": "14.2.6", + "testcafe-hammerhead": "14.2.7", "testcafe-legacy-api": "3.1.8", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", diff --git a/src/client/driver/driver.js b/src/client/driver/driver.js index 91beed9c..bbe0b79c 100644 --- a/src/client/driver/driver.js +++ b/src/client/driver/driver.js @@ -147,7 +147,7 @@ export default class Driver { if (this.skipJsErrors || this.contextStorage.getItem(TEST_DONE_SENT_FLAG)) return Promise.resolve(); - var error = new UncaughtErrorOnPage(err.msg || err.message, err.pageUrl); + const error = new UncaughtErrorOnPage(err.stack, err.pageUrl); if (!this.contextStorage.getItem(PENDING_PAGE_ERROR)) this.contextStorage.setItem(PENDING_PAGE_ERROR, error); @@ -158,7 +158,7 @@ export default class Driver { _failIfClientCodeExecutionIsInterrupted () { // NOTE: ClientFunction should be used primarily for observation. We raise // an error if the page was reloaded during ClientFunction execution. - var executingClientFnDescriptor = this.contextStorage.getItem(EXECUTING_CLIENT_FUNCTION_DESCRIPTOR); + const executingClientFnDescriptor = this.contextStorage.getItem(EXECUTING_CLIENT_FUNCTION_DESCRIPTOR); if (executingClientFnDescriptor) { this._onReady(new DriverStatus({ @@ -183,7 +183,7 @@ export default class Driver { // Status _addPendingErrorToStatus (status) { - var pendingPageError = this.contextStorage.getItem(PENDING_PAGE_ERROR); + const pendingPageError = this.contextStorage.getItem(PENDING_PAGE_ERROR); if (pendingPageError) { this.contextStorage.setItem(PENDING_PAGE_ERROR, null); @@ -192,7 +192,7 @@ export default class Driver { } _addUnexpectedDialogErrorToStatus (status) { - var dialogError = this.nativeDialogsTracker.getUnexpectedDialogError(); + const dialogError = this.nativeDialogsTracker.getUnexpectedDialogError(); status.pageError = status.pageError || dialogError; } @@ -213,7 +213,7 @@ export default class Driver { this.contextStorage.setItem(PENDING_STATUS, status); - var readyCommandResponse = null; + let readyCommandResponse = null; // NOTE: postpone status sending if the page is unloading return pageUnloadBarrier @@ -241,14 +241,14 @@ export default class Driver { // Iframes interaction _initChildDriverListening () { messageSandbox.on(messageSandbox.SERVICE_MSG_RECEIVED_EVENT, e => { - var msg = e.message; - var iframeWindow = e.source; + const msg = e.message; + const iframeWindow = e.source; if (msg.type === MESSAGE_TYPE.establishConnection) { - var childDriverLink = this._getChildDriverLinkByWindow(iframeWindow); + let childDriverLink = this._getChildDriverLinkByWindow(iframeWindow); if (!childDriverLink) { - var driverId = `${this.testRunId}-${generateId()}`; + const driverId = `${this.testRunId}-${generateId()}`; childDriverLink = new ChildDriverLink(iframeWindow, driverId); this.childDriverLinks.push(childDriverLink); @@ -264,8 +264,8 @@ export default class Driver { } _runInActiveIframe (command) { - var runningChain = Promise.resolve(); - var activeIframeSelector = this.contextStorage.getItem(ACTIVE_IFRAME_SELECTOR); + let runningChain = Promise.resolve(); + const activeIframeSelector = this.contextStorage.getItem(ACTIVE_IFRAME_SELECTOR); // NOTE: if the page was reloaded we restore the active child driver link via the iframe selector if (!this.activeChildDriverLink && activeIframeSelector) @@ -299,8 +299,8 @@ export default class Driver { } _switchToIframe (selector, iframeErrorCtors) { - var hasSpecificTimeout = typeof selector.timeout === 'number'; - var commandSelectorTimeout = hasSpecificTimeout ? selector.timeout : this.selectorTimeout; + const hasSpecificTimeout = typeof selector.timeout === 'number'; + const commandSelectorTimeout = hasSpecificTimeout ? selector.timeout : this.selectorTimeout; return getExecuteSelectorResult(selector, commandSelectorTimeout, null, fn => new iframeErrorCtors.NotFoundError(fn), () => iframeErrorCtors.IsInvisibleError(), this.statusBar) @@ -326,16 +326,16 @@ export default class Driver { } _setNativeDialogHandlerInIframes (dialogHandler) { - var msg = new SetNativeDialogHandlerMessage(dialogHandler); + const msg = new SetNativeDialogHandlerMessage(dialogHandler); - for (var i = 0; i < this.childDriverLinks.length; i++) + for (let i = 0; i < this.childDriverLinks.length; i++) messageSandbox.sendServiceMsg(msg, this.childDriverLinks[i].driverWindow); } // Commands handling _onActionCommand (command) { - var { startPromise, completionPromise } = executeActionCommand(command, this.selectorTimeout, this.statusBar, this.speed); + const { startPromise, completionPromise } = executeActionCommand(command, this.selectorTimeout, this.statusBar, this.speed); startPromise.then(() => this.contextStorage.setItem(this.COMMAND_EXECUTING_FLAG, true)); @@ -379,7 +379,7 @@ export default class Driver { _onExecuteClientFunctionCommand (command) { this.contextStorage.setItem(EXECUTING_CLIENT_FUNCTION_DESCRIPTOR, { instantiationCallsiteName: command.instantiationCallsiteName }); - var executor = new ClientFunctionExecutor(command); + const executor = new ClientFunctionExecutor(command); executor.getResultDriverStatus() .then(driverStatus => { @@ -481,7 +481,7 @@ export default class Driver { } _onCustomCommand (command) { - var handler = this.customCommandHandlers[command.type].handler; + const handler = this.customCommandHandlers[command.type].handler; handler(command).then(result => { this._onReady(new DriverStatus({ isCommandResult: true, result })); @@ -586,8 +586,8 @@ export default class Driver { .then(() => { // NOTE: we should not execute a command if we already have a pending page error and this command is // rejectable by page errors. In this case, we immediately send status with this error to the server. - var isCommandRejectableByError = isCommandRejectableByPageError(command); - var pendingPageError = this.contextStorage.getItem(PENDING_PAGE_ERROR); + const isCommandRejectableByError = isCommandRejectableByPageError(command); + const pendingPageError = this.contextStorage.getItem(PENDING_PAGE_ERROR); if (pendingPageError && isCommandRejectableByError) { this._onReady(new DriverStatus({ isCommandResult: true })); @@ -596,7 +596,7 @@ export default class Driver { // NOTE: we should execute a command in an iframe if the current execution context belongs to // this iframe and the command is not one of those that can be executed only in the top window. - var isThereActiveIframe = this.activeChildDriverLink || + const isThereActiveIframe = this.activeChildDriverLink || this.contextStorage.getItem(ACTIVE_IFRAME_SELECTOR); if (!this._isExecutableInTopWindowOnly(command) && isThereActiveIframe) { @@ -633,18 +633,18 @@ export default class Driver { this.readyPromise.then(() => { this.statusBar.hidePageLoadingStatus(); - var assertionRetriesTimeout = this.contextStorage.getItem(ASSERTION_RETRIES_TIMEOUT); + const assertionRetriesTimeout = this.contextStorage.getItem(ASSERTION_RETRIES_TIMEOUT); if (assertionRetriesTimeout) { - var startTime = this.contextStorage.getItem(ASSERTION_RETRIES_START_TIME); - var timeLeft = assertionRetriesTimeout - (new Date() - startTime); + const startTime = this.contextStorage.getItem(ASSERTION_RETRIES_START_TIME); + const timeLeft = assertionRetriesTimeout - (new Date() - startTime); if (timeLeft > 0) this.statusBar.showWaitingAssertionRetriesStatus(assertionRetriesTimeout, startTime); } }); - var pendingStatus = this.contextStorage.getItem(PENDING_STATUS); + const pendingStatus = this.contextStorage.getItem(PENDING_STATUS); if (pendingStatus) pendingStatus.resent = true; @@ -663,10 +663,10 @@ export default class Driver { if (this._failIfClientCodeExecutionIsInterrupted()) return; - var inCommandExecution = this.contextStorage.getItem(this.COMMAND_EXECUTING_FLAG) || + const inCommandExecution = this.contextStorage.getItem(this.COMMAND_EXECUTING_FLAG) || this.contextStorage.getItem(this.EXECUTING_IN_IFRAME_FLAG); - var status = pendingStatus || new DriverStatus({ isCommandResult: inCommandExecution }); + const status = pendingStatus || new DriverStatus({ isCommandResult: inCommandExecution }); this.contextStorage.setItem(this.COMMAND_EXECUTING_FLAG, false); this.contextStorage.setItem(this.EXECUTING_IN_IFRAME_FLAG, false); diff --git a/src/errors/test-run/index.js b/src/errors/test-run/index.js index a25cf11f..ea1564ac 100644 --- a/src/errors/test-run/index.js +++ b/src/errors/test-run/index.js @@ -100,10 +100,10 @@ export class PageLoadError extends TestRunErrorBase { // Uncaught errors //-------------------------------------------------------------------- export class UncaughtErrorOnPage extends TestRunErrorBase { - constructor (errMsg, pageDestUrl) { + constructor (errStack, pageDestUrl) { super(TYPE.uncaughtErrorOnPage); - this.errMsg = errMsg; + this.errStack = errStack; this.pageDestUrl = pageDestUrl; } } diff --git a/src/errors/test-run/templates.js b/src/errors/test-run/templates.js index 765a16a1..e5b334a7 100644 --- a/src/errors/test-run/templates.js +++ b/src/errors/test-run/templates.js @@ -1,6 +1,7 @@ import dedent from 'dedent'; import { escape as escapeHtml } from 'lodash'; import TYPE from './type'; +import { replaceLeadingSpacesWithNbsp } from '../../utils/string'; import TEST_RUN_PHASE from '../../test-run/phase'; const SUBTITLES = { @@ -50,7 +51,7 @@ function markup (err, msgMarkup, opts = {}) { msgMarkup += `\n

`; if (!opts.withoutCallsite) { - var callsiteMarkup = err.getCallsiteMarkup(); + const callsiteMarkup = err.getCallsiteMarkup(); if (callsiteMarkup) msgMarkup += `\n\n${callsiteMarkup}`; @@ -83,7 +84,7 @@ export default { [TYPE.uncaughtErrorOnPage]: err => markup(err, ` Error on page ${err.pageDestUrl}: - ${escapeHtml(err.errMsg)} + ${replaceLeadingSpacesWithNbsp(escapeHtml(err.errStack))} `), [TYPE.uncaughtErrorInTestCode]: err => markup(err, ` diff --git a/src/index.js b/src/index.js index 2f3b7abc..1057d161 100644 --- a/src/index.js +++ b/src/index.js @@ -43,7 +43,10 @@ async function createTestCafe (hostname, port1, port2, sslOptions, developmentMo getValidPort(port2) ]); - const testcafe = new TestCafe(hostname, port1, port2, sslOptions, developmentMode); + const testcafe = new TestCafe(hostname, port1, port2, { + ssl: sslOptions, + developmentMode + }); setupExitHook(cb => testcafe.close().then(cb)); diff --git a/src/reporter/plugin-host.js b/src/reporter/plugin-host.js index 2cda4fba..bfab018b 100644 --- a/src/reporter/plugin-host.js +++ b/src/reporter/plugin-host.js @@ -11,10 +11,10 @@ import getViewportWidth from '../utils/get-viewport-width'; // Therefore we use symbols to store them. /*global Symbol*/ -var stream = Symbol(); -var wordWrapEnabled = Symbol(); -var indent = Symbol(); -var errorDecorator = Symbol(); +const stream = Symbol(); +const wordWrapEnabled = Symbol(); +const indent = Symbol(); +const errorDecorator = Symbol(); export default class ReporterPluginHost { constructor (plugin, outStream) { @@ -22,7 +22,7 @@ export default class ReporterPluginHost { this[wordWrapEnabled] = false; this[indent] = 0; - var useColors = this[stream] === process.stdout && chalk.enabled && !plugin.noColors; + const useColors = this[stream] === process.stdout && chalk.enabled && !plugin.noColors; this.chalk = new chalk.constructor({ enabled: useColors }); this.moment = moment; @@ -90,9 +90,9 @@ export default class ReporterPluginHost { } formatError (err, prefix = '') { - var prefixLengthWithoutColors = removeTTYColors(prefix).length; - var maxMsgLength = this.viewportWidth - this[indent] - prefixLengthWithoutColors; - var msg = err.formatMessage(this[errorDecorator], maxMsgLength); + const prefixLengthWithoutColors = removeTTYColors(prefix).length; + const maxMsgLength = this.viewportWidth - this[indent] - prefixLengthWithoutColors; + let msg = err.formatMessage(this[errorDecorator], maxMsgLength); if (this[wordWrapEnabled]) msg = this.wordWrap(msg, prefixLengthWithoutColors, maxMsgLength); diff --git a/src/test-run/index.js b/src/test-run/index.js index 247ee5be..dd80d74d 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -45,7 +45,6 @@ import { canSetDebuggerBreakpointBeforeCommand } from './commands/utils'; -//Const const TEST_RUN_TEMPLATE = read('../client/test-run/index.js.mustache'); const IFRAME_TEST_RUN_TEMPLATE = read('../client/test-run/iframe.js.mustache'); const TEST_DONE_CONFIRMATION_RESPONSE = 'test-done-confirmation'; @@ -176,7 +175,6 @@ export default class TestRun extends EventEmitter { this.requestHooks.forEach(hook => this._initRequestHook(hook)); } - // Hammerhead payload _getPayloadScript () { this.fileDownloadingHandled = false; @@ -209,7 +207,6 @@ export default class TestRun extends EventEmitter { }); } - // Hammerhead handlers getAuthCredentials () { return this.test.authCredentials; @@ -361,7 +358,6 @@ export default class TestRun extends EventEmitter { this.browserManipulationQueue.removeAllNonServiceManipulations(); } - // Current driver task get currentDriverTask () { return this.driverTaskQueue[0]; @@ -383,7 +379,6 @@ export default class TestRun extends EventEmitter { this._removeAllNonServiceTasks(); } - // Pending request _clearPendingRequest () { if (this.pendingRequest) { @@ -398,7 +393,6 @@ export default class TestRun extends EventEmitter { this._clearPendingRequest(); } - // Handle driver request _fulfillCurrentDriverTask (driverStatus) { if (driverStatus.executionError) @@ -653,7 +647,6 @@ export default class TestRun extends EventEmitter { this.disableDebugBreakpoints = false; } - // Get current URL async getCurrentUrl () { var builder = new ClientFunctionBuilder(() => { @@ -668,7 +661,6 @@ export default class TestRun extends EventEmitter { } } - // Service message handlers var ServiceMessages = TestRun.prototype; diff --git a/src/testcafe.js b/src/testcafe.js index 514b234b..a39b0f9a 100644 --- a/src/testcafe.js +++ b/src/testcafe.js @@ -15,17 +15,17 @@ const UI_SPRITE = read('./client/ui/sprite.png', true); const FAVICON = read('./client/ui/favicon.ico', true); export default class TestCafe { - constructor (hostname, port1, port2, sslOptions, developmentMode) { + constructor (hostname, port1, port2, options = {}) { this._setupSourceMapsSupport(); registerErrorHandlers(); this.closed = false; - this.proxy = new Proxy(hostname, port1, port2, sslOptions, developmentMode); + this.proxy = new Proxy(hostname, port1, port2, options); this.browserConnectionGateway = new BrowserConnectionGateway(this.proxy); this.runners = []; - this._registerAssets(developmentMode); + this._registerAssets(options.developmentMode); } _registerAssets (developmentMode) { @@ -63,13 +63,13 @@ export default class TestCafe { // API async createBrowserConnection () { - var browserInfo = await browserProviderPool.getBrowserInfo('remote'); + const browserInfo = await browserProviderPool.getBrowserInfo('remote'); return new BrowserConnection(this.browserConnectionGateway, browserInfo, true); } createRunner () { - var newRunner = new Runner(this.proxy, this.browserConnectionGateway); + const newRunner = new Runner(this.proxy, this.browserConnectionGateway); this.runners.push(newRunner); diff --git a/src/utils/string.js b/src/utils/string.js index 7c3af7c9..72be1f36 100644 --- a/src/utils/string.js +++ b/src/utils/string.js @@ -1,4 +1,5 @@ import indentString from 'indent-string'; +import { repeat } from 'lodash'; function rtrim (str) { return str.replace(/\s+$/, ''); @@ -73,3 +74,9 @@ export function splitQuotedText (str, splitChar, quotes = '"\'') { return parts; } + +export function replaceLeadingSpacesWithNbsp (str) { + return str.replace(/^ +/mg, match => { + return repeat(' ', match.length); + }); +} diff --git a/test/functional/fixtures/api/es-next/hooks/test.js b/test/functional/fixtures/api/es-next/hooks/test.js index 0825c814..97bfd61b 100644 --- a/test/functional/fixtures/api/es-next/hooks/test.js +++ b/test/functional/fixtures/api/es-next/hooks/test.js @@ -1,88 +1,84 @@ -var expect = require('chai').expect; -var uniq = require('lodash').uniq; -var config = require('../../../../config'); - +const { expect } = require('chai'); +const { uniq } = require('lodash'); +const config = require('../../../../config'); // NOTE: we run tests in chrome only, because we mainly test server API functionality. -describe('[API] fixture.beforeEach/fixture.afterEach hooks', function () { - it('Should run hooks for all tests', function () { - var test1Err = null; +describe('[API] fixture.beforeEach/fixture.afterEach hooks', () => { + it('Should run hooks for all tests', () => { + let test1Err = null; return runTests('./testcafe-fixtures/run-all.js', 'Test1', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { test1Err = errs[0]; + return runTests('./testcafe-fixtures/run-all.js', 'Test2', { shouldFail: true, only: 'chrome' }); }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).eql(test1Err); - expect(errs[0].indexOf( '- Error in fixture.afterEach hook - ' + 'Error on page "http://localhost:3000/fixtures/api/es-next/hooks/pages/index.html": ' + - 'Uncaught Error: [beforeEach][test][afterEach]' + 'Error: [beforeEach][test][afterEach]' )).eql(0); expect(errs[0]).contains("> 9 | .click('#failAndReport');"); }); }); - it('Should not run test and afterEach if fails in beforeEach', function () { + it('Should not run test and afterEach if fails in beforeEach', () => { return runTests('./testcafe-fixtures/fail-in-before-each.js', 'Test', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0].indexOf( '- Error in fixture.beforeEach hook - ' + 'Error on page "http://localhost:3000/fixtures/api/es-next/hooks/pages/index.html": ' + - 'Uncaught Error: [beforeEach]' + 'Error: [beforeEach]' )).eql(0); - expect(errs[0]).contains("> 6 | .click('#failAndReport');"); }); }); - it('Should run test and afterEach and beforeEach if test fails', function () { + it('Should run test and afterEach and beforeEach if test fails', () => { return runTests('./testcafe-fixtures/fail-in-test.js', 'Test', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0].indexOf( 'Error on page "http://localhost:3000/fixtures/api/es-next/hooks/pages/index.html": ' + - 'Uncaught Error: [beforeEach] ' + 'Error: [beforeEach] ' )).eql(0); - expect(errs[1].indexOf( '- Error in fixture.afterEach hook - ' + 'Error on page "http://localhost:3000/fixtures/api/es-next/hooks/pages/index.html": ' + - 'Uncaught Error: [beforeEach][afterEach]' + 'Error: [beforeEach][afterEach]' )).eql(0); - expect(errs[0]).contains("> 13 | await t.click('#failAndReport');"); expect(errs[1]).contains("> 9 | .click('#failAndReport');"); }); }); }); -describe('[API] test.before/test.after hooks', function () { - it('Should run hooks before and after test and override fixture hooks', function () { +describe('[API] test.before/test.after hooks', () => { + it('Should run hooks before and after test and override fixture hooks', () => { return runTests('./testcafe-fixtures/run-all.js', 'Test3', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).contains('- Error in test.after hook - '); expect(errs[0]).contains('[testBefore][test][testAfter]'); }); }); }); -describe('[API] t.ctx', function () { - it('Should pass context object to tests and hooks', function () { +describe('[API] t.ctx', () => { + it('Should pass context object to tests and hooks', () => { return runTests('./testcafe-fixtures/run-all.js', 't.ctx', { shouldFail: true, only: 'chrome,ie,firefox' }) - .catch(function (errs) { - var testedBrowsers = config.currentEnvironment.browsers; + .catch(errs => { + const testedBrowsers = config.currentEnvironment.browsers; if (testedBrowsers.length === 1 && Array.isArray(errs)) errs = { [testedBrowsers[0].alias]: errs }; - var browsers = []; + const browsers = []; - Object.keys(errs).forEach(function (browser) { - var dataJson = errs[browser][0].match(/###(.+)###/)[1]; - var data = JSON.parse(dataJson); + Object.keys(errs).forEach(browser => { + const dataJson = errs[browser][0].match(/###(.+)###/)[1]; + const data = JSON.parse(dataJson); // NOTE: check context assignment expect(data.ctx).eql(123); @@ -100,16 +96,16 @@ describe('[API] t.ctx', function () { }); }); -describe('[API] fixture.before/fixture.after hooks', function () { - it('Should run hooks before and after fixture', function () { +describe('[API] fixture.before/fixture.after hooks', () => { + it('Should run hooks before and after fixture', () => { return runTests('./testcafe-fixtures/fixture-hooks.js', null); }); - it('Should keep sequential reports with long executing hooks', function () { + it('Should keep sequential reports with long executing hooks', () => { return runTests('./testcafe-fixtures/fixture-hooks-seq.js', null, { shouldFail: true, only: 'chrome' - }).catch(function (errs) { + }).catch(errs => { expect(errs[0]).contains('$$test1$$'); expect(errs[1]).contains('$$afterhook1$$'); expect(errs[2]).contains('$$test2$$'); @@ -118,23 +114,23 @@ describe('[API] fixture.before/fixture.after hooks', function () { }); }); - it('Should fail all tests in fixture if fixture.before hooks fails', function () { + it('Should fail all tests in fixture if fixture.before hooks fails', () => { return runTests('./testcafe-fixtures/fixture-before-fail.js', null, { shouldFail: true, only: 'chrome, firefox' - }).catch(function (errs) { - var allErrors = errs['chrome'].concat(errs['firefox']); + }).catch(errs => { + const allErrors = errs['chrome'].concat(errs['firefox']); expect(allErrors.length).eql(6); - allErrors.forEach(function (err) { + allErrors.forEach(err => { expect(err).contains('Error in fixture.before hook'); expect(err).contains('$$before$$'); }); }); }); - it('Fixture context', function () { + it('Fixture context', () => { return runTests('./testcafe-fixtures/fixture-ctx.js', null, { only: 'chrome, firefox' }); }); }); diff --git a/test/functional/fixtures/api/es-next/test-controller/test.js b/test/functional/fixtures/api/es-next/test-controller/test.js index 8224b842..6d6a7d26 100644 --- a/test/functional/fixtures/api/es-next/test-controller/test.js +++ b/test/functional/fixtures/api/es-next/test-controller/test.js @@ -37,7 +37,7 @@ describe('[API] TestController', () => { describe('Missing `await` tracking', () => { const missingAwaitErrMsg = 'A call to an async function is not awaited. Use the "await" keyword before actions, ' + - 'assertions or chains of them to ensure that they run in the right sequence.'; + 'assertions or chains of them to ensure that they run in the right sequence.'; it('Should track missing `await`', () => { return runTests('./testcafe-fixtures/test-controller-test.js', 'Missing await', { diff --git a/test/functional/fixtures/api/raw/click/test.js b/test/functional/fixtures/api/raw/click/test.js index 18f6a3f4..86ec2cc5 100644 --- a/test/functional/fixtures/api/raw/click/test.js +++ b/test/functional/fixtures/api/raw/click/test.js @@ -1,65 +1,65 @@ -var expect = require('chai').expect; -var errorInEachBrowserContains = require('../../../../assertion-helper.js').errorInEachBrowserContains; +const { expect } = require('chai'); +const { errorInEachBrowserContains } = require('../../../../assertion-helper.js'); -describe('[Raw API] Click action', function () { - it('Should make click on a button', function () { +describe('[Raw API] Click action', () => { + it('Should make click on a button', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Click simple button', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'Click on input raised', 0); }); }); - it('Should perform click on a submit button and wait for page redirect', function () { + it('Should perform click on a submit button and wait for page redirect', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Click submit button', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, "It's a submit page", 0); }); }); - it('Should wait for the page load barrier to finish after an action', function () { + it('Should wait for the page load barrier to finish after an action', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Redirect after a timeout', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, "It's a submit page", 0); }); }); - it('Should fail when a js-error appears on page load', function () { + it('Should fail when a js-error appears on page load', () => { return runTests('./testcafe-fixtures/page-with-error.testcafe', null, { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'Error on page "http://localhost:3000/fixtures/api/raw/click/pages/error.html":', 0); - errorInEachBrowserContains(errs, 'Custom error ', 0); + errorInEachBrowserContains(errs, 'Custom error', 0); errorInEachBrowserContains(errs, '[[Click on simple button callsite]]', 0); }); }); - it('Should fail when a js-error appears during click execution', function () { + it('Should fail when a js-error appears during click execution', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Click error button', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'Error on page "http://localhost:3000/fixtures/api/raw/click/pages/index.html":', 0); errorInEachBrowserContains(errs, 'Custom error', 0); errorInEachBrowserContains(errs, '[[Click error button callsite]]', 0); }); }); - it('Should wait for xhr-requests after an action', function () { + it('Should wait for xhr-requests after an action', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Click xhr button', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'Xhr requests are finished', 0); }); }); - it('Should wait for the next action element to appear', function () { + it('Should wait for the next action element to appear', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Wait for the next action target to appear', { shouldFail: true, selectorTimeout: 3000 }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'Click on the new button raised', 0); }); }); - it("Should fail if an action target doesn't exist", function () { + it("Should fail if an action target doesn't exist", () => { return runTests('./testcafe-fixtures/click.testcafe', 'Click non-existent button', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).contains( 'The specified selector does not match any element in the DOM tree.' + ' > | Selector(\'#new-button\')' @@ -68,25 +68,25 @@ describe('[Raw API] Click action', function () { }); }); - it('Should fail if an action target is invisible', function () { + it('Should fail if an action target is invisible', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Click invisible button', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).contains('The element that matches the specified selector is not visible.'); expect(errs[0]).contains('[[Click invisible button callsite]]'); }); }); - it('Should fail if an action target is out of the visible area', function () { + it('Should fail if an action target is out of the visible area', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Click a button that is out of the visible area', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).contains('The element that matches the specified selector is not visible.'); expect(errs[0]).contains('[[Click a button that is out of the visible area callsite]]'); }); }); - it('Should fail if action has incorrect selector', function () { + it('Should fail if action has incorrect selector', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Incorrect action selector', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).contains( 'Action "selector" argument error: Selector is expected to be initialized with a function, ' + 'CSS selector string, another Selector, node snapshot or a Promise returned by a Selector, but number was passed.' @@ -96,9 +96,9 @@ describe('[Raw API] Click action', function () { }); }); - it('Should fail if action has an incorrect option', function () { + it('Should fail if action has an incorrect option', () => { return runTests('./testcafe-fixtures/click.testcafe', 'Incorrect action option', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).contains('The "offsetX" option is expected to be an integer, but it was string.'); expect(errs[0]).contains('[[Incorrect action option callsite]]'); }); diff --git a/test/functional/fixtures/api/raw/hooks/test.js b/test/functional/fixtures/api/raw/hooks/test.js index bc99254a..ba47590c 100644 --- a/test/functional/fixtures/api/raw/hooks/test.js +++ b/test/functional/fixtures/api/raw/hooks/test.js @@ -1,62 +1,60 @@ -var expect = require('chai').expect; +const { expect } = require('chai'); // NOTE: we run tests in chrome only, because we mainly test server API functionality. -describe('[Raw API] fixture.beforeEach/fixture.afterEach hooks', function () { - it('Should run hooks for all tests', function () { - var test1Err = null; +describe('[Raw API] fixture.beforeEach/fixture.afterEach hooks', () => { + it('Should run hooks for all tests', () => { + let test1Err = null; return runTests('./testcafe-fixtures/run-all.testcafe', 'Test1', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { test1Err = errs[0]; + return runTests('./testcafe-fixtures/run-all.testcafe', 'Test2', { shouldFail: true, only: 'chrome' }); }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).eql(test1Err); - expect(errs[0]).contains( '- Error in fixture.afterEach hook - ' + 'Error on page "http://localhost:3000/fixtures/api/raw/hooks/pages/index.html": ' + - 'Uncaught Error: [beforeEach][test][afterEach]' + 'Error: [beforeEach][test][afterEach]' ); }); }); - it('Should not run test and afterEach if fails in beforeEach', function () { + it('Should not run test and afterEach if fails in beforeEach', () => { return runTests('./testcafe-fixtures/fail-in-before-each.testcafe', 'Test', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { - + .catch(errs => { expect(errs[0]).contains( '- Error in fixture.beforeEach hook - ' + 'Error on page "http://localhost:3000/fixtures/api/raw/hooks/pages/index.html": ' + - 'Uncaught Error: [beforeEach]' + 'Error: [beforeEach]' ); }); }); - it('Should run test and afterEach and beforeEach if test fails', function () { + it('Should run test and afterEach and beforeEach if test fails', () => { return runTests('./testcafe-fixtures/fail-in-test.testcafe', 'Test', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).to.contains('Error on page "http://localhost:3000/fixtures/api/raw/hooks/pages/index.html": ' + - 'Uncaught Error: [beforeEach]'); + 'Error: [beforeEach]'); expect(errs[1]).to.contains('- Error in fixture.afterEach hook - ' + 'Error on page "http://localhost:3000/fixtures/api/raw/hooks/pages/index.html": ' + - 'Uncaught Error: [beforeEach][afterEach]'); + 'Error: [beforeEach][afterEach]'); }); }); }); -describe('[Raw API] test.before/test.after hooks', function () { - it('Should run hooks before and after test and override fixture hooks', function () { +describe('[Raw API] test.before/test.after hooks', () => { + it('Should run hooks before and after test and override fixture hooks', () => { return runTests('./testcafe-fixtures/run-all.testcafe', 'Test3', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).contains('- Error in test.after hook - '); expect(errs[0]).contains('[testBefore][test][testAfter]'); }); }); - }); diff --git a/test/functional/fixtures/page-js-errors/test.js b/test/functional/fixtures/page-js-errors/test.js index 9e7886ac..46a53508 100644 --- a/test/functional/fixtures/page-js-errors/test.js +++ b/test/functional/fixtures/page-js-errors/test.js @@ -1,60 +1,62 @@ -var errorInEachBrowserContains = require('../../assertion-helper.js').errorInEachBrowserContains; +const { errorInEachBrowserContains } = require('../../assertion-helper.js'); +const { expect } = require('chai'); - -describe('Test should fail after js-error on the page', function () { - it('if an error is raised before test done', function () { +describe('Test should fail after js-error on the page', () => { + it('if an error is raised before test done', () => { return runTests('./testcafe-fixtures/error-on-load-test.js', 'Empty test', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'The first error on page load', 0); + errorInEachBrowserContains(errs, 'http://localhost:3000/fixtures/page-js-errors/pages/error-on-load.html', 0); }); }); - it('if an error is raised before a command', function () { + it('if an error is raised before a command', () => { return runTests('./testcafe-fixtures/error-on-load-test.js', 'Click body', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'The first error on page load', 0); }); }); - it('if an error is raised after a command', function () { + it('if an error is raised after a command', () => { return runTests('./testcafe-fixtures/error-after-click-test.js', 'Click button', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'Error on click', 0); }); }); - it('if an error is raised after a command after the page reloaded', function () { + it('if an error is raised after a command after the page reloaded', () => { return runTests('./testcafe-fixtures/error-after-reload-test.js', 'Click button', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'The first error on page load', 0); }); }); - it('if an error is raised after a command before the page reloaded', function () { + it('if an error is raised after a command before the page reloaded', () => { return runTests('./testcafe-fixtures/error-before-reload-test.js', 'Click button', { shouldFail: true }) - .catch(function (errs) { + .catch(errs => { errorInEachBrowserContains(errs, 'Error before reload', 0); }); }); - it('if unhandled promise rejection is raised', function () { + it('if unhandled promise rejection is raised', () => { return runTests('./testcafe-fixtures/unhandled-promise-rejection-test.js', 'Click button', { shouldFail: true, only: 'chrome' }) - .catch(function (errs) { - errorInEachBrowserContains(errs, 'Rejection reason', 0); + .catch(errs => { + expect(errs[0]).contains('Rejection reason'); + expect(errs[0]).contains('No stack trace available'); }); }); }); -describe('Should ignore an js-error on the page if the skipJsErrors option is set to true', function () { - it('uncaught JavaScript error', function () { +describe('Should ignore an js-error on the page if the skipJsErrors option is set to true', () => { + it('uncaught JavaScript error', () => { return runTests('./testcafe-fixtures/error-after-click-test.js', 'Click button', { skipJsErrors: true }); }); - it ('unhandled Promise rejection', function () { + it ('unhandled Promise rejection', () => { return runTests('./testcafe-fixtures/unhandled-promise-rejection-test.js', 'Click button', { skipJsErrors: true, diff --git a/test/functional/setup.js b/test/functional/setup.js index 21c36f6b..bfbbf64d 100644 --- a/test/functional/setup.js +++ b/test/functional/setup.js @@ -12,11 +12,11 @@ const site = require('./site'); const getTestError = require('./get-test-error.js'); const { createTestStream } = require('./utils/stream'); -var testCafe = null; -var browsersInfo = null; +let testCafe = null; +let browsersInfo = null; -var connector = null; -var browserInstances = null; +let connector = null; +let browserInstances = null; const WAIT_FOR_FREE_MACHINES_REQUEST_INTERVAL = 60000; const WAIT_FOR_FREE_MACHINES_MAX_ATTEMPT_COUNT = 60; @@ -27,9 +27,9 @@ const FUNCTIONAL_TESTS_SELECTOR_TIMEOUT = 200; const FUNCTIONAL_TESTS_ASSERTION_TIMEOUT = 1000; const FUNCTIONAL_TESTS_PAGE_LOAD_TIMEOUT = 0; -var environment = config.currentEnvironment; -var browserProvider = process.env.BROWSER_PROVIDER; -var isBrowserStack = browserProvider === config.browserProviderNames.browserstack; +const environment = config.currentEnvironment; +const browserProvider = process.env.BROWSER_PROVIDER; +const isBrowserStack = browserProvider === config.browserProviderNames.browserstack; config.browsers = environment.browsers; @@ -46,7 +46,7 @@ function getBrowserInfo (settings) { .getBrowserInfo(settings.browserName) .then(browserInfo => new BrowserConnection(testCafe.browserConnectionGateway, browserInfo, true)); }) - .then(function (connection) { + .then(connection => { return { settings: settings, connection: connection @@ -57,38 +57,38 @@ function getBrowserInfo (settings) { function initBrowsersInfo () { return Promise .all(environment.browsers.map(getBrowserInfo)) - .then(function (info) { + .then(info => { browsersInfo = info; }); } function openRemoteBrowsers () { - var Connector = isBrowserStack ? BsConnector : SlConnector; + const Connector = isBrowserStack ? BsConnector : SlConnector; connector = new Connector(environment[browserProvider].username, environment[browserProvider].accessKey, { servicePort: config.browserstackConnectorServicePort }); return connector .connect() - .then(function () { + .then(() => { return connector.waitForFreeMachines(REQUESTED_MACHINES_COUNT, WAIT_FOR_FREE_MACHINES_REQUEST_INTERVAL, WAIT_FOR_FREE_MACHINES_MAX_ATTEMPT_COUNT); }) - .then(function () { - var buildInfo = { + .then(() => { + const buildInfo = { jobName: environment.jobName, build: process.env.TRAVIS_BUILD_ID || '', tags: [process.env.TRAVIS_BRANCH || 'master'] }; - var openBrowserPromises = browsersInfo.map(function (browserInfo) { + const openBrowserPromises = browsersInfo.map(browserInfo => { return connector.startBrowser(browserInfo.settings, browserInfo.connection.url, buildInfo, isBrowserStack ? { openingTimeout: BROWSER_OPENING_TIMEOUT } : null); }); return Promise.all(openBrowserPromises); }) - .then(function (browsers) { + .then(browsers => { browserInstances = browsers; }); } @@ -103,18 +103,16 @@ function openLocalBrowsers () { } function closeRemoteBrowsers () { - var closeBrowserPromises = browserInstances.map(function (browser) { - return connector.stopBrowser(isBrowserStack ? browser.id : browser); - }); + const closeBrowserPromises = browserInstances.map(browser => connector.stopBrowser(isBrowserStack ? browser.id : browser)); return Promise.all(closeBrowserPromises) - .then(function () { + .then(() => { return connector.disconnect(); }); } function closeLocalBrowsers () { - var closeBrowserPromises = browsersInfo.map(function (browserInfo) { + const closeBrowserPromises = browsersInfo.map(browserInfo => { browserInfo.connection.close(); return promisifyEvent(browserInfo.connection, 'closed'); @@ -129,15 +127,13 @@ before(function () { mocha.timeout(60000); return createTestCafe(config.testCafe.hostname, config.testCafe.port1, config.testCafe.port2) - .then(function (tc) { + .then(tc => { testCafe = tc; return initBrowsersInfo(); }) - .then(function () { - var aliases = browsersInfo.map(function (browser) { - return browser.settings.alias; - }); + .then(() => { + const aliases = browsersInfo.map(browser => browser.settings.alias); process.stdout.write('Running tests in browsers: ' + aliases.join(', ') + '\n'); @@ -154,7 +150,7 @@ before(function () { return openLocalBrowsers(); }) - .then(function () { + .then(() => { global.testReport = null; global.testCafe = testCafe; diff --git a/test/server/create-testcafe-test.js b/test/server/create-testcafe-test.js index 26aa64e1..a644b167 100644 --- a/test/server/create-testcafe-test.js +++ b/test/server/create-testcafe-test.js @@ -12,7 +12,7 @@ describe('TestCafe factory function', function () { function getTestCafe (hostname, port1, port2, sslOptions) { return createTestCafe(hostname, port1, port2, sslOptions) - .then(function (tc) { + .then(tc => { testCafe = tc; }); } diff --git a/test/server/data/expected-test-run-errors/uncaught-js-error-on-page b/test/server/data/expected-test-run-errors/uncaught-js-error-on-page index 2a5c36ad..34c30eef 100644 --- a/test/server/data/expected-test-run-errors/uncaught-js-error-on-page +++ b/test/server/data/expected-test-run-errors/uncaught-js-error-on-page @@ -1,6 +1,9 @@ Error on page "http://example.org": -Custom script error +Test error: +    at method3 (http://example.com):1:3 +    at method2 (http://example.com):1:2 +    at method1 (http://example.com):1:1 Browser: Chrome 15.0.874 / Mac OS X 10.8.1 Screenshot: /unix/path/with/ diff --git a/test/server/legacy-test-run-error-formatting-test.js b/test/server/legacy-test-run-error-formatting-test.js index 158e195d..5fbd0b2f 100644 --- a/test/server/legacy-test-run-error-formatting-test.js +++ b/test/server/legacy-test-run-error-formatting-test.js @@ -1,36 +1,23 @@ -var expect = require('chai').expect; -var read = require('read-file-relative').readSync; -var remove = require('lodash').pull; -var ReporterPluginHost = require('../../lib/reporter/plugin-host'); -var testCafeLegacyApi = require('testcafe-legacy-api'); +const expect = require('chai').expect; +const read = require('read-file-relative').readSync; +const remove = require('lodash').pull; +const ReporterPluginHost = require('../../lib/reporter/plugin-host'); +const testCafeLegacyApi = require('testcafe-legacy-api'); +const { createTestStream } = require('../functional/utils/stream'); -var TEST_RUN_ERROR_TYPE = testCafeLegacyApi.TEST_RUN_ERROR_TYPE; -var LegacyTestRunErrorFormattableAdapter = testCafeLegacyApi.TestRunErrorFormattableAdapter; +const TEST_RUN_ERROR_TYPE = testCafeLegacyApi.TEST_RUN_ERROR_TYPE; +const LegacyTestRunErrorFormattableAdapter = testCafeLegacyApi.TestRunErrorFormattableAdapter; +const untestedErrorTypes = Object.keys(TEST_RUN_ERROR_TYPE).map(key => TEST_RUN_ERROR_TYPE[key]); -var untestedErrorTypes = Object.keys(TEST_RUN_ERROR_TYPE).map(function (key) { - return TEST_RUN_ERROR_TYPE[key]; -}); - -var userAgentMock = 'Chrome 15.0.874 / Mac OS X 10.8.1'; - -// Output stream and errorDecorator mocks -function createOutStreamMock () { - return { - data: '', - - write: function (text) { - this.data += text; - } - }; -} +const userAgentMock = 'Chrome 15.0.874 / Mac OS X 10.8.1'; function assertErrorMessage (file, err, callsite) { - var screenshotPath = '/unix/path/with/'; - var outStreamMock = createOutStreamMock(); - var plugin = new ReporterPluginHost({}, outStreamMock); + const screenshotPath = '/unix/path/with/'; + const outStreamMock = createTestStream(); + const plugin = new ReporterPluginHost({}, outStreamMock); - var errAdapter = new LegacyTestRunErrorFormattableAdapter(err, { + const errAdapter = new LegacyTestRunErrorFormattableAdapter(err, { userAgent: userAgentMock, screenshotPath: screenshotPath, callsite: callsite @@ -40,7 +27,7 @@ function assertErrorMessage (file, err, callsite) { .useWordWrap(true) .write(plugin.formatError(errAdapter)); - var expectedMsg = read('./data/expected-legacy-test-run-errors/' + file) + const expectedMsg = read('./data/expected-legacy-test-run-errors/' + file) .replace(/(\r\n)/gm, '\n') .trim(); diff --git a/test/server/test-run-error-formatting-test.js b/test/server/test-run-error-formatting-test.js index 3e05bbec..cf763fad 100644 --- a/test/server/test-run-error-formatting-test.js +++ b/test/server/test-run-error-formatting-test.js @@ -1,7 +1,6 @@ const expect = require('chai').expect; const read = require('read-file-relative').readSync; -const remove = require('lodash').pull; -const escapeRe = require('lodash').escapeRegExp; +const { escapeRegExp, pull: remove } = require('lodash'); const ReporterPluginHost = require('../../lib/reporter/plugin-host'); const TEST_RUN_PHASE = require('../../lib/test-run/phase'); const TYPE = require('../../lib/errors/test-run/type'); @@ -14,7 +13,7 @@ const ActionPositiveIntegerOptionError = require('../../lib/err const ActionIntegerArgumentError = require('../../lib/errors/test-run').ActionIntegerArgumentError; const ActionPositiveIntegerArgumentError = require('../../lib/errors/test-run').ActionPositiveIntegerArgumentError; const ActionBooleanOptionError = require('../../lib/errors/test-run').ActionBooleanOptionError; -var ActionBooleanArgumentError = require('../../lib/errors/test-run').ActionBooleanArgumentError; +const ActionBooleanArgumentError = require('../../lib/errors/test-run').ActionBooleanArgumentError; const ActionSpeedOptionError = require('../../lib/errors/test-run').ActionSpeedOptionError; const ActionSelectorError = require('../../lib/errors/test-run').ActionSelectorError; const ActionOptionsTypeError = require('../../lib/errors/test-run').ActionOptionsTypeError; @@ -64,12 +63,11 @@ const InvalidElementScreenshotDimensionsError = require('../../lib/err const SetTestSpeedArgumentError = require('../../lib/errors/test-run').SetTestSpeedArgumentError; const RoleSwitchInRoleInitializerError = require('../../lib/errors/test-run').RoleSwitchInRoleInitializerError; const ActionRoleArgumentError = require('../../lib/errors/test-run').ActionRoleArgumentError; +const { createTestStream } = require('../functional/utils/stream'); -const TEST_FILE_STACK_ENTRY_RE = new RegExp('\\s*\\n?\\(' + escapeRe(require.resolve('./data/test-callsite')), 'g'); +const TEST_FILE_STACK_ENTRY_RE = new RegExp('\\s*\\n?\\(' + escapeRegExp(require.resolve('./data/test-callsite')), 'g'); -const untestedErrorTypes = Object.keys(TYPE).map(function (key) { - return TYPE[key]; -}); +const untestedErrorTypes = Object.keys(TYPE).map(key => TYPE[key]); const userAgentMock = 'Chrome 15.0.874 / Mac OS X 10.8.1'; @@ -86,20 +84,9 @@ const testAssertionError = (function () { const longSelector = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'; -// Output stream and errorDecorator mocks -function createOutStreamMock () { - return { - data: '', - - write: function (text) { - this.data += text; - } - }; -} - function assertErrorMessage (file, err) { const screenshotPath = '/unix/path/with/'; - const outStreamMock = createOutStreamMock(); + const outStreamMock = createTestStream(); const plugin = new ReporterPluginHost({}, outStreamMock); const errAdapter = new TestRunErrorFormattableAdapter(err, { @@ -123,243 +110,250 @@ function assertErrorMessage (file, err) { // NOTE: check that the list of error types contains an // error of this type and remove tested messages from the list - expect(untestedErrorTypes.indexOf(err.type) !== -1).to.be.ok; + expect(untestedErrorTypes.includes(err.type)).to.be.ok; remove(untestedErrorTypes, err.type); } -describe('Error formatting', function () { - describe('Errors', function () { - it('Should format "actionIntegerOptionError" message', function () { +describe('Error formatting', () => { + describe('Errors', () => { + it('Should format "actionIntegerOptionError" message', () => { assertErrorMessage('action-integer-option-error', new ActionIntegerOptionError('offsetX', '1.01')); }); - it('Should format "actionPositiveIntegerOptionError" message', function () { + it('Should format "actionPositiveIntegerOptionError" message', () => { assertErrorMessage('action-positive-integer-option-error', new ActionPositiveIntegerOptionError('caretPos', '-1')); }); - it('Should format "actionIntegerArgumentError" message', function () { + it('Should format "actionIntegerArgumentError" message', () => { assertErrorMessage('action-integer-argument-error', new ActionIntegerArgumentError('dragOffsetX', 'NaN')); }); - it('Should format "actionPositiveIntegerArgumentError" message', function () { + it('Should format "actionPositiveIntegerArgumentError" message', () => { assertErrorMessage('action-positive-integer-argument-error', new ActionPositiveIntegerArgumentError('startPos', '-1')); }); - it('Should format "actionBooleanOptionError" message', function () { + it('Should format "actionBooleanOptionError" message', () => { assertErrorMessage('action-boolean-option-error', new ActionBooleanOptionError('modifier.ctrl', 'object')); }); - it('Should format the "actionBooleanArgumentError" message', function () { + it('Should format the "actionBooleanArgumentError" message', () => { assertErrorMessage('action-boolean-argument-error', new ActionBooleanArgumentError('isAsyncExpression', 'object')); }); - it('Should format "actionSpeedOptionError" message', function () { + it('Should format "actionSpeedOptionError" message', () => { assertErrorMessage('action-speed-option-error', new ActionSpeedOptionError('speed', 'object')); }); - it('Should format "pageLoadError" message', function () { + it('Should format "pageLoadError" message', () => { assertErrorMessage('page-load-error', new PageLoadError('Failed to find a DNS-record for the resource')); }); - it('Should format "uncaughtErrorOnPage" message', function () { - assertErrorMessage('uncaught-js-error-on-page', new UncaughtErrorOnPage('Custom script error', 'http://example.org')); + it('Should format "uncaughtErrorOnPage" message (with error stack)', () => { + const errStack = [ + 'Test error:', + ' at method3 (http://example.com):1:3', + ' at method2 (http://example.com):1:2', + ' at method1 (http://example.com):1:1' + ].join('\n'); + + assertErrorMessage('uncaught-js-error-on-page', new UncaughtErrorOnPage(errStack, 'http://example.org')); }); - it('Should format "uncaughtErrorInTestCode" message', function () { + it('Should format "uncaughtErrorInTestCode" message', () => { assertErrorMessage('uncaught-js-error-in-test-code', new UncaughtErrorInTestCode(new Error('Custom script error'), testCallsite)); }); - it('Should format "uncaughtNonErrorObjectInTestCode" message', function () { + it('Should format "uncaughtNonErrorObjectInTestCode" message', () => { assertErrorMessage('uncaught-non-error-object-in-test-code', new UncaughtNonErrorObjectInTestCode('Hey ya!')); }); - it('Should format "uncaughtErrorInAddCustomDOMProperties" message', function () { + it('Should format "uncaughtErrorInAddCustomDOMProperties" message', () => { assertErrorMessage('uncaught-error-in-add-custom-dom-properties-code', new UncaughtErrorInCustomDOMPropertyCode(testCallsite, new Error('Custom script error'), 'prop')); }); - it('Should format "unhandledPromiseRejectionError" message', function () { + it('Should format "unhandledPromiseRejectionError" message', () => { assertErrorMessage('unhandled-promise-rejection-error', new UnhandledPromiseRejectionError('Hey ya!')); }); - it('Should format "uncaughtExceptionError" message', function () { + it('Should format "uncaughtExceptionError" message', () => { assertErrorMessage('uncaught-exception-error', new UncaughtExceptionError('Hey ya!')); }); - it('Should format "actionElementNotFoundError" message', function () { + it('Should format "actionElementNotFoundError" message', () => { assertErrorMessage('action-element-not-found-error', new ActionElementNotFoundError({ apiFnChain: [longSelector, 'one', 'two', 'three'], apiFnIndex: 1 })); }); - it('Should format "actionElementIsInvisibleError" message', function () { + it('Should format "actionElementIsInvisibleError" message', () => { assertErrorMessage('action-element-is-invisible-error', new ActionElementIsInvisibleError()); }); - it('Should format "actionSelectorMatchesWrongNodeTypeError" message', function () { + it('Should format "actionSelectorMatchesWrongNodeTypeError" message', () => { assertErrorMessage('action-selector-matches-wrong-node-type-error', new ActionSelectorMatchesWrongNodeTypeError('text')); }); - it('Should format "actionElementNonEditableError" message', function () { + it('Should format "actionElementNonEditableError" message', () => { assertErrorMessage('action-element-non-editable-error', new ActionElementNonEditableError()); }); - it('Should format "actionRootContainerNotFoundError" message', function () { + it('Should format "actionRootContainerNotFoundError" message', () => { assertErrorMessage('action-root-container-not-found-error', new ActionRootContainerNotFoundError()); }); - it('Should format "actionElementNonContentEditableError" message', function () { + it('Should format "actionElementNonContentEditableError" message', () => { assertErrorMessage('action-element-non-content-editable-error', new ActionElementNonContentEditableError('startSelector')); }); - it('Should format "actionElementNotTextAreaError" message', function () { + it('Should format "actionElementNotTextAreaError" message', () => { assertErrorMessage('action-element-not-text-area-error', new ActionElementNotTextAreaError()); }); - it('Should format "actionElementNotIframeError" message', function () { + it('Should format "actionElementNotIframeError" message', () => { assertErrorMessage('action-element-not-iframe-error', new ActionElementNotIframeError()); }); - it('Should format "actionSelectorError" message', function () { + it('Should format "actionSelectorError" message', () => { assertErrorMessage('action-selector-error', new ActionSelectorError('selector', 'Yo!')); }); - it('Should format "actionOptionsTypeError" message', function () { + it('Should format "actionOptionsTypeError" message', () => { assertErrorMessage('action-options-type-error', new ActionOptionsTypeError(typeof 1)); }); - it('Should format "actionAdditionalElementNotFoundError" message', function () { + it('Should format "actionAdditionalElementNotFoundError" message', () => { assertErrorMessage('action-additional-element-not-found-error', new ActionAdditionalElementNotFoundError('startSelector', { apiFnChain: [longSelector, 'one', 'two', 'three'], apiFnIndex: 1 })); }); - it('Should format "actionAdditionalElementIsInvisibleError" message', function () { + it('Should format "actionAdditionalElementIsInvisibleError" message', () => { assertErrorMessage('action-additional-element-is-invisible-error', new ActionAdditionalElementIsInvisibleError('startSelector')); }); - it('Should format "actionAdditionalSelectorMatchesWrongNodeTypeError" message', function () { + it('Should format "actionAdditionalSelectorMatchesWrongNodeTypeError" message', () => { assertErrorMessage('action-additional-selector-matches-wrong-node-type-error', new ActionAdditionalSelectorMatchesWrongNodeTypeError('startSelector', 'text')); }); - it('Should format "actionStringArgumentError" message', function () { + it('Should format "actionStringArgumentError" message', () => { assertErrorMessage('action-string-argument-error', new ActionStringArgumentError('text', typeof 1)); }); - it('Should format "actionNullableStringArgumentError" message', function () { + it('Should format "actionNullableStringArgumentError" message', () => { assertErrorMessage('action-nullable-string-argument-error', new ActionNullableStringArgumentError('text', typeof 1)); }); - it('Should format "actionIncorrectKeysError" message', function () { + it('Should format "actionIncorrectKeysError" message', () => { assertErrorMessage('action-incorrect-keys-error', new ActionIncorrectKeysError('keys')); }); - it('Should format "actionNonEmptyStringArrayArgumentError" message', function () { + it('Should format "actionNonEmptyStringArrayArgumentError" message', () => { assertErrorMessage('action-non-empty-string-array-argument-error', new ActionStringOrStringArrayArgumentError('array', null)); }); - it('Should format "actionStringArrayElementError" message', function () { + it('Should format "actionStringArrayElementError" message', () => { assertErrorMessage('action-string-array-element-error', new ActionStringArrayElementError('array', 'number', 1)); }); - it('Should format "actionElementIsNotFileInputError" message', function () { + it('Should format "actionElementIsNotFileInputError" message', () => { assertErrorMessage('action-element-is-not-file-input-error', new ActionElementIsNotFileInputError()); }); - it('Should format "actionCanNotFindFileToUploadError" message', function () { + it('Should format "actionCanNotFindFileToUploadError" message', () => { assertErrorMessage('action-can-not-find-file-to-upload-error', new ActionCanNotFindFileToUploadError(['/path/1', '/path/2'])); }); - it('Should format "actionUnsupportedDeviceTypeError" message', function () { + it('Should format "actionUnsupportedDeviceTypeError" message', () => { assertErrorMessage('action-unsupported-device-type-error', new ActionUnsupportedDeviceTypeError('device', 'iPhone 555')); }); - it('Should format "actionInvalidScrollTargetError" message', function () { + it('Should format "actionInvalidScrollTargetError" message', () => { assertErrorMessage('action-invalid-scroll-target-error', new ActionInvalidScrollTargetError(false, true)); }); - it('Should format "actionIframeIsNotLoadedError" message', function () { + it('Should format "actionIframeIsNotLoadedError" message', () => { assertErrorMessage('action-iframe-is-not-loaded-error', new ActionIframeIsNotLoadedError()); }); - it('Should format "currentIframeIsNotLoadedError" message', function () { + it('Should format "currentIframeIsNotLoadedError" message', () => { assertErrorMessage('current-iframe-is-not-loaded-error', new CurrentIframeIsNotLoadedError()); }); - it('Should format "currentIframeNotFoundError" message', function () { + it('Should format "currentIframeNotFoundError" message', () => { assertErrorMessage('current-iframe-not-found-error', new CurrentIframeNotFoundError()); }); - it('Should format "currentIframeIsInvisibleError" message', function () { + it('Should format "currentIframeIsInvisibleError" message', () => { assertErrorMessage('current-iframe-is-invisible-error', new CurrentIframeIsInvisibleError()); }); - it('Should format "missingAwaitError', function () { + it('Should format "missingAwaitError', () => { assertErrorMessage('missing-await-error', new MissingAwaitError(testCallsite)); }); - it('Should format "externalAssertionLibraryError', function () { + it('Should format "externalAssertionLibraryError', () => { assertErrorMessage('external-assertion-library-error', new ExternalAssertionLibraryError(testAssertionError, testCallsite)); }); - it('Should format "uncaughtErrorInClientFunctionCode"', function () { + it('Should format "uncaughtErrorInClientFunctionCode"', () => { assertErrorMessage('uncaught-error-in-client-function-code', new UncaughtErrorInClientFunctionCode('Selector', new Error('Some error.'))); }); - it('Should format "clientFunctionExecutionInterruptionError"', function () { + it('Should format "clientFunctionExecutionInterruptionError"', () => { assertErrorMessage('client-function-execution-interruption-error', new ClientFunctionExecutionInterruptionError('eval')); }); - it('Should format "domNodeClientFunctionResultError"', function () { + it('Should format "domNodeClientFunctionResultError"', () => { assertErrorMessage('dom-node-client-function-result-error', new DomNodeClientFunctionResultError('ClientFunction')); }); - it('Should format "invalidSelectorResultError"', function () { + it('Should format "invalidSelectorResultError"', () => { assertErrorMessage('invalid-selector-result-error', new InvalidSelectorResultError()); }); - it('Should format "nativeDialogNotHandledError"', function () { + it('Should format "nativeDialogNotHandledError"', () => { assertErrorMessage('native-dialog-not-handled-error', new NativeDialogNotHandledError('alert', 'http://example.org')); }); - it('Should format "uncaughtErrorInNativeDialogHandler"', function () { + it('Should format "uncaughtErrorInNativeDialogHandler"', () => { assertErrorMessage('uncaught-error-in-native-dialog-handler', new UncaughtErrorInNativeDialogHandler('alert', 'error message', 'http://example.org')); }); - it('Should format "setNativeDialogHandlerCodeWrongTypeError"', function () { + it('Should format "setNativeDialogHandlerCodeWrongTypeError"', () => { assertErrorMessage('set-native-dialog-handler-code-wrong-type-error', new SetNativeDialogHandlerCodeWrongTypeError('number')); }); - it('Should format "cantObtainInfoForElementSpecifiedBySelectorError"', function () { + it('Should format "cantObtainInfoForElementSpecifiedBySelectorError"', () => { assertErrorMessage('cant-obtain-info-for-element-specified-by-selector-error', new CantObtainInfoForElementSpecifiedBySelectorError(testCallsite, { apiFnChain: [longSelector, 'one', 'two', 'three'], apiFnIndex: 1 })); }); - it('Should format "windowDimensionsOverflowError"', function () { + it('Should format "windowDimensionsOverflowError"', () => { assertErrorMessage('window-dimensions-overflow-error', new WindowDimensionsOverflowError()); }); - it('Should format "InvalidElementScreenshotDimensionsError"', function () { + it('Should format "InvalidElementScreenshotDimensionsError"', () => { assertErrorMessage('invalid-element-screenshot-dimensions-error', new InvalidElementScreenshotDimensionsError(0, 10)); }); - it('Should format "setTestSpeedArgumentError"', function () { + it('Should format "setTestSpeedArgumentError"', () => { assertErrorMessage('set-test-speed-argument-error', new SetTestSpeedArgumentError('speed', 'string')); }); - it('Should format "roleSwitchInRoleInitializerError"', function () { + it('Should format "roleSwitchInRoleInitializerError"', () => { assertErrorMessage('role-switch-in-role-initializer-error', new RoleSwitchInRoleInitializerError(testCallsite)); }); - it('Should format "actionRoleArgumentError"', function () { + it('Should format "actionRoleArgumentError"', () => { assertErrorMessage('action-role-argument-error', new ActionRoleArgumentError('role', 'number')); }); - it('Should format "assertionExecutableArgumentError"', function () { + it('Should format "assertionExecutableArgumentError"', () => { assertErrorMessage('assertion-executable-argument-error', new AssertionExecutableArgumentError('actual', '1 + temp', 'Unexpected identifier')); }); - it('Should format "assertionUnawaitedPromiseError"', function () { + it('Should format "assertionUnawaitedPromiseError"', () => { assertErrorMessage('assertion-unawaited-promise-error', new AssertionUnawaitedPromiseError(testCallsite)); }); }); - describe('Test coverage', function () { - it('Should test messages for all error codes', function () { + describe('Test coverage', () => { + it('Should test messages for all error codes', () => { expect(untestedErrorTypes).to.be.empty; }); }); diff --git a/test/server/util-test.js b/test/server/util-test.js index 097e9ce7..aec2ebd7 100644 --- a/test/server/util-test.js +++ b/test/server/util-test.js @@ -1,12 +1,12 @@ -const path = require('path'); -const fs = require('fs'); -const del = require('del'); -const expect = require('chai').expect; -const correctFilePath = require('../../lib/utils/correct-file-path'); -const escapeUserAgent = require('../../lib/utils/escape-user-agent'); -const parseFileList = require('../../lib/utils/parse-file-list'); -const TempDirectory = require('../../lib/utils/temp-directory'); - +const path = require('path'); +const fs = require('fs'); +const del = require('del'); +const expect = require('chai').expect; +const correctFilePath = require('../../lib/utils/correct-file-path'); +const escapeUserAgent = require('../../lib/utils/escape-user-agent'); +const parseFileList = require('../../lib/utils/parse-file-list'); +const TempDirectory = require('../../lib/utils/temp-directory'); +const { replaceLeadingSpacesWithNbsp } = require('../../lib/utils/string'); describe('Utils', () => { it('Correct File Path', () => { @@ -67,7 +67,7 @@ describe('Utils', () => { }); }); - describe('Temp Directory', function () { + describe('Temp Directory', () => { const TMP_ROOT = path.join(process.cwd(), '__tmp__'); const savedTmpRoot = TempDirectory.TEMP_DIRECTORIES_ROOT; @@ -120,4 +120,12 @@ describe('Utils', () => { }); }); }); + + it('Replace leading spaces with  ', () => { + expect(replaceLeadingSpacesWithNbsp('test')).eql('test'); + expect(replaceLeadingSpacesWithNbsp(' test')).eql(' test'); + expect(replaceLeadingSpacesWithNbsp(' test')).eql('  test'); + expect(replaceLeadingSpacesWithNbsp(' test1 test2 ')).eql(' test1 test2 '); + expect(replaceLeadingSpacesWithNbsp(' test1\n test2 \r\ntest3 ')).eql('  test1\n test2 \r\ntest3 '); + }); }); From 7ac5ac6775fef2c379f5e6b12503fff6a9fdf8c5 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Mon, 10 Sep 2018 23:45:16 +0300 Subject: [PATCH 091/184] fix 'Request hook added multiple times when using filter rule ' (close #2650) (#2834) * fix 'Request hook added multiple times when using filter rule ' (close #2650) * revert back method name --- src/api/request-hooks/hook.js | 9 ++--- src/client/automation/playback/dblclick.js | 19 +++++----- test/server/request-hooks-test.js | 40 +++++++++++++++------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/api/request-hooks/hook.js b/src/api/request-hooks/hook.js index 4ee026e2..3829ca4d 100644 --- a/src/api/request-hooks/hook.js +++ b/src/api/request-hooks/hook.js @@ -18,11 +18,12 @@ export default class RequestHook { } _instantiateRequestFilterRules () { + this._instantiatedRequestFilterRules = []; + this.requestFilterRules.forEach(rule => { - if (rule instanceof RequestFilterRule) - this._instantiatedRequestFilterRules.push(rule); - else - this._instantiatedRequestFilterRules.push(new RequestFilterRule(rule)); + const instantiatedRule = rule instanceof RequestFilterRule ? rule : new RequestFilterRule(rule); + + this._instantiatedRequestFilterRules.push(instantiatedRule); }); } diff --git a/src/client/automation/playback/dblclick.js b/src/client/automation/playback/dblclick.js index 14e6bf46..cae041ea 100644 --- a/src/client/automation/playback/dblclick.js +++ b/src/client/automation/playback/dblclick.js @@ -5,16 +5,15 @@ import VisibleElementAutomation from './visible-element-automation'; import ClickAutomation from './click'; import AutomationSettings from '../settings'; -var featureDetection = hammerhead.utils.featureDetection; -var browserUtils = hammerhead.utils.browser; -var eventSimulator = hammerhead.eventSandbox.eventSimulator; +const featureDetection = hammerhead.utils.featureDetection; +const browserUtils = hammerhead.utils.browser; +const eventSimulator = hammerhead.eventSandbox.eventSimulator; -var eventUtils = testCafeCore.eventUtils; -var delay = testCafeCore.delay; +const eventUtils = testCafeCore.eventUtils; +const delay = testCafeCore.delay; const FIRST_CLICK_DELAY = featureDetection.isTouchDevice ? 0 : 160; - export default class DblClickAutomation extends VisibleElementAutomation { constructor (element, clickOptions) { super(element, clickOptions); @@ -37,11 +36,11 @@ export default class DblClickAutomation extends VisibleElementAutomation { _firstClick (useStrictElementCheck) { // NOTE: we should always perform click with the highest speed - var clickOptions = new ClickOptions(this.options); + const clickOptions = new ClickOptions(this.options); clickOptions.speed = 1; - var clickAutomation = new ClickAutomation(this.element, clickOptions); + const clickAutomation = new ClickAutomation(this.element, clickOptions); clickAutomation.on(clickAutomation.TARGET_ELEMENT_FOUND_EVENT, e => this.emit(this.TARGET_ELEMENT_FOUND_EVENT, e)); @@ -56,7 +55,7 @@ export default class DblClickAutomation extends VisibleElementAutomation { if (browserUtils.isIE) eventUtils.bind(document, 'focus', eventUtils.preventDefault, true); - var clickOptions = new ClickOptions({ + const clickOptions = new ClickOptions({ offsetX: eventArgs.screenPoint.x, offsetY: eventArgs.screenPoint.y, caretPos: this.caretPos, @@ -64,7 +63,7 @@ export default class DblClickAutomation extends VisibleElementAutomation { speed: 1 }); - var clickAutomation = new ClickAutomation(document.documentElement, clickOptions); + const clickAutomation = new ClickAutomation(document.documentElement, clickOptions); return clickAutomation.run() .then(clickEventArgs => { diff --git a/test/server/request-hooks-test.js b/test/server/request-hooks-test.js index 117c12c4..6fe22411 100644 --- a/test/server/request-hooks-test.js +++ b/test/server/request-hooks-test.js @@ -1,12 +1,10 @@ -const RequestFilterRule = require('testcafe-hammerhead').RequestFilterRule; -const testRunTracker = require('../../lib/api/test-run-tracker'); -const exportableLib = require('../../lib/api/exportable-lib'); -const RequestMock = exportableLib.RequestMock; -const RequestLogger = exportableLib.RequestLogger; -const RequestHook = exportableLib.RequestHook; -const Promise = require('pinkie'); -const nanoid = require('nanoid'); -const expect = require('chai').expect; +const { RequestFilterRule } = require('testcafe-hammerhead'); +const testRunTracker = require('../../lib/api/test-run-tracker'); +const exportableLib = require('../../lib/api/exportable-lib'); +const { RequestMock, RequestLogger, RequestHook } = exportableLib; +const Promise = require('pinkie'); +const nanoid = require('nanoid'); +const { expect } = require('chai'); describe('RequestLogger', () => { const createProxyRequestEventMock = (testRunId, requestId) => { @@ -222,9 +220,25 @@ describe('RequestMock', () => { }); }); -it('RequestHook should handle any requests by default', () => { - const hook = new RequestHook(); - const defaultHookRequestFilterRules = hook.requestFilterRules; +describe('RequestHook', () => { + it('Should handle any requests by default', () => { + const hook = new RequestHook(); + const defaultHookRequestFilterRules = hook.requestFilterRules; - expect(defaultHookRequestFilterRules).to.deep.equal([RequestFilterRule.ANY]); + expect(defaultHookRequestFilterRules).to.deep.equal([RequestFilterRule.ANY]); + }); + + it('Should not duplicate instantiated filter rules between test runs (GH-2650)', () => { + const url = 'http://example.com'; + const hook = new RequestHook(url); + + hook._instantiateRequestFilterRules(); + + expect(hook._instantiatedRequestFilterRules.length).eql(1); + + hook._instantiateRequestFilterRules(); + + expect(hook._instantiatedRequestFilterRules.length).eql(1); + }); }); + From 462606c3266170b8ff111f76b2bed683bd8808b6 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Tue, 11 Sep 2018 14:07:33 +0300 Subject: [PATCH 092/184] Restart browser if it became unresponsive (closes #1815) (#2800) * [WIP]Restart browser if it became unresponsive (closes #1815) * tests * change approach * fix server tests * fix for headless browsers * fix functional test * refactor and fix tests * refactoring and tests * refactoring * refactor * refactoring * fix and refactoring * add listenered to connection only when testRun is started * rename and fix typos --- Gulpfile.js | 2 +- src/browser/connection/index.js | 109 +++++++++++++----- src/runner/browser-job.js | 6 +- src/runner/test-run-controller.js | 29 ++++- src/test-run/index.js | 75 ++++++++---- .../browser-reconnect/pages/index.html | 9 ++ .../browser-reconnect/test.js | 72 ++++++++++++ .../testcafe-fixtures/index-test.js | 48 ++++++++ test/server/browser-connection-test.js | 4 + 9 files changed, 292 insertions(+), 62 deletions(-) create mode 100644 test/functional/fixtures/browser-provider/browser-reconnect/pages/index.html create mode 100644 test/functional/fixtures/browser-provider/browser-reconnect/test.js create mode 100644 test/functional/fixtures/browser-provider/browser-reconnect/testcafe-fixtures/index-test.js diff --git a/Gulpfile.js b/Gulpfile.js index ece2f310..e2821c8f 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -627,7 +627,7 @@ function testFunctional (fixturesDir, testingEnvironmentName, browserProviderNam .pipe(mocha({ ui: 'bdd', reporter: 'spec', - timeout: typeof v8debug === 'undefined' ? 30000 : Infinity // NOTE: disable timeouts in debug + timeout: typeof v8debug === 'undefined' ? 180000 : Infinity // NOTE: disable timeouts in debug })); } diff --git a/src/browser/connection/index.js b/src/browser/connection/index.js index 07611e1a..224d5000 100644 --- a/src/browser/connection/index.js +++ b/src/browser/connection/index.js @@ -12,19 +12,22 @@ import { GeneralError } from '../../errors/runtime'; import MESSAGE from '../../errors/runtime/message'; const IDLE_PAGE_TEMPLATE = read('../../client/browser/idle-page/index.html.mustache'); +const connections = {}; -var connections = {}; export default class BrowserConnection extends EventEmitter { constructor (gateway, browserInfo, permanent) { super(); - this.HEARTBEAT_TIMEOUT = 2 * 60 * 1000; + this.HEARTBEAT_TIMEOUT = 2 * 60 * 1000; + this.BROWSER_RESTART_TIMEOUT = 60 * 1000; this.id = BrowserConnection._generateId(); this.jobQueue = []; this.initScriptsQueue = []; this.browserConnectionGateway = gateway; + this.errorSuppressed = false; + this.testRunAborted = false; this.browserInfo = browserInfo; this.browserInfo.userAgent = ''; @@ -63,33 +66,30 @@ export default class BrowserConnection extends EventEmitter { this.browserConnectionGateway.startServingConnection(this); - this._runBrowser(); + process.nextTick(() => this._runBrowser()); } static _generateId () { return nanoid(7); } - _runBrowser () { - // NOTE: Give caller time to assign event listeners - process.nextTick(async () => { - try { - await this.provider.openBrowser(this.id, this.url, this.browserInfo.browserName); + async _runBrowser () { + try { + await this.provider.openBrowser(this.id, this.url, this.browserInfo.browserName); - if (!this.ready) - await promisifyEvent(this, 'ready'); + if (!this.ready) + await promisifyEvent(this, 'ready'); - this.opened = true; - this.emit('opened'); - } - catch (err) { - this.emit('error', new GeneralError( - MESSAGE.unableToOpenBrowser, - this.browserInfo.providerName + ':' + this.browserInfo.browserName, - err.stack - )); - } - }); + this.opened = true; + this.emit('opened'); + } + catch (err) { + this.emit('error', new GeneralError( + MESSAGE.unableToOpenBrowser, + this.browserInfo.providerName + ':' + this.browserInfo.browserName, + err.stack + )); + } } async _closeBrowser () { @@ -112,14 +112,28 @@ export default class BrowserConnection extends EventEmitter { } } + _createBrowserDisconnectedError () { + return new GeneralError(MESSAGE.browserDisconnected, this.userAgent); + } + _waitForHeartbeat () { this.heartbeatTimeout = setTimeout(() => { - this.emit('error', new GeneralError(MESSAGE.browserDisconnected, this.userAgent)); + const err = this._createBrowserDisconnectedError(); + + this.opened = false; + this.errorSuppressed = false; + this.testRunAborted = true; + + this.emit('disconnected', err); + + if (!this.errorSuppressed) + this.emit('error', err); + }, this.HEARTBEAT_TIMEOUT); } - async _getTestRunUrl (isTestDone) { - if (isTestDone || !this.pendingTestRunUrl) + async _getTestRunUrl (needPopNext) { + if (needPopNext || !this.pendingTestRunUrl) this.pendingTestRunUrl = await this._popNextTestRunUrl(); return this.pendingTestRunUrl; @@ -136,6 +150,43 @@ export default class BrowserConnection extends EventEmitter { return connections[id] || null; } + async restartBrowser () { + this.ready = false; + + this._forceIdle(); + + let resolveTimeout = null; + let isTimeoutExpired = false; + let timeout = null; + + const restartPromise = this._closeBrowser() + .then(() => this._runBrowser()); + + const timeoutPromise = new Promise(resolve => { + resolveTimeout = resolve; + + timeout = setTimeout(() => { + isTimeoutExpired = true; + + resolve(); + }, this.BROWSER_RESTART_TIMEOUT); + }); + + Promise.race([ restartPromise, timeoutPromise ]) + .then(() => { + clearTimeout(timeout); + + if (isTimeoutExpired) + this.emit('error', this._createBrowserDisconnectedError()); + else + resolveTimeout(); + }); + } + + suppressError () { + this.errorSuppressed = true; + } + addWarning (...args) { if (this.currentJob) this.currentJob.warningLog.addWarning(...args); @@ -146,7 +197,7 @@ export default class BrowserConnection extends EventEmitter { } get userAgent () { - var userAgent = this.browserInfo.userAgent; + let userAgent = this.browserInfo.userAgent; if (this.browserInfo.userAgentProviderMetaInfo) userAgent += ` (${this.browserInfo.userAgentProviderMetaInfo})`; @@ -228,13 +279,13 @@ export default class BrowserConnection extends EventEmitter { } getInitScript () { - var initScriptPromise = this.initScriptsQueue[0]; + const initScriptPromise = this.initScriptsQueue[0]; return { code: initScriptPromise ? initScriptPromise.code : null }; } handleInitScriptResult (data) { - var initScriptPromise = this.initScriptsQueue.shift(); + const initScriptPromise = this.initScriptsQueue.shift(); if (initScriptPromise) initScriptPromise.resolve(JSON.parse(data)); @@ -251,7 +302,9 @@ export default class BrowserConnection extends EventEmitter { } if (this.opened) { - var testRunUrl = await this._getTestRunUrl(isTestDone); + const testRunUrl = await this._getTestRunUrl(isTestDone || this.testRunAborted); + + this.testRunAborted = false; if (testRunUrl) { this.idle = false; diff --git a/src/runner/browser-job.js b/src/runner/browser-job.js index 2ce3ad0f..ae177f8e 100644 --- a/src/runner/browser-job.js +++ b/src/runner/browser-job.js @@ -33,7 +33,7 @@ export default class BrowserJob extends EventEmitter { } _createTestRunController (test, index) { - var testRunController = new TestRunController(test, index + 1, this.proxy, this.screenshots, this.warningLog, + const testRunController = new TestRunController(test, index + 1, this.proxy, this.screenshots, this.warningLog, this.fixtureHookController, this.opts); testRunController.on('test-run-start', () => this.emit('test-run-start', testRunController.testRun)); @@ -100,7 +100,7 @@ export default class BrowserJob extends EventEmitter { if (this.testRunControllerQueue[0].blocked) break; - var testRunController = this.testRunControllerQueue.shift(); + const testRunController = this.testRunControllerQueue.shift(); this._addToCompletionQueue(testRunController); @@ -109,7 +109,7 @@ export default class BrowserJob extends EventEmitter { this.emit('start'); } - var testRunUrl = await testRunController.start(connection); + const testRunUrl = await testRunController.start(connection); if (testRunUrl) return testRunUrl; diff --git a/src/runner/test-run-controller.js b/src/runner/test-run-controller.js index cff54d92..fd87e1ef 100644 --- a/src/runner/test-run-controller.js +++ b/src/runner/test-run-controller.js @@ -4,6 +4,7 @@ import TestRun from '../test-run'; import SessionController from '../test-run/session-controller'; const QUARANTINE_THRESHOLD = 3; +const DISCONNECT_THRESHOLD = 3; class Quarantine { constructor () { @@ -38,9 +39,10 @@ export default class TestRunController extends EventEmitter { this.TestRunCtor = TestRunController._getTestRunCtor(test, opts); - this.testRun = null; - this.done = false; - this.quarantine = null; + this.testRun = null; + this.done = false; + this.quarantine = null; + this.disconnectionCount = 0; if (this.opts.quarantineMode) this.quarantine = new Quarantine(); @@ -54,8 +56,8 @@ export default class TestRunController extends EventEmitter { } _createTestRun (connection) { - var screenshotCapturer = this.screenshots.createCapturerFor(this.test, this.index, this.quarantine, connection, this.warningLog); - var TestRunCtor = this.TestRunCtor; + const screenshotCapturer = this.screenshots.createCapturerFor(this.test, this.index, this.quarantine, connection, this.warningLog); + const TestRunCtor = this.TestRunCtor; this.testRun = new TestRunCtor(this.test, connection, screenshotCapturer, this.warningLog, this.opts); @@ -89,6 +91,10 @@ export default class TestRunController extends EventEmitter { } _keepInQuarantine () { + this._restartTest(); + } + + _restartTest () { this.emit('test-run-restart'); } @@ -116,6 +122,18 @@ export default class TestRunController extends EventEmitter { this.emit('test-run-done'); } + async _testRunDisconnected (connection) { + this.disconnectionCount++; + + if (this.disconnectionCount < DISCONNECT_THRESHOLD) { + connection.suppressError(); + + await connection.restartBrowser(); + + this._restartTest(); + } + } + get blocked () { return this.fixtureHookController.isTestBlocked(this.test); } @@ -133,6 +151,7 @@ export default class TestRunController extends EventEmitter { testRun.once('start', () => this.emit('test-run-start')); testRun.once('done', () => this._testRunDone()); + testRun.once('disconnected', () => this._testRunDisconnected(connection)); testRun.start(); diff --git a/src/test-run/index.js b/src/test-run/index.js index dd80d74d..d94c8bea 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -235,7 +235,7 @@ export default class TestRun extends EventEmitter { await fn(this); } catch (err) { - var screenshotPath = null; + let screenshotPath = null; if (this.opts.takeScreenshotsOnFails) screenshotPath = await this.executeCommand(new TakeScreenshotOnFailCommand()); @@ -272,15 +272,25 @@ export default class TestRun extends EventEmitter { this.emit('start'); + const onDisconnected = err => this._disconnect(err); + + this.browserConnection.once('disconnected', onDisconnected); + if (await this._runBeforeHook()) { await this._executeTestFn(PHASE.inTest, this.test.fn); await this._runAfterHook(); } + if (this.disconnected) + return; + + this.browserConnection.removeListener('disconnected', onDisconnected); + if (this.errs.length && this.debugOnFail) await this._enqueueSetBreakpointCommand(null, this.debugReporterPluginHost.formatError(this.errs[0])); await this.executeCommand(new TestDoneCommand()); + this._addPendingPageErrorIfAny(); delete testRunTracker.activeTestRuns[this.session.id]; @@ -309,10 +319,10 @@ export default class TestRun extends EventEmitter { } addError (err, screenshotPath) { - var errList = err instanceof TestCafeErrorList ? err.items : [err]; + const errList = err instanceof TestCafeErrorList ? err.items : [err]; errList.forEach(item => { - var adapter = new TestRunErrorFormattableAdapter(item, { + const adapter = new TestRunErrorFormattableAdapter(item, { userAgent: this.browserConnection.userAgent, screenshotPath: screenshotPath || '', testRunPhase: this.phase @@ -372,7 +382,7 @@ export default class TestRun extends EventEmitter { } _rejectCurrentDriverTask (err) { - err.callsite = err.callsite || this.driverTaskQueue[0].callsite; + err.callsite = err.callsite || this.currentDriverTask.callsite; err.isRejectedDriverTask = true; this.currentDriverTask.reject(err); @@ -415,14 +425,17 @@ export default class TestRun extends EventEmitter { } _handleDriverRequest (driverStatus) { - var pageError = this.pendingPageError || driverStatus.pageError; + const isTestDone = this.currentDriverTask && this.currentDriverTask.command.type === COMMAND_TYPE.testDone; + const pageError = this.pendingPageError || driverStatus.pageError; + const currentTaskRejectedByError = pageError && this._handlePageErrorStatus(pageError); - var currentTaskRejectedByError = pageError && this._handlePageErrorStatus(pageError); + if (this.disconnected) + return new Promise((_, reject) => reject()); this.consoleMessages.concat(driverStatus.consoleMessages); if (!currentTaskRejectedByError && driverStatus.isCommandResult) { - if (this.currentDriverTask.command.type === COMMAND_TYPE.testDone) { + if (isTestDone) { this._resolveCurrentDriverTask(); return TEST_DONE_CONFIRMATION_RESPONSE; @@ -453,7 +466,9 @@ export default class TestRun extends EventEmitter { } async _executeExpression (command) { - var { expression, resultVariableName, isAsyncExpression } = command; + const { resultVariableName, isAsyncExpression } = command; + + let expression = command.expression; if (isAsyncExpression) expression = `await ${expression}`; @@ -464,14 +479,14 @@ export default class TestRun extends EventEmitter { if (isAsyncExpression) expression = `(async () => { return ${expression}; }).apply(this);`; - var result = this._evaluate(expression); + const result = this._evaluate(expression); return isAsyncExpression ? await result : result; } async _executeAssertion (command, callsite) { - var assertionTimeout = command.options.timeout === void 0 ? this.opts.assertionTimeout : command.options.timeout; - var executor = new AssertionExecutor(command, assertionTimeout, callsite); + const assertionTimeout = command.options.timeout === void 0 ? this.opts.assertionTimeout : command.options.timeout; + const executor = new AssertionExecutor(command, assertionTimeout, callsite); executor.once('start-assertion-retries', timeout => this.executeCommand(new ShowAssertionRetriesStatusCommand(timeout))); executor.once('end-assertion-retries', success => this.executeCommand(new HideAssertionRetriesStatusCommand(success))); @@ -561,7 +576,7 @@ export default class TestRun extends EventEmitter { } _rejectCommandWithPageError (callsite) { - var err = this.pendingPageError; + const err = this.pendingPageError; err.callsite = callsite; this.pendingPageError = null; @@ -571,7 +586,7 @@ export default class TestRun extends EventEmitter { // Role management async getStateSnapshot () { - var state = this.session.getStateSnapshot(); + const state = this.session.getStateSnapshot(); state.storages = await this.executeCommand(new BackupStoragesCommand()); @@ -586,26 +601,26 @@ export default class TestRun extends EventEmitter { this.session.useStateSnapshot(null); if (this.activeDialogHandler) { - var removeDialogHandlerCommand = new SetNativeDialogHandlerCommand({ dialogHandler: { fn: null } }); + const removeDialogHandlerCommand = new SetNativeDialogHandlerCommand({ dialogHandler: { fn: null } }); await this.executeCommand(removeDialogHandlerCommand); } if (this.speed !== this.opts.speed) { - var setSpeedCommand = new SetTestSpeedCommand({ speed: this.opts.speed }); + const setSpeedCommand = new SetTestSpeedCommand({ speed: this.opts.speed }); await this.executeCommand(setSpeedCommand); } if (this.pageLoadTimeout !== this.opts.pageLoadTimeout) { - var setPageLoadTimeoutCommand = new SetPageLoadTimeoutCommand({ duration: this.opts.pageLoadTimeout }); + const setPageLoadTimeoutCommand = new SetPageLoadTimeoutCommand({ duration: this.opts.pageLoadTimeout }); await this.executeCommand(setPageLoadTimeoutCommand); } } async _getStateSnapshotFromRole (role) { - var prevPhase = this.phase; + const prevPhase = this.phase; this.phase = PHASE.inRoleInitializer; @@ -629,14 +644,14 @@ export default class TestRun extends EventEmitter { this.disableDebugBreakpoints = true; - var bookmark = new TestRunBookmark(this, role); + const bookmark = new TestRunBookmark(this, role); await bookmark.init(); if (this.currentRoleId) this.usedRoleStates[this.currentRoleId] = await this.getStateSnapshot(); - var stateSnapshot = this.usedRoleStates[role.id] || await this._getStateSnapshotFromRole(role); + const stateSnapshot = this.usedRoleStates[role.id] || await this._getStateSnapshotFromRole(role); this.session.useStateSnapshot(stateSnapshot); @@ -649,20 +664,30 @@ export default class TestRun extends EventEmitter { // Get current URL async getCurrentUrl () { - var builder = new ClientFunctionBuilder(() => { + const builder = new ClientFunctionBuilder(() => { /* eslint-disable no-undef */ return window.location.href; /* eslint-enable no-undef */ }, { boundTestRun: this }); - var getLocation = builder.getFunction(); + const getLocation = builder.getFunction(); return await getLocation(); } + + _disconnect (err) { + this.disconnected = true; + + this._rejectCurrentDriverTask(err); + + this.emit('disconnected', err); + + delete testRunTracker.activeTestRuns[this.session.id]; + } } // Service message handlers -var ServiceMessages = TestRun.prototype; +const ServiceMessages = TestRun.prototype; ServiceMessages[CLIENT_MESSAGES.ready] = function (msg) { this.debugLog.driverMessage(msg); @@ -682,7 +707,7 @@ ServiceMessages[CLIENT_MESSAGES.ready] = function (msg) { // NOTE: browsers abort an opened xhr request after a certain timeout (the actual duration depends on the browser). // To avoid this, we send an empty response after 2 minutes if we didn't get any command. - var responseTimeout = setTimeout(() => this._resolvePendingRequest(null), MAX_RESPONSE_DELAY); + const responseTimeout = setTimeout(() => this._resolvePendingRequest(null), MAX_RESPONSE_DELAY); return new Promise((resolve, reject) => { this.pendingRequest = { resolve, reject, responseTimeout }; @@ -692,8 +717,8 @@ ServiceMessages[CLIENT_MESSAGES.ready] = function (msg) { ServiceMessages[CLIENT_MESSAGES.readyForBrowserManipulation] = async function (msg) { this.debugLog.driverMessage(msg); - var result = null; - var error = null; + let result = null; + let error = null; try { result = await this.browserManipulationQueue.executePendingManipulation(msg); diff --git a/test/functional/fixtures/browser-provider/browser-reconnect/pages/index.html b/test/functional/fixtures/browser-provider/browser-reconnect/pages/index.html new file mode 100644 index 00000000..25a82555 --- /dev/null +++ b/test/functional/fixtures/browser-provider/browser-reconnect/pages/index.html @@ -0,0 +1,9 @@ + + + + + Title + + + + diff --git a/test/functional/fixtures/browser-provider/browser-reconnect/test.js b/test/functional/fixtures/browser-provider/browser-reconnect/test.js new file mode 100644 index 00000000..bafc8675 --- /dev/null +++ b/test/functional/fixtures/browser-provider/browser-reconnect/test.js @@ -0,0 +1,72 @@ +const path = require('path'); +const Promise = require('pinkie'); +const expect = require('chai').expect; +const config = require('../../../config'); +const browserProviderPool = require('../../../../../lib/browser/provider/pool'); +const BrowserConnection = require('../../../../../lib/browser/connection'); + +let errors = null; + +function customReporter () { + return { + reportTestDone (name, testRunInfo) { + errors = testRunInfo.errs; + }, + reportFixtureStart () { + }, + reportTaskStart () { + }, + reportTaskDone () { + } + }; +} + +function createConnection (browser) { + return browserProviderPool + .getBrowserInfo(browser) + .then(browserInfo => new BrowserConnection(testCafe.browserConnectionGateway, browserInfo, false)); +} + +async function run (pathToTest, filter) { + const src = path.join(__dirname, pathToTest); + const browserNames = config.currentEnvironment.browsers.map(browser => browser.browserName || browser.alias); + + return Promise.all(browserNames.map(browser => createConnection(browser))) + .then(connections => { + connections.forEach(connection => { + connection.HEARTBEAT_TIMEOUT = 4000; + }); + + return connections; + }) + .then(connection => { + return testCafe + .createRunner() + .src(src) + .filter(testName => testName === filter) + .reporter(customReporter) + .browsers(connection) + .run(); + }); +} + +describe('Browser reconnect', function () { + if (config.useLocalBrowsers) { + it('Should restart browser when it does not respond', function () { + return run('./testcafe-fixtures/index-test.js', 'Should restart browser when it does not respond') + .then(() => { + expect(errors.length).eql(0); + }); + }); + + it('Should fail on 3 disconnects in one browser', function () { + return run('./testcafe-fixtures/index-test.js', 'Should fail on 3 disconnects in one browser') + .then(() => { + throw new Error('Test should have failed but it succeeded'); + }) + .catch(err => { + expect(err.message).contains('browser disconnected. This problem may appear when a browser hangs or is closed, or due to network issues'); + }); + }); + } +}); diff --git a/test/functional/fixtures/browser-provider/browser-reconnect/testcafe-fixtures/index-test.js b/test/functional/fixtures/browser-provider/browser-reconnect/testcafe-fixtures/index-test.js new file mode 100644 index 00000000..6d003f09 --- /dev/null +++ b/test/functional/fixtures/browser-provider/browser-reconnect/testcafe-fixtures/index-test.js @@ -0,0 +1,48 @@ +import { ClientFunction } from 'testcafe'; + +fixture `Browser reconnect` + .page `http://localhost:3000/fixtures/browser-provider/browser-reconnect/pages/index.html`; + +const counter = {}; +const getUserAgent = ClientFunction(() => navigator.userAgent.toString()); +let ctx = null; + +const hang = ClientFunction(() => { + const now = Date.now(); + + while (Date.now() < now + 10000) { + // hang for 10s + } +}); + +test('Should restart browser when it does not respond', async t => { + const userAgent = await getUserAgent(); + + counter[userAgent] = counter[userAgent] || 0; + + counter[userAgent]++; + + if (counter[userAgent] < 3) + await hang(); + + await t.expect(counter[userAgent]).eql(3); +}); + +test('Should fail on 3 disconnects in one browser', async t => { + const userAgent = await getUserAgent(); + + counter[userAgent] = counter[userAgent] || 0; + + counter[userAgent]++; + + ctx = ctx || userAgent; + + if (ctx === userAgent) { + await hang(); + + throw new Error('browser has not restarted'); + } + + await t.expect(counter[userAgent]).eql(1); +}); + diff --git a/test/server/browser-connection-test.js b/test/server/browser-connection-test.js index 176ee8d3..515e3de3 100644 --- a/test/server/browser-connection-test.js +++ b/test/server/browser-connection-test.js @@ -132,6 +132,10 @@ describe('Browser connection', function () { once: function () { // Do nothing =) + }, + + on: function () { + // Do nothing } }; } From ddc02041645496d052bfe818582b6b4912c88b44 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Tue, 11 Sep 2018 19:20:07 +0300 Subject: [PATCH 093/184] Bump version (v0.22.1-alpha.1) (#2847) --- .publishrc | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.publishrc b/.publishrc index 5727c783..2414a453 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "latest", + "publishTag": "alpha", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index adf9dc87..94e603dd 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.22.0", + "version": "0.22.1-alpha.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From 158695b099dce51a0495b2c269449a72eb701672 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Fri, 14 Sep 2018 12:40:07 +0300 Subject: [PATCH 094/184] fix 'incorrect screenshot path in report output ' (close #2726) (#2853) * fix 'incorrect screenshot path in report output ' (close #2726) * fix tests - 1 * fix test * fix tests 3 * remove globby --- package.json | 1 + src/client/automation/playback/rclick.js | 19 +++++------ src/client/automation/utils/get-key-code.js | 3 +- .../utils/get-line-rect-intersection.js | 14 ++++---- src/client/automation/utils/next-tick.js | 6 ++-- src/screenshots/capturer.js | 17 ---------- src/screenshots/index.js | 7 ++-- src/screenshots/path-pattern.js | 6 ---- src/utils/get-common-path.js | 25 ++++++++++++++ .../api/es-next/take-screenshot/test.js | 14 +++++--- .../fixtures/api/legacy/smoke/test.js | 34 +++++++++---------- test/server/util-test.js | 13 +++++++ 12 files changed, 88 insertions(+), 71 deletions(-) create mode 100644 src/utils/get-common-path.js diff --git a/package.json b/package.json index 94e603dd..78c06c58 100644 --- a/package.json +++ b/package.json @@ -131,6 +131,7 @@ "broken-link-checker": "^0.7.0", "browserstack-connector": "^0.1.5", "caller": "^1.0.1", + "chai-string": "^1.5.0", "connect": "^3.4.0", "cross-spawn": "^4.0.0", "dom-walk": "^0.1.1", diff --git a/src/client/automation/playback/rclick.js b/src/client/automation/playback/rclick.js index f779e229..f11bf46e 100644 --- a/src/client/automation/playback/rclick.js +++ b/src/client/automation/playback/rclick.js @@ -5,16 +5,13 @@ import { focusAndSetSelection, focusByRelatedElement } from '../utils/utils'; import cursor from '../cursor'; import nextTick from '../utils/next-tick'; -var Promise = hammerhead.Promise; +const Promise = hammerhead.Promise; -var extend = hammerhead.utils.extend; -var browserUtils = hammerhead.utils.browser; -var eventSimulator = hammerhead.eventSandbox.eventSimulator; - -var domUtils = testCafeCore.domUtils; -var eventUtils = testCafeCore.eventUtils; -var delay = testCafeCore.delay; +const extend = hammerhead.utils.extend; +const browserUtils = hammerhead.utils.browser; +const eventSimulator = hammerhead.eventSandbox.eventSimulator; +const { domUtils, eventUtils, delay } = testCafeCore; export default class RClickAutomation extends VisibleElementAutomation { constructor (element, clickOptions) { @@ -46,10 +43,10 @@ export default class RClickAutomation extends VisibleElementAutomation { // NOTE: If a target element is a contentEditable element, we need to call focusAndSetSelection directly for // this element. Otherwise, if the element obtained by elementFromPoint is a child of the contentEditable // element, a selection position may be calculated incorrectly (by using the caretPos option). - var elementForFocus = domUtils.isContentEditableElement(this.element) ? this.element : eventArgs.element; + const elementForFocus = domUtils.isContentEditableElement(this.element) ? this.element : eventArgs.element; // NOTE: IE doesn't perform focus if active element has been changed while executing mousedown - var simulateFocus = !browserUtils.isIE || this.eventState.activeElementBeforeMouseDown === domUtils.getActiveElement(); + const simulateFocus = !browserUtils.isIE || this.eventState.activeElementBeforeMouseDown === domUtils.getActiveElement(); return focusAndSetSelection(elementForFocus, simulateFocus, this.caretPos) .then(() => nextTick()); @@ -74,7 +71,7 @@ export default class RClickAutomation extends VisibleElementAutomation { } run (useStrictElementCheck) { - var eventArgs = null; + let eventArgs = null; return this ._ensureElement(useStrictElementCheck) diff --git a/src/client/automation/utils/get-key-code.js b/src/client/automation/utils/get-key-code.js index dddb2ce4..6baf48d8 100644 --- a/src/client/automation/utils/get-key-code.js +++ b/src/client/automation/utils/get-key-code.js @@ -1,12 +1,11 @@ import { KEY_MAPS } from '../deps/testcafe-core'; import isLetter from './is-letter'; - export default function (char) { if (isLetter(char)) return char.toUpperCase().charCodeAt(0); - var res = KEY_MAPS.shiftMap[char] ? KEY_MAPS.shiftMap[char].charCodeAt(0) : char.charCodeAt(0); + const res = KEY_MAPS.shiftMap[char] ? KEY_MAPS.shiftMap[char].charCodeAt(0) : char.charCodeAt(0); return KEY_MAPS.symbolCharCodeToKeyCode[res] || res; } diff --git a/src/client/automation/utils/get-line-rect-intersection.js b/src/client/automation/utils/get-line-rect-intersection.js index a79b1457..5a48ce24 100644 --- a/src/client/automation/utils/get-line-rect-intersection.js +++ b/src/client/automation/utils/get-line-rect-intersection.js @@ -6,8 +6,8 @@ function getPointsDistance (start, end) { } function findLineAndRectSideIntersection (startLinePoint, endLinePoint, rectSide) { - var intersectionX = null; - var haveIntersectionInBounds = null; + let intersectionX = null; + let haveIntersectionInBounds = null; if (rectSide.isHorizontal) { intersectionX = positionUtils.getLineXByYCoord(startLinePoint, endLinePoint, rectSide.y1); @@ -16,7 +16,7 @@ function findLineAndRectSideIntersection (startLinePoint, endLinePoint, rectSide return haveIntersectionInBounds ? { x: intersectionX, y: rectSide.y1 } : null; } - var intersectionY = positionUtils.getLineYByXCoord(startLinePoint, endLinePoint, rectSide.x1); + const intersectionY = positionUtils.getLineYByXCoord(startLinePoint, endLinePoint, rectSide.x1); haveIntersectionInBounds = intersectionY && intersectionY >= rectSide.y1 && intersectionY <= rectSide.y2; @@ -24,17 +24,17 @@ function findLineAndRectSideIntersection (startLinePoint, endLinePoint, rectSide } export default function (startLinePoint, endLinePoint, rect) { - var res = []; - var intersection = null; + const res = []; + let intersection = null; - var rectLines = [ + const rectLines = [ { x1: rect.left, y1: rect.top, x2: rect.left, y2: rect.bottom, isHorizontal: false }, // left-side { x1: rect.right, y1: rect.top, x2: rect.right, y2: rect.bottom, isHorizontal: false }, // right-side { x1: rect.left, y1: rect.top, x2: rect.right, y2: rect.top, isHorizontal: true }, // top-side { x1: rect.left, y1: rect.bottom, x2: rect.right, y2: rect.bottom, isHorizontal: true } // bottom-side ]; - for (var i = 0; i < rectLines.length; i++) { + for (let i = 0; i < rectLines.length; i++) { intersection = findLineAndRectSideIntersection(startLinePoint, endLinePoint, rectLines[i]); if (intersection) diff --git a/src/client/automation/utils/next-tick.js b/src/client/automation/utils/next-tick.js index bc21cfea..369d7908 100644 --- a/src/client/automation/utils/next-tick.js +++ b/src/client/automation/utils/next-tick.js @@ -1,9 +1,9 @@ import hammerhead from '../deps/hammerhead'; -var Promise = hammerhead.Promise; -var nativeMethods = hammerhead.nativeMethods; - +const Promise = hammerhead.Promise; +const nativeMethods = hammerhead.nativeMethods; export default function () { return new Promise(resolve => nativeMethods.setTimeout.call(window, resolve, 0)); } + diff --git a/src/screenshots/capturer.js b/src/screenshots/capturer.js index 9adc6799..cd8c9756 100644 --- a/src/screenshots/capturer.js +++ b/src/screenshots/capturer.js @@ -59,21 +59,6 @@ export default class Capturer { return joinPath(this.baseScreenshotsPath, path); } - _updateScreenshotPathForTestEntry (customPath) { - // NOTE: if test contains takeScreenshot action with custom path - // we should specify the most common screenshot folder in report - let screenshotPathForTestEntry = this.baseScreenshotsPath; - - if (!customPath) { - const pathForReport = this.pathPattern.getPathForReport(); - - screenshotPathForTestEntry = this._joinWithBaseScreenshotPath(pathForReport); - } - - - this.testEntry.path = screenshotPathForTestEntry; - } - _incrementFileIndexes (forError) { if (forError) this.pathPattern.data.errorFileIndex++; @@ -126,8 +111,6 @@ export default class Capturer { await generateThumbnail(screenshotPath, thumbnailPath); }); - this._updateScreenshotPathForTestEntry(customPath); - const screenshot = { screenshotPath, thumbnailPath, diff --git a/src/screenshots/index.js b/src/screenshots/index.js index df6f5cf2..c59bf18c 100644 --- a/src/screenshots/index.js +++ b/src/screenshots/index.js @@ -2,6 +2,7 @@ import { find } from 'lodash'; import moment from 'moment'; import Capturer from './capturer'; import PathPattern from './path-pattern'; +import getCommonPath from '../utils/get-common-path'; export default class Screenshots { constructor (path, pattern) { @@ -15,7 +16,6 @@ export default class Screenshots { _addTestEntry (test) { const testEntry = { test: test, - path: this.screenshotsPath || '', screenshots: [] }; @@ -46,7 +46,10 @@ export default class Screenshots { } getPathFor (test) { - return this._getTestEntry(test).path; + const testEntry = this._getTestEntry(test); + const screenshotPaths = testEntry.screenshots.map(screenshot => screenshot.screenshotPath); + + return getCommonPath(screenshotPaths); } createCapturerFor (test, testIndex, quarantine, connection, warningLog) { diff --git a/src/screenshots/path-pattern.js b/src/screenshots/path-pattern.js index 59bc880b..51c1f6e1 100644 --- a/src/screenshots/path-pattern.js +++ b/src/screenshots/path-pattern.js @@ -106,12 +106,6 @@ export default class PathPattern { return correctFilePath(path, SCRENSHOT_EXTENTION); } - getPathForReport () { - const path = PathPattern._buildPath(DEFAULT_PATH_PATTERN_FOR_REPORT, this.placeholderToDataMap); - - return correctFilePath(path); - } - // For testing purposes static get PLACEHOLDERS () { return PLACEHOLDERS; diff --git a/src/utils/get-common-path.js b/src/utils/get-common-path.js new file mode 100644 index 00000000..8bc5deb4 --- /dev/null +++ b/src/utils/get-common-path.js @@ -0,0 +1,25 @@ +import path from 'path'; + +export default function (paths) { + if (!paths) + return null; + + if (paths.length === 1) + return paths[0]; + + const pathArrs = paths.map(item => item.split(path.sep)); + const isCommonPathFragment = (pathFragment, idx) => pathArrs.every(pathArray => pathArray[idx] === pathFragment); + const firstPathArr = pathArrs[0]; + let commonPathFramgemtnIndex = 0; + + while (commonPathFramgemtnIndex < firstPathArr.length && + isCommonPathFragment(firstPathArr[commonPathFramgemtnIndex], commonPathFramgemtnIndex)) + commonPathFramgemtnIndex++; + + if (!commonPathFramgemtnIndex) + return null; + + const commonPathFragments = firstPathArr.slice(0, commonPathFramgemtnIndex); + + return path.join(...commonPathFragments); +} diff --git a/test/functional/fixtures/api/es-next/take-screenshot/test.js b/test/functional/fixtures/api/es-next/take-screenshot/test.js index b5a0cd33..a1cfb8b8 100644 --- a/test/functional/fixtures/api/es-next/take-screenshot/test.js +++ b/test/functional/fixtures/api/es-next/take-screenshot/test.js @@ -1,16 +1,19 @@ const path = require('path'); const fs = require('fs'); -const expect = require('chai').expect; +const chai = require('chai'); +const { expect } = chai; const config = require('../../../../config.js'); const assertionHelper = require('../../../../assertion-helper.js'); +chai.use(require('chai-string')); + const SCREENSHOTS_PATH = assertionHelper.SCREENSHOTS_PATH; const THUMBNAILS_DIR_NAME = assertionHelper.THUMBNAILS_DIR_NAME; -const SCREENSHOT_PATH_MESSAGE_RE = /^___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1$/; +const SCREENSHOT_PATH_MESSAGE_RE = /^___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1/; const SCREENSHOT_ON_FAIL_PATH_MESSAGE_RE = /^.*run-1/; const SLASH_RE = /[\\/]/g; -var getReporter = function (scope) { +const getReporter = function (scope) { const userAgents = { }; function patchScreenshotPath (screenshotPath) { @@ -60,7 +63,8 @@ describe('[API] t.takeScreenshot()', function () { return runTests('./testcafe-fixtures/take-screenshot.js', 'Take a screenshot with a custom path (OS separator)', { setScreenshotPath: true }) .then(function () { - expect(testReport.screenshotPath).eql(SCREENSHOTS_PATH); + + expect(testReport.screenshotPath).startsWith(path.join(SCREENSHOTS_PATH, 'custom')); const screenshotsCheckingOptions = { forError: false, screenshotsCount: 2, customPath: 'custom' }; @@ -214,7 +218,7 @@ describe('[API] t.takeScreenshot()', function () { only: 'chrome' }) .then(() => { - expect(SCREENSHOT_PATH_MESSAGE_RE.test(testReport.screenshotPath)).eql(true); + expect(testReport.screenshotPath).eql(SCREENSHOTS_PATH); const screenshot1Path = path.join(assertionHelper.SCREENSHOTS_PATH, 'Take a screenshot-1.png'); const screenshot2Path = path.join(assertionHelper.SCREENSHOTS_PATH, 'Take a screenshot-2.png'); diff --git a/test/functional/fixtures/api/legacy/smoke/test.js b/test/functional/fixtures/api/legacy/smoke/test.js index 748bb8a3..a9f9e5ee 100644 --- a/test/functional/fixtures/api/legacy/smoke/test.js +++ b/test/functional/fixtures/api/legacy/smoke/test.js @@ -1,41 +1,39 @@ -var expect = require('chai').expect; -var globby = require('globby').sync; -var path = require('path'); -var config = require('../../../../config'); -var assertionHelper = require('../../../../assertion-helper'); +const { expect } = require('chai'); +const path = require('path'); +const config = require('../../../../config'); +const assertionHelper = require('../../../../assertion-helper'); +const SCREENSHOT_PATH_MESSAGE_RE = /^___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1/; +const ERROR_SCREENSHOT_PATH_RE = /Screenshot: ___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1[\\/]\S+[\\/]errors[\\/]\d.png/; -var SCREENSHOT_PATH_MESSAGE_RE = /^___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1$/; -var ERROR_SCREENSHOT_PATH_RE = /Screenshot: ___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1[\\/]\S+[\\/]errors[\\/]\d.png/; - -describe('[Legacy] Smoke tests', function () { - it('Should run basic tests', function () { - return runTests(globby(path.join(__dirname, './testcafe-fixtures/basic/*test.js')), null, { skip: 'iphone,ipad' }); +describe('[Legacy] Smoke tests', () => { + it('Should run basic tests', () => { + return runTests(path.join(__dirname, './testcafe-fixtures/basic/*test.js'), null, { skip: 'iphone,ipad' }); }); - it('Should fail on errors', function () { + it('Should fail on errors', () => { return runTests('./testcafe-fixtures/errors.test.js', null, { shouldFail: true, skip: 'iphone,ipad' }) - .catch(function (errs) { + .catch(errs => { expect(errs[0]).contains('A target element of the click action has not been found in the DOM tree.'); }); }); if (config.useLocalBrowsers) { - describe('Screenshots', function () { + describe('Screenshots', () => { afterEach(assertionHelper.removeScreenshotDir); - it('Should take a screenshot', function () { + it('Should take a screenshot', () => { return runTests('./testcafe-fixtures/screenshots.test.js', 'Take a screenshot', { setScreenshotPath: true }) - .then(function () { + .then(() => { expect(SCREENSHOT_PATH_MESSAGE_RE.test(testReport.screenshotPath)).eql(true); expect(assertionHelper.checkScreenshotsCreated({ forError: false, screenshotsCount: 2 })).eql(true); }); }); - it('Should take a screenshot if an error in test code is raised', function () { + it('Should take a screenshot if an error in test code is raised', () => { return runTests('./testcafe-fixtures/screenshots.test.js', 'Screenshot on test code error', { shouldFail: true, screenshotsOnFails: true, setScreenshotPath: true }) - .catch(function (errs) { + .catch(errs => { assertionHelper.errorInEachBrowserContainsRegExp(errs, ERROR_SCREENSHOT_PATH_RE, 0); expect(assertionHelper.checkScreenshotsCreated({ forError: true })).eql(true); }); diff --git a/test/server/util-test.js b/test/server/util-test.js index aec2ebd7..1c57f842 100644 --- a/test/server/util-test.js +++ b/test/server/util-test.js @@ -7,6 +7,7 @@ const escapeUserAgent = require('../../lib/utils/escape-user-ag const parseFileList = require('../../lib/utils/parse-file-list'); const TempDirectory = require('../../lib/utils/temp-directory'); const { replaceLeadingSpacesWithNbsp } = require('../../lib/utils/string'); +const getCommonPath = require('../../lib/utils/get-common-path'); describe('Utils', () => { it('Correct File Path', () => { @@ -128,4 +129,16 @@ describe('Utils', () => { expect(replaceLeadingSpacesWithNbsp(' test1 test2 ')).eql(' test1 test2 '); expect(replaceLeadingSpacesWithNbsp(' test1\n test2 \r\ntest3 ')).eql('  test1\n test2 \r\ntest3 '); }); + + it('Get common path', () => { + const pathFragemts = [ 'home', 'user1', 'tmp' ]; + const path1 = path.join(...pathFragemts); + const path2 = path.join(pathFragemts[0], pathFragemts[1]); + const path3 = path.join(pathFragemts[0], pathFragemts[2]); + + expect(getCommonPath([path1])).eql(path1); + expect(getCommonPath([path1, path1])).eql(path1); + expect(getCommonPath([path1, path2])).eql(path2); + expect(getCommonPath([path1, path2, path3])).eql(pathFragemts[0]); + }); }); From 45c02c42199a8bf1af3e4f123d6b19566954a299 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Mon, 17 Sep 2018 12:50:22 +0300 Subject: [PATCH 095/184] update chai (#2866) --- package.json | 2 +- test/server/create-testcafe-test.js | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 78c06c58..17317161 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "bin-v8-flags-filter": "^1.1.2", "callsite": "^1.0.0", "callsite-record": "^4.0.0", - "chai": "^3.0.0", + "chai": "^4.1.2", "chalk": "^1.1.0", "chrome-emulated-devices-list": "^0.1.0", "chrome-remote-interface": "^0.25.3", diff --git a/test/server/create-testcafe-test.js b/test/server/create-testcafe-test.js index a644b167..812e4634 100644 --- a/test/server/create-testcafe-test.js +++ b/test/server/create-testcafe-test.js @@ -87,9 +87,8 @@ describe('TestCafe factory function', function () { }); }); - it('Should contain plugin testing, embedding utils and common runtime functions', function () { - expect(createTestCafe.pluginTestingUtils).to.be.an.object; - expect(createTestCafe.embeddingUtils).to.be.an.object; + it('Should contain embedding utils and common runtime functions', function () { + expect(createTestCafe.embeddingUtils).to.be.an('object'); expect(createTestCafe.Role).eql(exportableLib.Role); expect(createTestCafe.ClientFunction).eql(exportableLib.ClientFunction); }); From 9e1fb654e55db8a284e718f3264cf7431d240f4d Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Mon, 17 Sep 2018 13:04:01 +0300 Subject: [PATCH 096/184] [docs] Add details to the quarantine mode description (#2771) * Add details to the quarantine mode description * Address Miher's remarks * Address Margarita's remark * Update runner.md * Apply Dirk's corrections --- .../using-testcafe/programming-interface/runner.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index 388686b3..45c2a40e 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -467,16 +467,22 @@ You can also cancel all pending tasks at once using the [runner.stop](#stop) fun #### Quarantine Mode -The quarantine mode is designed to isolate *non-deterministic* tests (that is, tests that sometimes pass and fail without any apparent reason) -from the rest of the test base (*healthy* tests). +The quarantine mode is designed to isolate *non-deterministic* tests (that is, tests that pass and fail without any apparent reason) from the other tests. -In this mode, a failed test is executed several times. The test result depends on the outcome (passed or failed) that occurs most often. That is, if the test fails on most attempts, the result is failed. If the test result differs between test runs, the test is marked as unstable. +When the quarantine mode is enabled, tests run according to the following logic: + +1. A test runs at the first time. If it passes, TestCafe proceeds to the next test. +2. If the test fails, it runs again until it passes or fails three times. +3. The most frequent outcome is recorded as the test result. +4. If the test result differs between test runs, the test is marked as unstable. + +> Note that it increases the test task's duration if you enable quarantine mode on your test machine because failed tests are executed three to five times. See Martin Fowler's [Eradicating Non-Determinism in Tests](http://martinfowler.com/articles/nonDeterminism.html) article for more information about non-deterministic tests. ### stop -Stops all pending test tasks. +Stops all the pending test tasks. ```text async stop() From f22ed6083ea8bd4e1461582e8b98a01a3e700946 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Mon, 17 Sep 2018 14:31:36 +0300 Subject: [PATCH 097/184] Implement unstable network mode (closes #2727) (#2824) --- .travis.yml | 11 ++- Gulpfile.js | 9 ++- src/browser/connection/gateway.js | 4 +- src/browser/connection/index.js | 9 +-- src/browser/connection/remotes-queue.js | 6 +- .../connection/unstable-network-mode.js | 1 + .../browser/idle-page/index.html.mustache | 2 +- src/client/browser/idle-page/index.js | 5 +- src/client/browser/index.js | 70 ++++++++++++++++--- src/client/core/index.js | 2 + .../core/utils/get-time-limited-promise.js | 8 +++ .../command-executors/execute-navigate-to.js | 23 +++--- src/client/driver/driver.js | 38 ++++++++-- src/client/test-run/iframe.js.mustache | 9 +-- src/client/test-run/index.js.mustache | 2 + src/errors/runtime/message.js | 9 ++- src/index.js | 5 +- src/runner/browser-set.js | 4 +- src/runner/index.js | 3 +- src/test-run/index.js | 8 +++ src/test-run/session-controller.js | 13 ++++ src/testcafe.js | 8 ++- .../temp-directory/cleanup-process/index.js | 24 +++++-- test/functional/config.js | 20 +++++- .../hooks/testcafe-fixtures/fixture-hooks.js | 4 +- .../api/add-remove-request-hook.js | 23 +++--- .../testcafe-fixtures/request-logger/api.js | 5 +- .../fixtures/api/legacy/smoke/test.js | 26 +++---- test/functional/setup.js | 6 +- test/functional/site/server.js | 3 + 30 files changed, 266 insertions(+), 94 deletions(-) create mode 100644 src/browser/connection/unstable-network-mode.js create mode 100644 src/client/core/utils/get-time-limited-promise.js diff --git a/.travis.yml b/.travis.yml index 64364c82..f2a9083b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,14 +24,11 @@ matrix: env: GULP_TASK="test-functional-local-headless" fast_finish: true -cache: yarn +cache: + directories: + - $HOME/.npm -before_install: - - export $(dbus-launch) - - curl -o- -L https://yarnpkg.com/install.sh | bash - - export PATH=$HOME/.yarn/bin:$PATH - -install: yarn +install: travis_retry npm install branches: except: diff --git a/Gulpfile.js b/Gulpfile.js index e2821c8f..d1845d4b 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -619,15 +619,18 @@ gulp.task('test-docs-travis', gulp.parallel('test-website-travis', 'lint')); function testFunctional (fixturesDir, testingEnvironmentName, browserProviderName) { - process.env.TESTING_ENVIRONMENT = testingEnvironmentName; - process.env.BROWSER_PROVIDER = browserProviderName; + process.env.TESTING_ENVIRONMENT = testingEnvironmentName; + process.env.BROWSER_PROVIDER = browserProviderName; + + if (DEV_MODE) + process.env.DEV_MODE = 'true'; return gulp .src(['test/functional/setup.js', fixturesDir + '/**/test.js']) .pipe(mocha({ ui: 'bdd', reporter: 'spec', - timeout: typeof v8debug === 'undefined' ? 180000 : Infinity // NOTE: disable timeouts in debug + timeout: typeof v8debug === 'undefined' ? 3 * 60 * 1000 : Infinity // NOTE: disable timeouts in debug })); } diff --git a/src/browser/connection/gateway.js b/src/browser/connection/gateway.js index a3055fdc..443fc806 100644 --- a/src/browser/connection/gateway.js +++ b/src/browser/connection/gateway.js @@ -10,13 +10,15 @@ const IDLE_PAGE_LOGO = read('../../client/browser/idle-page/logo.svg', true); // Gateway export default class BrowserConnectionGateway { - constructor (proxy) { + constructor (proxy, options = {}) { this.connections = {}; this.remotesQueue = new RemotesQueue(); this.domain = proxy.server1Info.domain; this.connectUrl = `${this.domain}/browser/connect`; + this.retryTestPages = options.retryTestPages; + this._registerRoutes(proxy); } diff --git a/src/browser/connection/index.js b/src/browser/connection/index.js index 224d5000..1e05f153 100644 --- a/src/browser/connection/index.js +++ b/src/browser/connection/index.js @@ -271,10 +271,11 @@ export default class BrowserConnection extends EventEmitter { renderIdlePage () { return Mustache.render(IDLE_PAGE_TEMPLATE, { - userAgent: this.userAgent, - statusUrl: this.statusUrl, - heartbeatUrl: this.heartbeatUrl, - initScriptUrl: this.initScriptUrl + userAgent: this.userAgent, + statusUrl: this.statusUrl, + heartbeatUrl: this.heartbeatUrl, + initScriptUrl: this.initScriptUrl, + retryTestPages: !!this.browserConnectionGateway.retryTestPages }); } diff --git a/src/browser/connection/remotes-queue.js b/src/browser/connection/remotes-queue.js index c85b149f..91f5a8a2 100644 --- a/src/browser/connection/remotes-queue.js +++ b/src/browser/connection/remotes-queue.js @@ -1,7 +1,7 @@ import Promise from 'pinkie'; import { EventEmitter } from 'events'; import promisifyEvent from 'promisify-event'; -import timeLimit from 'time-limit-promise'; +import getTimeLimitedPromise from 'time-limit-promise'; const REMOTE_REDIRECT_TIMEOUT = 10000; @@ -36,7 +36,7 @@ export default class RemotesQueue { var headId = Object.keys(this.pendingConnections)[0]; if (!headId) - headId = await timeLimit(promisifyEvent(this.events, 'connection-added'), ADDING_CONNECTION_WAITING_TIMEOUT); + headId = await getTimeLimitedPromise(promisifyEvent(this.events, 'connection-added'), ADDING_CONNECTION_WAITING_TIMEOUT); return headId ? this.pendingConnections[headId].connection : null; }); @@ -46,7 +46,7 @@ export default class RemotesQueue { if (!connection) return Promise.resolve(); - return timeLimit(this.pendingConnections[connection.id].readyPromise, REMOTE_REDIRECT_TIMEOUT); + return getTimeLimitedPromise(this.pendingConnections[connection.id].readyPromise, REMOTE_REDIRECT_TIMEOUT); }); return shiftingPromise; diff --git a/src/browser/connection/unstable-network-mode.js b/src/browser/connection/unstable-network-mode.js new file mode 100644 index 00000000..f8457c00 --- /dev/null +++ b/src/browser/connection/unstable-network-mode.js @@ -0,0 +1 @@ +export const UNSTABLE_NETWORK_MODE_HEADER = 'x-testcafe-cache-page-request'; diff --git a/src/client/browser/idle-page/index.html.mustache b/src/client/browser/idle-page/index.html.mustache index 60a47735..cdf5e2dc 100644 --- a/src/client/browser/idle-page/index.html.mustache +++ b/src/client/browser/idle-page/index.html.mustache @@ -27,7 +27,7 @@

#f2d7x11H76yZ2nTHXJ(1*E4n{5 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

diff --git a/src/client/browser/idle-page/index.js b/src/client/browser/idle-page/index.js index 0b0e4946..f2cfd641 100644 --- a/src/client/browser/idle-page/index.js +++ b/src/client/browser/idle-page/index.js @@ -9,10 +9,13 @@ var createXHR = () => new XMLHttpRequest(); class IdlePage { - constructor (statusUrl, heartbeatUrl, initScriptUrl) { + constructor (statusUrl, heartbeatUrl, initScriptUrl, options = {}) { this.statusUrl = statusUrl; this.statusIndicator = new StatusIndicator(); + if (options.retryTestPages) + browser.enableRetryingTestPages(); + browser.startHeartbeat(heartbeatUrl, createXHR); browser.startInitScriptExecution(initScriptUrl, createXHR); diff --git a/src/client/browser/index.js b/src/client/browser/index.js index 3e7a5342..79af664f 100644 --- a/src/client/browser/index.js +++ b/src/client/browser/index.js @@ -2,24 +2,43 @@ import Promise from 'pinkie'; import COMMAND from '../../browser/connection/command'; import STATUS from '../../browser/connection/status'; +import { UNSTABLE_NETWORK_MODE_HEADER } from '../../browser/connection/unstable-network-mode'; const HEARTBEAT_INTERVAL = 2 * 1000; -var allowInitScriptExecution = false; +let allowInitScriptExecution = false; +let retryTestPages = false; + +const noop = () => void 0; +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); + +const FETCH_PAGE_TO_CACHE_RETRY_DELAY = 300; +const FETCH_PAGE_TO_CACHE_RETRY_COUNT = 5; //Utils // NOTE: the window.XMLHttpRequest may have been wrapped by Hammerhead, while we should send a request to // the original URL. That's why we need the XMLHttpRequest argument to send the request via native methods. -function sendXHR (url, createXHR, method = 'GET', data = null) { +export function sendXHR (url, createXHR, { method = 'GET', data = null, parseResponse = true } = {}) { return new Promise((resolve, reject) => { - var xhr = createXHR(); + const xhr = createXHR(); xhr.open(method, url, true); + if (isRetryingTestPagesEnabled()) { + xhr.setRequestHeader(UNSTABLE_NETWORK_MODE_HEADER, 'true'); + xhr.setRequestHeader('accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'); + } + xhr.onreadystatechange = () => { if (xhr.readyState === 4) { - if (xhr.status === 200) - resolve(xhr.responseText ? JSON.parse(xhr.responseText) : ''); //eslint-disable-line no-restricted-globals + if (xhr.status === 200) { + let responseText = xhr.responseText || ''; + + if (responseText && parseResponse) + responseText = JSON.parse(xhr.responseText); //eslint-disable-line no-restricted-globals + + resolve(responseText); + } else reject('disconnected'); } @@ -63,7 +82,7 @@ function executeInitScript (initScriptUrl, createXHR) { return null; /* eslint-disable no-eval, no-restricted-globals*/ - return sendXHR(initScriptUrl, createXHR, 'POST', JSON.stringify(eval(res.code))); + return sendXHR(initScriptUrl, createXHR, { method: 'POST', data: JSON.stringify(eval(res.code)) }); /* eslint-enable no-eval, no-restricted-globals */ }) .then(() => { @@ -86,17 +105,48 @@ export function redirect (command) { document.location = command.url; } +export function fetchPageToCache (pageUrl, createXHR) { + const requestAttempt = () => sendXHR(pageUrl, createXHR, { parseResponse: false }); + const retryRequest = () => delay(FETCH_PAGE_TO_CACHE_RETRY_DELAY).then(requestAttempt); + + let fetchPagePromise = requestAttempt(); + + for (let i = 0; i < FETCH_PAGE_TO_CACHE_RETRY_COUNT; i++) + fetchPagePromise = fetchPagePromise.catch(retryRequest); + + return fetchPagePromise.catch(noop); +} + export function checkStatus (statusUrl, createXHR, opts) { const { manualRedirect } = opts || {}; return sendXHR(statusUrl, createXHR) - .then(res => { - const redirecting = (res.cmd === COMMAND.run || res.cmd === COMMAND.idle) && !isCurrentLocation(res.url); + .then(result => { + let ensurePagePromise = Promise.resolve(); + + if (result.url && isRetryingTestPagesEnabled()) + ensurePagePromise = fetchPageToCache(result.url, createXHR); + + return ensurePagePromise.then(() => result); + }) + .then(result => { + const redirecting = (result.cmd === COMMAND.run || result.cmd === COMMAND.idle) && !isCurrentLocation(result.url); if (redirecting && !manualRedirect) - redirect(res); + redirect(result); - return { command: res, redirecting }; + return { command: result, redirecting }; }); } +export function enableRetryingTestPages () { + retryTestPages = true; +} + +export function disableRetryingTestPages () { + retryTestPages = false; +} + +export function isRetryingTestPagesEnabled () { + return retryTestPages; +} diff --git a/src/client/core/index.js b/src/client/core/index.js index f3f5a194..049d3b48 100644 --- a/src/client/core/index.js +++ b/src/client/core/index.js @@ -18,6 +18,7 @@ import * as promiseUtils from './utils/promise'; import * as textSelection from './utils/text-selection'; import waitFor from './utils/wait-for'; import delay from './utils/delay'; +import getTimeLimitedPromise from './utils/get-time-limited-promise'; import noop from './utils/noop'; import getKeyArray from './utils/get-key-array'; import getSanitizedKey from './utils/get-sanitized-key'; @@ -46,6 +47,7 @@ exports.promiseUtils = promiseUtils; exports.textSelection = textSelection; exports.waitFor = waitFor; exports.delay = delay; +exports.getTimeLimitedPromise = getTimeLimitedPromise; exports.noop = noop; exports.getKeyArray = getKeyArray; exports.getSanitizedKey = getSanitizedKey; diff --git a/src/client/core/utils/get-time-limited-promise.js b/src/client/core/utils/get-time-limited-promise.js new file mode 100644 index 00000000..9d934df2 --- /dev/null +++ b/src/client/core/utils/get-time-limited-promise.js @@ -0,0 +1,8 @@ +import { Promise } from '../deps/hammerhead'; +import delay from './delay'; +import { timeLimitedPromiseTimeoutExpired } from '../../../errors/runtime/message'; + + +export default function (promise, ms) { + return Promise.race([promise, delay(ms).then(() => Promise.reject(new Error(timeLimitedPromiseTimeoutExpired)))]); +} diff --git a/src/client/driver/command-executors/execute-navigate-to.js b/src/client/driver/command-executors/execute-navigate-to.js index 9ab2708c..3dacbe0d 100644 --- a/src/client/driver/command-executors/execute-navigate-to.js +++ b/src/client/driver/command-executors/execute-navigate-to.js @@ -1,19 +1,26 @@ import hammerhead from '../deps/hammerhead'; -import testCafeCore from '../deps/testcafe-core'; +import { RequestBarrier, pageUnloadBarrier, browser } from '../deps/testcafe-core'; import DriverStatus from '../status'; -var Promise = hammerhead.Promise; - -var RequestBarrier = testCafeCore.RequestBarrier; -var pageUnloadBarrier = testCafeCore.pageUnloadBarrier; +const { createNativeXHR, utils } = hammerhead; export default function executeNavigateTo (command) { - var requestBarrier = new RequestBarrier(); + const navigationUrl = utils.url.getNavigationUrl(command.url, window); + + let ensurePagePromise = hammerhead.Promise.resolve(); + + if (navigationUrl && browser.isRetryingTestPagesEnabled()) + ensurePagePromise = browser.fetchPageToCache(navigationUrl, createNativeXHR); + + return ensurePagePromise + .then(() => { + const requestBarrier = new RequestBarrier(); - hammerhead.navigateTo(command.url); + hammerhead.navigateTo(command.url); - return Promise.all([requestBarrier.wait(), pageUnloadBarrier.wait()]) + return hammerhead.Promise.all([requestBarrier.wait(), pageUnloadBarrier.wait()]); + }) .then(() => new DriverStatus({ isCommandResult: true })) .catch(err => new DriverStatus({ isCommandResult: true, executionError: err })); } diff --git a/src/client/driver/driver.js b/src/client/driver/driver.js index bbe0b79c..6e47bd24 100644 --- a/src/client/driver/driver.js +++ b/src/client/driver/driver.js @@ -7,6 +7,8 @@ import { preventRealEvents, disableRealEventsPreventing, waitFor, + delay, + getTimeLimitedPromise, browser } from './deps/testcafe-core'; import { StatusBar } from './deps/testcafe-ui'; @@ -66,6 +68,10 @@ const ASSERTION_RETRIES_TIMEOUT = 'testcafe|driver|assertion-retries- const ASSERTION_RETRIES_START_TIME = 'testcafe|driver|assertion-retries-start-time'; const CONSOLE_MESSAGES = 'testcafe|driver|console-messages'; const CHECK_IFRAME_DRIVER_LINK_DELAY = 500; +const SEND_STATUS_REQUEST_TIME_LIMIT = 1000; +const SEND_STATUS_REQUEST_RETRY_DELAY = 300; +const SEND_STATUS_REQUEST_RETRY_COUNT = 5; +const CHECK_STATUS_RETRY_DELAY = 1000; const ACTION_IFRAME_ERROR_CTORS = { NotLoadedError: ActionIframeIsNotLoadedError, @@ -108,6 +114,9 @@ export default class Driver { this.statusBar = null; + if (options.retryTestPages) + browser.enableRetryingTestPages(); + this.pageInitialRequestBarrier = new RequestBarrier(); this.readyPromise = eventUtils @@ -202,6 +211,25 @@ export default class Driver { this.consoleMessages = null; } + _sendStatusRequest (status) { + const statusRequestOptions = { + cmd: TEST_RUN_MESSAGES.ready, + status: status, + disableResending: true, + allowRejecting: true + }; + + const requestAttempt = () => getTimeLimitedPromise(transport.asyncServiceMsg(statusRequestOptions), SEND_STATUS_REQUEST_TIME_LIMIT); + const retryRequest = () => delay(SEND_STATUS_REQUEST_RETRY_DELAY).then(requestAttempt); + + let statusPromise = requestAttempt(); + + for (let i = 0; i < SEND_STATUS_REQUEST_RETRY_COUNT; i++) + statusPromise = statusPromise.catch(retryRequest); + + return statusPromise; + } + _sendStatus (status) { // NOTE: We should not modify the status if it is resent after // the page load because the server has cached the response @@ -218,12 +246,7 @@ export default class Driver { // NOTE: postpone status sending if the page is unloading return pageUnloadBarrier .wait(0) - .then(() => transport.queuedAsyncServiceMsg({ - cmd: TEST_RUN_MESSAGES.ready, - status: status, - disableResending: true - })) - + .then(() => this._sendStatusRequest(status)) //NOTE: do not execute the next command if the page is unloading .then(res => { readyCommandResponse = res; @@ -477,6 +500,9 @@ export default class Driver { browser.redirect(command); else this._onReady({ isCommandResult: false }); + }) + .catch(() => { + return delay(CHECK_STATUS_RETRY_DELAY); }); } diff --git a/src/client/test-run/iframe.js.mustache b/src/client/test-run/iframe.js.mustache index 81bf3ae1..0a7a0756 100644 --- a/src/client/test-run/iframe.js.mustache +++ b/src/client/test-run/iframe.js.mustache @@ -1,10 +1,11 @@ (function () { var IframeDriver = window['%testCafeIframeDriver%']; var driver = new IframeDriver({{{testRunId}}}, { - selectorTimeout: {{{selectorTimeout}}}, - pageLoadTimeout: {{{pageLoadTimeout}}}, - dialogHandler: {{{dialogHandler}}}, - speed: {{{speed}}} + selectorTimeout: {{{selectorTimeout}}}, + pageLoadTimeout: {{{pageLoadTimeout}}}, + dialogHandler: {{{dialogHandler}}}, + unstableNetworkMode: {{{retryTestPages}}}, + speed: {{{speed}}} }); driver.start(); diff --git a/src/client/test-run/index.js.mustache b/src/client/test-run/index.js.mustache index cf5f7125..c3ccd082 100644 --- a/src/client/test-run/index.js.mustache +++ b/src/client/test-run/index.js.mustache @@ -8,6 +8,7 @@ var browserId = {{{browserId}}}; var selectorTimeout = {{{selectorTimeout}}}; var pageLoadTimeout = {{{pageLoadTimeout}}}; + var retryTestPages = {{{retryTestPages}}}; var speed = {{{speed}}}; var browserHeartbeatUrl = origin + {{{browserHeartbeatRelativeUrl}}}; var browserStatusUrl = origin + {{{browserStatusRelativeUrl}}}; @@ -27,6 +28,7 @@ pageLoadTimeout: pageLoadTimeout, skipJsErrors: skipJsErrors, dialogHandler: dialogHandler, + retryTestPages: retryTestPages, speed: speed } ); diff --git a/src/errors/runtime/message.js b/src/errors/runtime/message.js index 289fa487..37139ce8 100644 --- a/src/errors/runtime/message.js +++ b/src/errors/runtime/message.js @@ -1,3 +1,9 @@ +// ------------------------------------------------------------- +// WARNING: this file is used by both the client and the server. +// Do not use any browser or node-specific API! +// ------------------------------------------------------------- + + export default { browserDisconnected: 'The {userAgent} browser disconnected. This problem may appear when a browser hangs or is closed, or due to network issues.', cantRunAgainstDisconnectedBrowsers: 'The following browsers disconnected: {userAgents}. Tests will not be run.', @@ -29,5 +35,6 @@ export default { unsupportedUrlProtocol: 'The specified "{url}" test page URL uses an unsupported {protocol}:// protocol. Only relative URLs or absolute URLs with http://, https:// and file:// protocols are supported.', unableToOpenBrowser: 'Was unable to open the browser "{alias}" due to error.\n\n{errMessage}', testControllerProxyCantResolveTestRun: `Cannot implicitly resolve the test run in the context of which the test controller action should be executed. Use test function's 't' argument instead.`, - requestHookConfigureAPIError: 'There was an error while configuring the request hook:\n\n{requestHookName}: {errMsg}' + requestHookConfigureAPIError: 'There was an error while configuring the request hook:\n\n{requestHookName}: {errMsg}', + timeLimitedPromiseTimeoutExpired: 'Timeout expired for a time limited promise' }; diff --git a/src/index.js b/src/index.js index 1057d161..80185192 100644 --- a/src/index.js +++ b/src/index.js @@ -36,7 +36,7 @@ async function getValidPort (port) { } // API -async function createTestCafe (hostname, port1, port2, sslOptions, developmentMode) { +async function createTestCafe (hostname, port1, port2, sslOptions, developmentMode, retryTestPages) { [hostname, port1, port2] = await Promise.all([ getValidHostname(hostname), getValidPort(port1), @@ -45,7 +45,8 @@ async function createTestCafe (hostname, port1, port2, sslOptions, developmentMo const testcafe = new TestCafe(hostname, port1, port2, { ssl: sslOptions, - developmentMode + developmentMode, + retryTestPages }); setupExitHook(cb => testcafe.close().then(cb)); diff --git a/src/runner/browser-set.js b/src/runner/browser-set.js index 00c5b525..e5b48a83 100644 --- a/src/runner/browser-set.js +++ b/src/runner/browser-set.js @@ -1,6 +1,6 @@ import { EventEmitter } from 'events'; import Promise from 'pinkie'; -import timeLimit from 'time-limit-promise'; +import getTimeLimitedPromise from 'time-limit-promise'; import promisifyEvent from 'promisify-event'; import { noop, pull as remove, flatten } from 'lodash'; import mapReverse from 'map-reverse'; @@ -132,7 +132,7 @@ export default class BrowserSet extends EventEmitter { BrowserSet._closeConnection(bc) : BrowserSet._waitIdle(bc); - var release = timeLimit(appropriateStateSwitch, this.RELEASE_TIMEOUT).then(() => remove(this.pendingReleases, release)); + var release = getTimeLimitedPromise(appropriateStateSwitch, this.RELEASE_TIMEOUT).then(() => remove(this.pendingReleases, release)); this.pendingReleases.push(release); diff --git a/src/runner/index.js b/src/runner/index.js index 618a8fac..a1852fa7 100644 --- a/src/runner/index.js +++ b/src/runner/index.js @@ -16,7 +16,7 @@ const DEFAULT_ASSERTION_TIMEOUT = 3000; const DEFAULT_PAGE_LOAD_TIMEOUT = 3000; export default class Runner extends EventEmitter { - constructor (proxy, browserConnectionGateway) { + constructor (proxy, browserConnectionGateway, options = {}) { super(); this.proxy = proxy; @@ -32,6 +32,7 @@ export default class Runner extends EventEmitter { skipJsErrors: false, quarantineMode: false, debugMode: false, + retryTestPages: options.retryTestPages, selectorTimeout: DEFAULT_SELECTOR_TIMEOUT, pageLoadTimeout: DEFAULT_PAGE_LOAD_TIMEOUT }; diff --git a/src/test-run/index.js b/src/test-run/index.js index d94c8bea..fb3f7d55 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -24,6 +24,7 @@ import TestRunBookmark from './bookmark'; import ClientFunctionBuilder from '../client-functions/client-function-builder'; import ReporterPluginHost from '../reporter/plugin-host'; import BrowserConsoleMessages from './browser-console-messages'; +import { UNSTABLE_NETWORK_MODE_HEADER } from '../browser/connection/unstable-network-mode'; import { TakeScreenshotOnFailCommand } from './commands/browser-manipulation'; import { SetNativeDialogHandlerCommand, SetTestSpeedCommand, SetPageLoadTimeoutCommand } from './commands/actions'; @@ -192,6 +193,7 @@ export default class TestRun extends EventEmitter { selectorTimeout: this.opts.selectorTimeout, pageLoadTimeout: this.pageLoadTimeout, skipJsErrors: this.opts.skipJsErrors, + retryTestPages: !!this.opts.retryTestPages, speed: this.speed, dialogHandler: JSON.stringify(this.activeDialogHandler) }); @@ -202,6 +204,7 @@ export default class TestRun extends EventEmitter { testRunId: JSON.stringify(this.session.id), selectorTimeout: this.opts.selectorTimeout, pageLoadTimeout: this.pageLoadTimeout, + retryTestPages: !!this.opts.retryTestPages, speed: this.speed, dialogHandler: JSON.stringify(this.activeDialogHandler) }); @@ -222,6 +225,11 @@ export default class TestRun extends EventEmitter { } handlePageError (ctx, err) { + if (ctx.req.headers[UNSTABLE_NETWORK_MODE_HEADER]) { + ctx.closeWithError(500, err.toString()); + return; + } + this.pendingPageError = new PageLoadError(err); ctx.redirect(ctx.toProxyUrl('about:error')); diff --git a/src/test-run/session-controller.js b/src/test-run/session-controller.js index 4eeaa674..f0b1e78d 100644 --- a/src/test-run/session-controller.js +++ b/src/test-run/session-controller.js @@ -1,5 +1,6 @@ import path from 'path'; import { Session } from 'testcafe-hammerhead'; +import { UNSTABLE_NETWORK_MODE_HEADER } from '../browser/connection/unstable-network-mode'; const ACTIVE_SESSIONS_MAP = {}; @@ -41,6 +42,18 @@ export default class SessionController extends Session { return this.currentTestRun.handlePageError(ctx, err); } + onPageRequest (ctx) { + const requireStateSwitch = this.requireStateSwitch; + const pendingStateSnapshot = this.pendingStateSnapshot; + + super.onPageRequest(ctx); + + if (requireStateSwitch && ctx.req.headers[UNSTABLE_NETWORK_MODE_HEADER]) { + this.requireStateSwitch = true; + + this.pendingStateSnapshot = pendingStateSnapshot; + } + } // API static getSession (testRun) { let sessionInfo = ACTIVE_SESSIONS_MAP[testRun.browserConnection.id]; diff --git a/src/testcafe.js b/src/testcafe.js index a39b0f9a..6a156517 100644 --- a/src/testcafe.js +++ b/src/testcafe.js @@ -20,10 +20,14 @@ export default class TestCafe { registerErrorHandlers(); + if (options.retryTestPages) + options.staticContentCaching = { maxAge: 3600, mustRevalidate: false }; + this.closed = false; this.proxy = new Proxy(hostname, port1, port2, options); - this.browserConnectionGateway = new BrowserConnectionGateway(this.proxy); + this.browserConnectionGateway = new BrowserConnectionGateway(this.proxy, { retryTestPages: options.retryTestPages }); this.runners = []; + this.retryTestPages = options.retryTestPages; this._registerAssets(options.developmentMode); } @@ -69,7 +73,7 @@ export default class TestCafe { } createRunner () { - const newRunner = new Runner(this.proxy, this.browserConnectionGateway); + const newRunner = new Runner(this.proxy, this.browserConnectionGateway, { retryTestPages: this.retryTestPages }); this.runners.push(newRunner); diff --git a/src/utils/temp-directory/cleanup-process/index.js b/src/utils/temp-directory/cleanup-process/index.js index f7432756..043e4a49 100644 --- a/src/utils/temp-directory/cleanup-process/index.js +++ b/src/utils/temp-directory/cleanup-process/index.js @@ -13,9 +13,10 @@ const DEBUG_LOGGER = debug('testcafe:utils:temp-directory:cleanup-process'); class CleanupProcess { constructor () { - this.worker = null; - this.initialized = false; - this.initPromise = Promise.resolve(void 0); + this.worker = null; + this.initialized = false; + this.initPromise = Promise.resolve(void 0); + this.errorPromise = null; this.messageCounter = 0; @@ -25,7 +26,7 @@ class CleanupProcess { _sendMessage (id, msg) { return Promise.race([ sendMessageToChildProcess(this.worker, { id, ...msg }), - promisifyEvent(this.worker, 'error') + this._waitProcessError() ]); } @@ -77,6 +78,19 @@ class CleanupProcess { .then(exitCode => Promise.reject(new Error(`Worker process terminated with code ${exitCode}`))); } + _waitProcessError () { + if (this.errorPromise) + return this.errorPromise; + + this.errorPromise = promisifyEvent(this.worker, 'error'); + + this.errorPromise.then(() => { + this.errorPromise = null; + }); + + return this.errorPromise; + } + _setupWorkerEventHandlers () { this.worker.on('message', message => this._onResponse(message)); @@ -116,7 +130,7 @@ class CleanupProcess { try { await Promise.race([ this._waitResponseForMessage({ command: COMMANDS.init }), - promisifyEvent(this.worker, 'error'), + this._waitProcessError(), exitPromise ]); diff --git a/test/functional/config.js b/test/functional/config.js index 5636cc16..8f094f84 100644 --- a/test/functional/config.js +++ b/test/functional/config.js @@ -29,22 +29,24 @@ testingEnvironments[testingEnvironmentNames.osXDesktopAndMSEdgeBrowsers] = { accessKey: process.env.BROWSER_STACK_ACCESS_KEY }, + retryTestPages: true, + browsers: [ { os: 'OS X', - osVersion: 'Sierra', + osVersion: 'HIgh Sierra', name: 'safari', alias: 'safari' }, { os: 'OS X', - osVersion: 'Sierra', + osVersion: 'High Sierra', name: 'chrome', alias: 'chrome-osx' }, { os: 'OS X', - osVersion: 'Sierra', + osVersion: 'High Sierra', name: 'firefox', alias: 'firefox-osx' }, @@ -65,6 +67,8 @@ testingEnvironments[testingEnvironmentNames.mobileBrowsers] = { accessKey: process.env.BROWSER_STACK_ACCESS_KEY }, + retryTestPages: true, + browsers: [ { realMobile: true, @@ -174,6 +178,8 @@ testingEnvironments[testingEnvironmentNames.oldBrowsers] = { }, + retryTestPages: true, + browsers: [ { platform: 'Windows 8', @@ -226,6 +232,14 @@ module.exports = { return this.currentEnvironment.isLocalBrowsers; }, + get devMode () { + return !!process.env.DEV_MODE; + }, + + get retryTestPages () { + return this.currentEnvironment.retryTestPages; + }, + isTravisEnvironment, testingEnvironmentNames, diff --git a/test/functional/fixtures/api/es-next/hooks/testcafe-fixtures/fixture-hooks.js b/test/functional/fixtures/api/es-next/hooks/testcafe-fixtures/fixture-hooks.js index b8818453..ae3659f9 100644 --- a/test/functional/fixtures/api/es-next/hooks/testcafe-fixtures/fixture-hooks.js +++ b/test/functional/fixtures/api/es-next/hooks/testcafe-fixtures/fixture-hooks.js @@ -1,5 +1,5 @@ import delay from '../../../../../../../src/utils/delay'; -import timeLimit from 'time-limit-promise'; +import getTimeLimitedPromise from 'time-limit-promise'; var hooksExecuted = { fixture1Before: 0, @@ -47,7 +47,7 @@ test('Test3', async t => { return Promise.resolve().then(() => hooksExecuted.fixture1After === 1 ? null : delay(100).then(check)); } - await timeLimit(check(), 5000, { rejectWith: new Error(`fixture1After counter is expected to be 1, but it was ${hooksExecuted.fixture1After}`) }); + await getTimeLimitedPromise(check(), 5000, { rejectWith: new Error(`fixture1After counter is expected to be 1, but it was ${hooksExecuted.fixture1After}`) }); }); fixture `Fixture3` diff --git a/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/api/add-remove-request-hook.js b/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/api/add-remove-request-hook.js index 94d78dea..957004d0 100644 --- a/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/api/add-remove-request-hook.js +++ b/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/api/add-remove-request-hook.js @@ -1,5 +1,6 @@ import { RequestHook } from 'testcafe'; import path from 'path'; +import config from '../../../../../../config'; const ResultPromise = require(path.resolve('./lib/utils/re-executable-promise')); const pageUrl = 'http://localhost:3000/fixtures/api/es-next/request-hooks/pages/index.html'; @@ -34,29 +35,29 @@ test .requestHooks(hook2) ('Test', async t => { await t - .expect(hook1.onResponseCallCount).eql(1) - .expect(hook2.onResponseCallCount).eql(1); + .expect(hook1.onResponseCallCount).eql(config.retryTestPages ? 2 : 1) + .expect(hook2.onResponseCallCount).eql(config.retryTestPages ? 2 : 1); await t .addRequestHooks(hook3) .expect(hook3.onResponseCallCount).eql(0) .navigateTo(pageUrl) - .expect(hook1.onResponseCallCount).eql(2) - .expect(hook2.onResponseCallCount).eql(2) - .expect(hook3.onResponseCallCount).eql(1); + .expect(hook1.onResponseCallCount).eql(config.retryTestPages ? 4 : 2) + .expect(hook2.onResponseCallCount).eql(config.retryTestPages ? 4 : 2) + .expect(hook3.onResponseCallCount).eql(config.retryTestPages ? 2 : 1); await t .addRequestHooks(hook1, hook2, hook3) .navigateTo(pageUrl) - .expect(hook1.onResponseCallCount).eql(3) - .expect(hook2.onResponseCallCount).eql(3) - .expect(hook3.onResponseCallCount).eql(2); + .expect(hook1.onResponseCallCount).eql(config.retryTestPages ? 6 : 3) + .expect(hook2.onResponseCallCount).eql(config.retryTestPages ? 6 : 3) + .expect(hook3.onResponseCallCount).eql(config.retryTestPages ? 4 : 2); await t .removeRequestHooks(hook1) .removeRequestHooks(hook1) .navigateTo(pageUrl) - .expect(hook1.onResponseCallCount).eql(3) - .expect(hook2.onResponseCallCount).eql(4) - .expect(hook3.onResponseCallCount).eql(3); + .expect(hook1.onResponseCallCount).eql(config.retryTestPages ? 6 : 3) + .expect(hook2.onResponseCallCount).eql(config.retryTestPages ? 8 : 4) + .expect(hook3.onResponseCallCount).eql(config.retryTestPages ? 6 : 3); }); diff --git a/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-logger/api.js b/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-logger/api.js index 6ea89791..7e98505c 100644 --- a/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-logger/api.js +++ b/test/functional/fixtures/api/es-next/request-hooks/testcafe-fixtures/request-logger/api.js @@ -1,4 +1,5 @@ import { RequestLogger } from 'testcafe'; +import config from '../../../../../../config'; const pageUrl = 'http://localhost:3000/fixtures/api/es-next/request-hooks/pages/index.html'; const logger = new RequestLogger(pageUrl); @@ -11,7 +12,7 @@ test ('API', async t => { await t .expect(logger.contains(r => r.response.statusCode === 200)).ok() - .expect(logger.count(r => r.request.url === pageUrl)).eql(1); + .expect(logger.count(r => r.request.url === pageUrl)).eql(config.retryTestPages ? 2 : 1); logger.clear(); @@ -24,7 +25,7 @@ test .expect(logger.contains(r => r.request.url === pageUrl)).ok(); await t - .expect(logger.requests.length).eql(1) + .expect(logger.requests.length).eql(config.retryTestPages ? 2 : 1) .expect(logger.requests[0].request.url).eql(pageUrl) .expect(logger.requests[0].response.statusCode).eql(304); }); diff --git a/test/functional/fixtures/api/legacy/smoke/test.js b/test/functional/fixtures/api/legacy/smoke/test.js index a9f9e5ee..db9d00e1 100644 --- a/test/functional/fixtures/api/legacy/smoke/test.js +++ b/test/functional/fixtures/api/legacy/smoke/test.js @@ -6,19 +6,19 @@ const assertionHelper = require('../../../../assertion-helper'); const SCREENSHOT_PATH_MESSAGE_RE = /^___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1/; const ERROR_SCREENSHOT_PATH_RE = /Screenshot: ___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1[\\/]\S+[\\/]errors[\\/]\d.png/; -describe('[Legacy] Smoke tests', () => { - it('Should run basic tests', () => { - return runTests(path.join(__dirname, './testcafe-fixtures/basic/*test.js'), null, { skip: 'iphone,ipad' }); - }); +if (config.useLocalBrowsers) { + describe('[Legacy] Smoke tests', () => { + it('Should run basic tests', () => { + return runTests(path.join(__dirname, './testcafe-fixtures/basic/*test.js'), null, { skip: 'iphone,ipad' }); + }); - it('Should fail on errors', () => { - return runTests('./testcafe-fixtures/errors.test.js', null, { shouldFail: true, skip: 'iphone,ipad' }) - .catch(errs => { - expect(errs[0]).contains('A target element of the click action has not been found in the DOM tree.'); - }); - }); + it('Should fail on errors', () => { + return runTests('./testcafe-fixtures/errors.test.js', null, { shouldFail: true, skip: 'iphone,ipad' }) + .catch(errs => { + expect(errs[0]).contains('A target element of the click action has not been found in the DOM tree.'); + }); + }); - if (config.useLocalBrowsers) { describe('Screenshots', () => { afterEach(assertionHelper.removeScreenshotDir); @@ -39,5 +39,5 @@ describe('[Legacy] Smoke tests', () => { }); }); }); - } -}); + }); +} diff --git a/test/functional/setup.js b/test/functional/setup.js index bfbbf64d..60ab7095 100644 --- a/test/functional/setup.js +++ b/test/functional/setup.js @@ -126,8 +126,10 @@ before(function () { mocha.timeout(60000); - return createTestCafe(config.testCafe.hostname, config.testCafe.port1, config.testCafe.port2) - .then(tc => { + const { devMode, retryTestPages } = config; + + return createTestCafe(config.testCafe.hostname, config.testCafe.port1, config.testCafe.port2, null, devMode, retryTestPages) + .then(function (tc) { testCafe = tc; return initBrowsersInfo(); diff --git a/test/functional/site/server.js b/test/functional/site/server.js index 2b09d1f0..431ff2a0 100644 --- a/test/functional/site/server.js +++ b/test/functional/site/server.js @@ -66,6 +66,9 @@ Server.prototype._setupRoutes = function () { .then(function (content) { res.setHeader('content-type', CONTENT_TYPES[path.extname(resourcePath)]); + if (!reqPath.startsWith('/fixtures/api/es-next/roles/pages') && !reqPath.startsWith('/fixtures/api/es-next/request-hooks/pages')) + res.setHeader('cache-control', 'max-age=3600'); + setTimeout(function () { res.send(content); }, delay); From 32478e1b740457de845714c71826a738c0851558 Mon Sep 17 00:00:00 2001 From: AlexSkorkin Date: Tue, 18 Sep 2018 14:21:06 +0300 Subject: [PATCH 098/184] Update year in license to 2018 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 87b38819..1e408654 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (C) 2012-2017 Developer Express Inc. +Copyright (C) 2012-2018 Developer Express Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 58aca1bd32bddb94a14e794c78c043e1e59ae67c Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Wed, 19 Sep 2018 15:04:26 +0300 Subject: [PATCH 099/184] Add an SVG logo for README.md --- media/testcafe-logo.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 media/testcafe-logo.svg diff --git a/media/testcafe-logo.svg b/media/testcafe-logo.svg new file mode 100644 index 00000000..66cb58c1 --- /dev/null +++ b/media/testcafe-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file From c785fb01d8b77b83782206cd66bb780c63df73f4 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Wed, 19 Sep 2018 15:38:17 +0300 Subject: [PATCH 100/184] Change README logo to SVG --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f8172c9..66910af3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

- testcafe + testcafe

From e7790ccad7a67b3962d7df16c117c88144faed04 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Thu, 20 Sep 2018 10:10:54 +0300 Subject: [PATCH 101/184] Enable ESLint no-var rule (#2858) --- .eslintrc | 1 + src/browser/connection/gateway.js | 14 +- src/browser/connection/remotes-queue.js | 6 +- src/browser/provider/built-in/chrome/cdp.js | 27 +- .../provider/built-in/chrome/config.js | 36 +- src/browser/provider/built-in/chrome/index.js | 14 +- .../provider/built-in/firefox/config.js | 16 +- .../built-in/firefox/create-temp-profile.js | 4 +- .../provider/built-in/firefox/index.js | 16 +- .../built-in/firefox/marionette-client.js | 32 +- src/browser/provider/index.js | 52 +- src/browser/provider/plugin-host.js | 12 +- src/browser/provider/pool.js | 26 +- src/cli/cli.js | 38 +- src/cli/log.js | 4 +- src/cli/remotes-wizard.js | 8 +- .../client-function-builder.js | 26 +- src/client-functions/replicator.js | 4 +- .../selectors/create-snapshot-methods.js | 2 +- .../selectors/selector-attribute-filter.js | 8 +- .../selectors/selector-text-filter.js | 12 +- src/client/automation/cursor.js | 6 +- src/client/automation/get-element.js | 40 +- src/client/automation/playback/click/index.js | 46 +- .../automation/playback/click/select-child.js | 52 +- src/client/automation/playback/drag/base.js | 26 +- .../automation/playback/drag/to-element.js | 10 +- .../automation/playback/drag/to-offset.js | 14 +- .../playback/move/event-sequence/base.js | 14 +- .../drag-and-drop-first-move.js | 4 +- .../move/event-sequence/drag-and-drop-move.js | 4 +- .../playback/move/event-sequence/index.js | 12 +- src/client/automation/playback/move/index.js | 148 ++--- src/client/automation/playback/press/index.js | 54 +- .../playback/press/key-press-simulator.js | 56 +- .../automation/playback/press/shortcuts.js | 192 +++---- src/client/automation/playback/press/utils.js | 18 +- src/client/automation/playback/select/base.js | 34 +- .../select/calculate-select-text-arguments.js | 36 +- .../select/select-editable-content.js | 26 +- .../automation/playback/select/select-text.js | 14 +- .../automation/playback/select/utils.js | 126 ++--- src/client/automation/playback/type/index.js | 82 +-- .../automation/playback/type/type-text.js | 74 +-- src/client/automation/utils/offsets.js | 18 +- .../utils/screen-point-to-client.js | 2 +- src/client/automation/utils/utils.js | 56 +- src/client/browser/idle-page/index.js | 2 +- .../browser/idle-page/status-indicator.js | 38 +- src/client/core/page-unload-barrier.js | 26 +- src/client/core/prevent-real-events.js | 14 +- src/client/core/request-barrier.js | 14 +- src/client/core/scroll-controller.js | 4 +- src/client/core/utils/array.js | 34 +- src/client/core/utils/content-editable.js | 136 ++--- src/client/core/utils/delay.js | 4 +- src/client/core/utils/dom.js | 204 +++---- src/client/core/utils/event.js | 8 +- src/client/core/utils/get-key-array.js | 2 +- src/client/core/utils/get-sanitized-key.js | 4 +- src/client/core/utils/key-maps.js | 6 +- src/client/core/utils/parse-key-sequence.js | 22 +- src/client/core/utils/position.js | 138 ++--- src/client/core/utils/promise.js | 2 +- .../core/utils/send-request-to-frame.js | 4 +- src/client/core/utils/service.js | 10 +- src/client/core/utils/style.js | 80 +-- src/client/core/utils/text-selection.js | 154 +++--- src/client/core/utils/wait-for.js | 10 +- .../ensure-crop-options.js | 36 +- .../browser-manipulation/index.js | 36 +- .../client-function-executor.js | 2 +- .../client-functions/eval-function.js | 2 +- .../client-functions/replicator.js | 8 +- .../selector-executor/index.js | 10 +- .../selector-executor/node-snapshots.js | 36 +- .../command-executors/execute-action.js | 24 +- .../command-executors/execute-selector.js | 4 +- src/client/driver/driver-link/child.js | 8 +- src/client/driver/driver-link/messages.js | 2 +- src/client/driver/driver-link/parent.js | 6 +- .../driver-link/send-message-to-driver.js | 8 +- src/client/driver/iframe-driver.js | 6 +- .../driver/native-dialog-tracker/iframe.js | 2 +- .../driver/native-dialog-tracker/index.js | 24 +- src/client/driver/script-execution-barrier.js | 12 +- src/client/driver/storage.js | 6 +- src/client/driver/utils/ensure-elements.js | 4 +- src/client/driver/utils/run-with-barriers.js | 10 +- src/client/ui/cursor/iframe-cursor.js | 4 +- src/client/ui/cursor/index.js | 22 +- src/client/ui/index.js | 6 +- src/client/ui/modal-background.js | 28 +- src/client/ui/progress-panel/index.js | 32 +- src/client/ui/progress-panel/progress-bar.js | 4 +- src/client/ui/select-element.js | 104 ++-- src/client/ui/status-bar/iframe-status-bar.js | 8 +- src/client/ui/status-bar/index.js | 94 ++-- .../progress-bar/determinate-indicator.js | 14 +- .../progress-bar/indeterminate-indicator.js | 44 +- .../ui/status-bar/progress-bar/index.js | 6 +- src/client/ui/ui-root.js | 2 +- src/compiler/compile-client-function.js | 20 +- src/compiler/index.js | 12 +- src/compiler/test-file/api-based.js | 20 +- src/compiler/test-file/base.js | 2 +- .../formats/coffeescript/compiler.js | 8 +- .../test-file/formats/es-next/compiler.js | 8 +- src/compiler/test-file/formats/raw.js | 14 +- .../test-file/formats/typescript/compiler.js | 24 +- src/embedding-utils.js | 2 +- src/errors/create-stack-filter.js | 6 +- src/errors/get-callsite.js | 6 +- src/errors/process-test-fn-error.js | 6 +- src/errors/runtime/index.js | 2 +- src/errors/runtime/type-assertions.js | 14 +- src/errors/test-run/formattable-adapter.js | 14 +- src/errors/test-run/index.js | 4 +- src/index.js | 4 +- src/notifications/debug-logger.js | 18 +- src/notifications/deprecation-message.js | 2 +- src/notifications/warning-log.js | 2 +- src/role/index.js | 2 +- src/runner/bootstrapper.js | 24 +- src/runner/browser-set.js | 20 +- src/runner/fixture-hook-controller.js | 18 +- src/runner/tested-app.js | 12 +- src/test-run/bookmark.js | 16 +- src/test-run/browser-console-messages.js | 4 +- src/test-run/browser-manipulation-queue.js | 10 +- src/test-run/commands/actions.js | 12 +- src/test-run/commands/assertion.js | 2 +- src/test-run/commands/options.js | 8 +- src/test-run/commands/validations/argument.js | 20 +- .../commands/validations/factories.js | 10 +- src/test-run/debug-log.js | 2 +- src/test-run/execute-js-expression.js | 8 +- src/utils/assignable.js | 20 +- src/utils/delegated-api.js | 6 +- src/utils/get-viewport-width.js | 2 +- src/utils/kill-browser-process.js | 10 +- src/utils/re-executable-promise.js | 2 +- src/utils/render-template.js | 2 +- src/utils/string.js | 16 +- test/client/before-test.js | 33 +- test/client/config-qunit-server-app.js | 20 +- test/client/data/dom-utils/iframe.html | 6 +- .../client/data/focus-blur-change/iframe.html | 2 +- test/client/data/runner/iframe.html | 12 +- .../fixtures/automation/automations-test.js | 213 ++++---- test/client/fixtures/automation/click-test.js | 283 +++++----- .../index-test.js | 270 ++++----- .../regression-test/index-test.js | 67 +-- .../index-test.js | 229 ++++---- .../fixtures/automation/dblclick-test.js | 22 +- ...on-element-after-events-simulation-test.js | 220 ++++---- test/client/fixtures/automation/drag-test.js | 92 ++-- .../automation/focus-blur-change-test.js | 242 ++++---- .../fixtures/automation/get-element-test.js | 26 +- test/client/fixtures/automation/hover-test.js | 66 +-- .../automation/key-press-simulation-test.js | 114 ++-- .../fixtures/automation/out-of-bounds-test.js | 224 ++++---- .../automation/press-shortcuts-test.js | 516 +++++++++--------- test/client/fixtures/automation/press-test.js | 82 +-- .../client/fixtures/automation/rclick-test.js | 48 +- .../automation/real-actions-blocker-test.js | 39 +- .../fixtures/automation/regression-test.js | 365 +++++++------ .../automation/select-element-test.js | 298 +++++----- .../automation/select-test/index-test.js | 146 ++--- .../automation/submit-on-enter-test.js | 197 +++---- .../fixtures/automation/tab-emulation-test.js | 91 +-- test/client/fixtures/automation/type-test.js | 165 +++--- test/client/fixtures/core/dom-utils-test.js | 10 +- .../fixtures/core/page-unload-barrier-test.js | 24 +- .../fixtures/core/request-barrier-test.js | 102 ++-- test/client/fixtures/core/style-utils-test.js | 8 +- .../driver/script-execution-barrier-test.js | 34 +- .../index-test.js | 24 +- .../index-test.js | 132 ++--- .../legacy-fixtures/api/assertions-test.js | 112 ++-- test/client/legacy-fixtures/api/click-test.js | 123 +++-- .../legacy-fixtures/api/dblclick-test.js | 71 +-- test/client/legacy-fixtures/api/drag-test.js | 152 +++--- .../api/native-dialogs-test.js | 22 +- .../legacy-fixtures/api/navigate-to-test.js | 14 +- test/client/legacy-fixtures/api/press-test.js | 92 ++-- .../api/select-test/index-test.js | 152 +++--- test/client/legacy-fixtures/api/type-test.js | 38 +- .../legacy-fixtures/api/wait-for-test.js | 45 +- test/client/legacy-fixtures/api/wait-test.js | 61 ++- .../cross-domain/in-iframe-test.js | 102 ++-- .../legacy-fixtures/cross-domain/run-test.js | 36 +- .../element-availability-waiting-test.js | 55 +- .../jquery-data-proxy-test/index-test.js | 31 +- .../client/legacy-fixtures/regression-test.js | 41 +- .../legacy-fixtures/runner-base-test.js | 71 +-- test/client/legacy-fixtures/runner-test.js | 40 +- .../sandboxed-jquery-test/iframe.html | 4 +- .../sandboxed-jquery-test/index-test.js | 4 +- .../legacy-fixtures/select-element-test.js | 52 +- .../legacy-fixtures/step-iterator-test.js | 73 +-- test/functional/assertion-helper.js | 68 +-- test/functional/config.js | 12 +- .../fixtures/api/coffeescript/smoke/test.js | 2 +- .../api/es-next/assertions/pages/index.html | 4 +- .../fixtures/api/es-next/assertions/test.js | 2 +- .../fixtures/api/es-next/auth/test.js | 2 +- .../ntlm-auth-check-username-test.js | 4 +- .../api/es-next/click/pages/index.html | 4 +- .../fixtures/api/es-next/click/test.js | 2 +- .../click/testcafe-fixtures/click-test.js | 4 +- .../api/es-next/client-function/test.js | 10 +- .../testcafe-fixtures/client-fn-test.js | 16 +- .../api/es-next/console/pages/index.html | 2 +- .../api/es-next/double-click/pages/index.html | 2 +- .../fixtures/api/es-next/double-click/test.js | 2 +- .../api/es-next/drag/pages/drag-and-drop.html | 172 +++--- .../api/es-next/drag/pages/index.html | 42 +- .../drag/pages/invalid-drag-and-drop.html | 94 ++-- .../fixtures/api/es-next/drag/test.js | 2 +- .../testcafe-fixtures/drag-and-drop-test.js | 8 +- .../fixtures/api/es-next/eval/test.js | 10 +- .../api/es-next/generic-errors/test.js | 4 +- .../api/es-next/hooks/pages/index.html | 2 +- .../hooks/testcafe-fixtures/fixture-ctx.js | 2 +- .../hooks/testcafe-fixtures/fixture-hooks.js | 2 +- .../hooks/testcafe-fixtures/run-all.js | 2 +- .../api/es-next/hover/pages/index.html | 10 +- .../fixtures/api/es-next/hover/test.js | 2 +- .../iframe-switching/pages/errors-iframe.html | 2 +- .../iframe-switching/pages/iframe.html | 6 +- .../es-next/iframe-switching/pages/index.html | 6 +- .../iframe-switching/pages/nested-iframe.html | 4 +- .../api/es-next/iframe-switching/test.js | 10 +- .../iframe-switching-test.js | 2 +- .../api/es-next/maximize-window/test.js | 2 +- .../testcafe-fixtures/maximize-window-test.js | 2 +- .../native-dialogs-handling/iframe/test.js | 18 +- .../testcafe-fixtures/in-iframe-test.js | 14 +- .../testcafe-fixtures/page-load-test.js | 2 +- .../pages/page-load.html | 4 +- .../native-dialogs-handling/pages/prompt.html | 2 +- .../es-next/native-dialogs-handling/test.js | 12 +- .../testcafe-fixtures/native-dialogs-test.js | 18 +- .../testcafe-fixtures/page-load-test.js | 2 +- .../es-next/navigate-to-and-test-page/test.js | 2 +- .../fixtures/api/es-next/press-key/test.js | 2 +- .../pages/failed-cors-validation.html | 2 +- .../request-hooks/pages/multi-browser.html | 4 +- .../api/es-next/resize-window/test.js | 8 +- .../testcafe-fixtures/resize-window-test.js | 8 +- .../fixtures/api/es-next/right-click/test.js | 2 +- .../api/es-next/roles/pages/index.html | 6 +- .../api/es-next/roles/pages/login-page.html | 2 +- .../fixtures/api/es-next/roles/test.js | 10 +- .../roles/testcafe-fixtures/errors-test.js | 2 +- .../fixtures/api/es-next/select-text/test.js | 2 +- .../testcafe-fixtures/select-text-test.js | 22 +- .../api/es-next/selector/pages/index.html | 6 +- .../fixtures/api/es-next/selector/test.js | 8 +- .../testcafe-fixtures/selector-test.js | 22 +- .../fixtures/api/es-next/skip-only/test.js | 2 +- .../api/es-next/speed/pages/index.html | 7 +- .../pages/element-screenshot.html | 8 +- .../es-next/take-screenshot/pages/index.html | 2 +- .../take-screenshot/pages/nested-iframe.html | 6 +- .../pages/same-domain-iframe.html | 6 +- .../api/es-next/take-screenshot/test.js | 14 +- .../es-next/test-controller/pages/index.html | 4 +- .../test-controller/pages/second-page.html | 2 +- .../testcafe-fixtures/test-controller-test.js | 2 +- .../api/es-next/type/pages/index.html | 8 +- .../fixtures/api/es-next/type/test.js | 2 +- .../type/testcafe-fixtures/type-test.js | 2 +- .../fixtures/api/es-next/upload/test.js | 2 +- .../api/es-next/wait/pages/index.html | 2 +- .../fixtures/api/es-next/wait/test.js | 2 +- ...est.js => real-action-preventing.testx.js} | 2 +- .../testcafe-fixtures/basic/upload.test.js | 2 +- .../smoke/testcafe-fixtures/errors.test.js | 2 +- .../fixtures/api/raw/assertions/test.js | 2 +- .../fixtures/api/raw/click/pages/index.html | 6 +- .../api/raw/double-click/pages/index.html | 2 +- .../fixtures/api/raw/double-click/test.js | 2 +- .../fixtures/api/raw/drag/pages/index.html | 42 +- test/functional/fixtures/api/raw/drag/test.js | 4 +- .../fixtures/api/raw/hooks/pages/index.html | 2 +- .../fixtures/api/raw/hover/pages/index.html | 2 +- .../functional/fixtures/api/raw/hover/test.js | 4 +- .../api/raw/iframe-switching/pages/index.html | 2 +- .../fixtures/api/raw/iframe-switching/test.js | 2 +- .../api/raw/native-dialogs-handling/test.js | 6 +- .../fixtures/api/raw/navigate-to/test.js | 2 +- .../api/raw/press-key/pages/index.html | 12 +- .../fixtures/api/raw/press-key/test.js | 4 +- .../fixtures/api/raw/right-click/test.js | 2 +- .../select-editable-content/pages/index.html | 8 +- .../api/raw/select-editable-content/test.js | 4 +- .../select-text-area-content/pages/index.html | 2 +- .../api/raw/select-text-area-content/test.js | 4 +- .../api/raw/select-text/pages/index.html | 6 +- .../fixtures/api/raw/select-text/test.js | 4 +- .../api/raw/selector/pages/index.html | 2 +- .../fixtures/api/raw/selector/test.js | 2 +- .../fixtures/api/raw/type/pages/index.html | 16 +- test/functional/fixtures/api/raw/type/test.js | 4 +- .../fixtures/api/raw/upload/test.js | 4 +- .../fixtures/api/typescript/smoke/test.js | 2 +- .../fixtures/app-command/failing-app.js | 4 +- test/functional/fixtures/app-command/test.js | 6 +- .../browser-provider/job-reporting/test.js | 24 +- test/functional/fixtures/concurrency/test.js | 24 +- .../fixtures/driver/pages/page1.html | 20 +- .../script-execution-barrier/pages/index.html | 13 +- test/functional/fixtures/driver/test.js | 2 +- test/functional/fixtures/page-error/test.js | 2 +- test/functional/fixtures/proxy/test.js | 4 +- .../regression/gh-1054/pages/index.html | 10 +- .../gh-1054/testcafe-fixtures/index.test.js | 4 +- .../gh-1057/pages/hiddenByFixedParent.html | 11 +- .../gh-1138/testcafe-fixtures/index.test.js | 2 +- .../regression/gh-1161/pages/index.html | 8 +- .../fixtures/regression/gh-1267/test.js | 2 +- .../regression/gh-1275/pages/index.html | 4 +- .../regression/gh-1312/pages/index.html | 8 +- .../regression/gh-1327/pages/empty-input.html | 12 +- .../regression/gh-1353/pages/index.html | 11 +- .../regression/gh-1385/pages/index.html | 4 +- .../regression/gh-1388/pages/index.html | 2 +- .../regression/gh-1424/pages/index.html | 38 +- .../regression/gh-1486/pages/index.html | 10 +- .../gh-1521/pages/changing-element.html | 2 +- .../gh-1521/pages/fixed-element.html | 4 +- .../gh-1521/pages/hidden-element.html | 2 +- .../gh-1521/pages/hover-element.html | 6 +- .../gh-1521/pages/moving-element.html | 19 +- .../gh-1521/pages/overlap-element.html | 4 +- .../fixtures/regression/gh-1521/test.js | 2 +- .../regression/gh-1679/pages/index.html | 2 +- .../regression/gh-1846/pages/index.html | 12 +- .../gh-1874/testcafe-fixtures/index-test.js | 2 +- .../fixtures/regression/gh-1907/test.js | 2 +- .../fixtures/regression/gh-1940/test.js | 2 +- .../regression/gh-1956/pages/index.html | 13 +- .../fixtures/regression/gh-1956/test.js | 6 +- .../fixtures/regression/gh-1994/test.js | 2 +- .../regression/gh-2015/pages/logon.html | 6 +- .../regression/gh-2080/pages/index.html | 6 +- .../regression/gh-2153/pages/index.html | 8 +- .../regression/gh-2205/pages/index.html | 6 +- .../regression/gh-2271/pages/index.html | 6 +- .../regression/gh-2282/pages/authorized.html | 4 +- .../gh-2450/testcafe-fixtures/index.js | 2 +- .../regression/gh-423/pages/index.html | 120 ++-- .../fixtures/regression/gh-637/test.js | 12 +- .../typing-in-content-editable-test.js | 10 +- .../two-tests-in-a-fixture.js | 2 +- .../regression/gh-751/pages/index.html | 6 +- .../gh-751/testcafe-fixtures/index-test.js | 15 +- .../regression/gh-770/pages/index.html | 14 +- .../gh-845/testcafe-fixtures/index-test.js | 4 +- .../regression/gh-847/pages/index.html | 2 +- .../regression/gh-850/pages/index.html | 4 +- .../regression/gh-851/pages/index.html | 98 ++-- .../gh-851/testcafe-fixtures/index.test.js | 32 +- .../regression/gh-883/pages/index.html | 13 +- .../gh-889/testcafe-fixtures/index.test.js | 8 +- .../fixtures/regression/gh-965/test.js | 2 +- .../regression/gh-973/pages/index.html | 11 +- .../regression/gh-993/pages/index.html | 4 +- .../run-options/selector-timeout/test.js | 2 +- .../speed/testcafe-fixtures/speed-test.js | 6 +- .../screenshots-on-fails/pages/index.html | 2 +- .../fixtures/screenshots-on-fails/test.js | 14 +- test/functional/get-test-error.js | 14 +- test/functional/is-touch-device.js | 18 +- test/functional/legacy-fixtures/.eslintrc | 5 +- test/functional/quarantine-mode-tracker.js | 4 +- test/functional/setup.js | 2 +- test/functional/site/basic-auth-server.js | 16 +- test/functional/site/index.js | 14 +- test/functional/site/ntlm-auth-server.js | 14 +- test/functional/site/server.js | 52 +- .../site/transparent-proxy-server.js | 16 +- test/functional/site/trusted-proxy-server.js | 14 +- test/server/api-test.js | 102 ++-- test/server/browser-connection-test.js | 34 +- test/server/browser-provider-test.js | 24 +- test/server/chrome-provider-config-test.js | 18 +- test/server/cli-argument-parser-test.js | 8 +- test/server/compiler-test.js | 10 +- test/server/create-testcafe-test.js | 16 +- test/server/error-handle-test.js | 7 +- test/server/firefox-provider-config-test.js | 12 +- test/server/helpers/assert-error.js | 18 +- test/server/helpers/compile.js | 10 +- .../legacy-test-run-error-formatting-test.js | 64 +-- test/server/parse-fixture-test.js | 2 +- test/server/request-hooks-test.js | 2 +- test/server/runner-test.js | 71 +-- test/server/test-run-command-options-test.js | 48 +- test/server/test-run-commands-test.js | 126 ++--- test/server/test-run-tracker-test.js | 18 +- 403 files changed, 5932 insertions(+), 5763 deletions(-) rename test/functional/fixtures/api/legacy/smoke/testcafe-fixtures/basic/{real-action-preventing.test.js => real-action-preventing.testx.js} (93%) diff --git a/.eslintrc b/.eslintrc index df8fc7fc..0fa26e5b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -33,6 +33,7 @@ "no-trailing-spaces": 2, "no-undef-init": 2, "no-unused-expressions": 2, + "no-var": 2, "no-with": 2, "camelcase": 2, "comma-spacing": 2, diff --git a/src/browser/connection/gateway.js b/src/browser/connection/gateway.js index 443fc806..b2e9a2b8 100644 --- a/src/browser/connection/gateway.js +++ b/src/browser/connection/gateway.js @@ -24,7 +24,7 @@ export default class BrowserConnectionGateway { _dispatch (url, proxy, handler, method = 'GET') { proxy[method](url, (req, res, si, params) => { - var connection = this.connections[params.id]; + const connection = this.connections[params.id]; preventCaching(res); @@ -70,7 +70,7 @@ export default class BrowserConnectionGateway { respond500(res, 'The connection is already established.'); else { - var userAgent = req.headers['user-agent']; + const userAgent = req.headers['user-agent']; connection.establish(userAgent); redirect(res, connection.idleUrl); @@ -79,7 +79,7 @@ export default class BrowserConnectionGateway { static onHeartbeat (req, res, connection) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { - var status = connection.heartbeat(); + const status = connection.heartbeat(); respondWithJSON(res, status); } @@ -108,7 +108,7 @@ export default class BrowserConnectionGateway { static async _onStatusRequestCore (req, res, connection, isTestDone) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { - var status = await connection.getStatus(isTestDone); + const status = await connection.getStatus(isTestDone); respondWithJSON(res, status); } @@ -116,7 +116,7 @@ export default class BrowserConnectionGateway { static onInitScriptRequest (req, res, connection) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { - var script = connection.getInitScript(); + const script = connection.getInitScript(); respondWithJSON(res, script); } @@ -124,7 +124,7 @@ export default class BrowserConnectionGateway { static onInitScriptResponse (req, res, connection) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { - var data = ''; + let data = ''; req.on('data', chunk => { data += chunk; @@ -141,7 +141,7 @@ export default class BrowserConnectionGateway { async _connectNextRemoteBrowser (req, res) { preventCaching(res); - var remoteConnection = await this.remotesQueue.shift(); + const remoteConnection = await this.remotesQueue.shift(); if (remoteConnection) redirect(res, remoteConnection.url); diff --git a/src/browser/connection/remotes-queue.js b/src/browser/connection/remotes-queue.js index 91f5a8a2..5262b977 100644 --- a/src/browser/connection/remotes-queue.js +++ b/src/browser/connection/remotes-queue.js @@ -15,7 +15,7 @@ export default class RemotesQueue { } add (remoteConnection) { - var connectionReadyPromise = promisifyEvent(remoteConnection, 'ready') + const connectionReadyPromise = promisifyEvent(remoteConnection, 'ready') .then(() => this.remove(remoteConnection)); this.pendingConnections[remoteConnection.id] = { @@ -31,9 +31,9 @@ export default class RemotesQueue { } shift () { - var shiftingPromise = this.shiftingTimeout + const shiftingPromise = this.shiftingTimeout .then(async () => { - var headId = Object.keys(this.pendingConnections)[0]; + let headId = Object.keys(this.pendingConnections)[0]; if (!headId) headId = await getTimeLimitedPromise(promisifyEvent(this.events, 'connection-added'), ADDING_CONNECTION_WAITING_TIMEOUT); diff --git a/src/browser/provider/built-in/chrome/cdp.js b/src/browser/provider/built-in/chrome/cdp.js index 5ca1abac..ec85bb70 100644 --- a/src/browser/provider/built-in/chrome/cdp.js +++ b/src/browser/provider/built-in/chrome/cdp.js @@ -4,8 +4,8 @@ import { GET_WINDOW_DIMENSIONS_INFO_SCRIPT } from '../../utils/client-functions' async function getActiveTab (cdpPort, browserId) { - var tabs = await remoteChrome.listTabs({ port: cdpPort }); - var tab = tabs.filter(t => t.type === 'page' && t.url.indexOf(browserId) > -1)[0]; + const tabs = await remoteChrome.listTabs({ port: cdpPort }); + const tab = tabs.filter(t => t.type === 'page' && t.url.indexOf(browserId) > -1)[0]; return tab; } @@ -23,7 +23,7 @@ async function setEmulationBounds ({ client, config, viewportSize, emulatedDevic } async function setEmulation (runtimeInfo) { - var { client, config } = runtimeInfo; + const { client, config } = runtimeInfo; if (config.userAgent !== void 0) await client.Network.setUserAgentOverride({ userAgent: config.userAgent }); @@ -46,15 +46,18 @@ async function setEmulation (runtimeInfo) { } export async function createClient (runtimeInfo) { - var { browserId, config, cdpPort } = runtimeInfo; + const { browserId, config, cdpPort } = runtimeInfo; + + let tab = null; + let client = null; try { - var tab = await getActiveTab(cdpPort, browserId); + tab = await getActiveTab(cdpPort, browserId); if (!tab) return; - var client = await remoteChrome({ target: tab, port: cdpPort }); + client = await remoteChrome({ target: tab, port: cdpPort }); } catch (e) { return; @@ -67,7 +70,7 @@ export async function createClient (runtimeInfo) { await client.Network.enable(); await client.Runtime.enable(); - var devicePixelRatioQueryResult = await client.Runtime.evaluate({ expression: 'window.devicePixelRatio' }); + const devicePixelRatioQueryResult = await client.Runtime.evaluate({ expression: 'window.devicePixelRatio' }); runtimeInfo.originalDevicePixelRatio = devicePixelRatioQueryResult.result.value; runtimeInfo.emulatedDevicePixelRatio = config.scaleFactor || runtimeInfo.originalDevicePixelRatio; @@ -113,12 +116,12 @@ export async function takeScreenshot (path, { client }) { } export async function resizeWindow (newDimensions, runtimeInfo) { - var { browserId, config, viewportSize, providerMethods } = runtimeInfo; + const { browserId, config, viewportSize, providerMethods } = runtimeInfo; - var currentWidth = viewportSize.width; - var currentHeight = viewportSize.height; - var newWidth = newDimensions.width || currentWidth; - var newHeight = newDimensions.height || currentHeight; + const currentWidth = viewportSize.width; + const currentHeight = viewportSize.height; + const newWidth = newDimensions.width || currentWidth; + const newHeight = newDimensions.height || currentHeight; if (!config.headless) await providerMethods.resizeLocalBrowserWindow(browserId, newWidth, newHeight, currentWidth, currentHeight); diff --git a/src/browser/provider/built-in/chrome/config.js b/src/browser/provider/built-in/chrome/config.js index 276bb332..25349e3d 100644 --- a/src/browser/provider/built-in/chrome/config.js +++ b/src/browser/provider/built-in/chrome/config.js @@ -10,17 +10,17 @@ const HEADLESS_DEFAULT_HEIGHT = 800; const AVAILABLE_MODES = ['userProfile', 'headless', 'emulation']; -var configCache = {}; +const configCache = {}; function hasCustomProfile (userArgs) { return !!userArgs.match(/--user-data-dir=/); } function parseModes (modesStr, userArgs) { - var parsed = splitEscaped(modesStr, ':'); - var path = getPathFromParsedModes(parsed, AVAILABLE_MODES); - var detectedModes = getModes(parsed, AVAILABLE_MODES); - var optionsString = ''; + const parsed = splitEscaped(modesStr, ':'); + const path = getPathFromParsedModes(parsed, AVAILABLE_MODES); + const detectedModes = getModes(parsed, AVAILABLE_MODES); + let optionsString = ''; if (parsed.length) optionsString = parsed.shift(); @@ -28,7 +28,7 @@ function parseModes (modesStr, userArgs) { while (parsed.length) optionsString += ':' + parsed.shift(); - var modes = { + const modes = { path: path, userProfile: detectedModes.userProfile || hasCustomProfile(userArgs), headless: detectedModes.headless, @@ -43,7 +43,7 @@ function simplifyDeviceName (deviceName) { } function findDevice (deviceName) { - var simpleName = simplifyDeviceName(deviceName); + const simpleName = simplifyDeviceName(deviceName); return emulatedDevices.filter(device => simplifyDeviceName(device.title).indexOf(simpleName) >= 0)[0]; } @@ -52,12 +52,12 @@ function getDeviceBasedOptions (deviceName, orientation) { if (!deviceName) return {}; - var deviceData = findDevice(deviceName); + const deviceData = findDevice(deviceName); if (!deviceData) return {}; - var mobile = deviceData.capabilities.indexOf('mobile') >= 0; + const mobile = deviceData.capabilities.indexOf('mobile') >= 0; if (!orientation) orientation = mobile ? 'vertical' : 'horizontal'; @@ -74,9 +74,9 @@ function getDeviceBasedOptions (deviceName, orientation) { } function parseOptions (str, modes) { - var parsed = splitEscaped(str, ';'); + const parsed = splitEscaped(str, ';'); - var baseOptions = { + const baseOptions = { width: modes.headless ? HEADLESS_DEFAULT_WIDTH : 0, height: modes.headless ? HEADLESS_DEFAULT_HEIGHT : 0, scaleFactor: 0, @@ -84,11 +84,11 @@ function parseOptions (str, modes) { cdpPort: findMatch(parsed, /^cdpPort=(.*)/) }; - var deviceName = findMatch(parsed, /^device=(.*)/); - var orientation = findMatch(parsed, /^orientation=(.*)/); - var deviceBasedOptions = getDeviceBasedOptions(deviceName, orientation); + const deviceName = findMatch(parsed, /^device=(.*)/); + const orientation = findMatch(parsed, /^orientation=(.*)/); + const deviceBasedOptions = getDeviceBasedOptions(deviceName, orientation); - var specifiedDeviceOptions = { + let specifiedDeviceOptions = { orientation: orientation, touch: hasMatch(parsed, /^touch=/) ? isMatchTrue(parsed, /^touch=(.*)/) : void 0, mobile: isMatchTrue(parsed, /^mobile=(.*)/), @@ -107,9 +107,9 @@ function parseOptions (str, modes) { function getNewConfig (configString) { - var { userArgs, modesString } = parseConfig(configString); - var { modes, optionsString } = parseModes(modesString, userArgs); - var options = parseOptions(optionsString, modes); + const { userArgs, modesString } = parseConfig(configString); + const { modes, optionsString } = parseModes(modesString, userArgs); + const options = parseOptions(optionsString, modes); return Object.assign({ userArgs }, modes, options); } diff --git a/src/browser/provider/built-in/chrome/index.js b/src/browser/provider/built-in/chrome/index.js index cfd0cc3e..b26e5f96 100644 --- a/src/browser/provider/built-in/chrome/index.js +++ b/src/browser/provider/built-in/chrome/index.js @@ -14,8 +14,8 @@ export default { isMultiBrowser: false, async openBrowser (browserId, pageUrl, configString) { - var runtimeInfo = await getRuntimeInfo(parseUrl(pageUrl).hostname, configString); - var browserName = this.providerName.replace(':', ''); + const runtimeInfo = await getRuntimeInfo(parseUrl(pageUrl).hostname, configString); + const browserName = this.providerName.replace(':', ''); runtimeInfo.browserId = browserId; runtimeInfo.browserName = browserName; @@ -36,7 +36,7 @@ export default { }, async closeBrowser (browserId) { - var runtimeInfo = this.openedBrowsers[browserId]; + const runtimeInfo = this.openedBrowsers[browserId]; if (cdp.isHeadlessTab(runtimeInfo)) await cdp.closeTab(runtimeInfo); @@ -53,19 +53,19 @@ export default { }, async isLocalBrowser (browserId, configString) { - var config = this.openedBrowsers[browserId] ? this.openedBrowsers[browserId].config : getConfig(configString); + const config = this.openedBrowsers[browserId] ? this.openedBrowsers[browserId].config : getConfig(configString); return !config.headless; }, async takeScreenshot (browserId, path) { - var runtimeInfo = this.openedBrowsers[browserId]; + const runtimeInfo = this.openedBrowsers[browserId]; await cdp.takeScreenshot(path, runtimeInfo); }, async resizeWindow (browserId, width, height, currentWidth, currentHeight) { - var runtimeInfo = this.openedBrowsers[browserId]; + const runtimeInfo = this.openedBrowsers[browserId]; if (runtimeInfo.config.mobile) await cdp.updateMobileViewportSize(runtimeInfo); @@ -84,7 +84,7 @@ export default { }, async hasCustomActionForBrowser (browserId) { - var { config, client } = this.openedBrowsers[browserId]; + const { config, client } = this.openedBrowsers[browserId]; return { hasCloseBrowser: true, diff --git a/src/browser/provider/built-in/firefox/config.js b/src/browser/provider/built-in/firefox/config.js index e6ff1f88..0c443fdf 100644 --- a/src/browser/provider/built-in/firefox/config.js +++ b/src/browser/provider/built-in/firefox/config.js @@ -3,18 +3,18 @@ import { findMatch, isMatchTrue, splitEscaped, parseConfig, getModes, getPathFro const AVAILABLE_MODES = ['userProfile', 'headless']; -var configCache = {}; +const configCache = {}; function hasCustomProfile (userArgs) { return !!(userArgs.match(/-P\s/) || userArgs.match(/-profile\s/)); } function parseModes (modesStr, userArgs) { - var parsed = splitEscaped(modesStr, ':'); - var path = getPathFromParsedModes(parsed, AVAILABLE_MODES); - var detectedModes = getModes(parsed, AVAILABLE_MODES); - var optionsString = parsed.filter(item => !!item).join(':'); - var options = parsed.length ? splitEscaped(optionsString, ';') : []; + const parsed = splitEscaped(modesStr, ':'); + const path = getPathFromParsedModes(parsed, AVAILABLE_MODES); + const detectedModes = getModes(parsed, AVAILABLE_MODES); + const optionsString = parsed.filter(item => !!item).join(':'); + const options = parsed.length ? splitEscaped(optionsString, ';') : []; return { path: path, @@ -27,8 +27,8 @@ function parseModes (modesStr, userArgs) { function getNewConfig (configString) { - var { userArgs, modesString } = parseConfig(configString); - var modes = parseModes(modesString, userArgs); + const { userArgs, modesString } = parseConfig(configString); + const modes = parseModes(modesString, userArgs); return Object.assign({ userArgs }, modes); } diff --git a/src/browser/provider/built-in/firefox/create-temp-profile.js b/src/browser/provider/built-in/firefox/create-temp-profile.js index 5d5283b9..1647f711 100644 --- a/src/browser/provider/built-in/firefox/create-temp-profile.js +++ b/src/browser/provider/built-in/firefox/create-temp-profile.js @@ -4,9 +4,9 @@ import { writeFile } from '../../../../utils/promisified-functions'; async function generatePreferences (profileDir, { marionettePort, config }) { - var prefsFileName = path.join(profileDir, 'user.js'); + const prefsFileName = path.join(profileDir, 'user.js'); - var prefs = [ + let prefs = [ 'user_pref("browser.link.open_newwindow.override.external", 2);', 'user_pref("app.update.enabled", false);', 'user_pref("app.update.auto", false);', diff --git a/src/browser/provider/built-in/firefox/index.js b/src/browser/provider/built-in/firefox/index.js index 92fed99c..ed5aee52 100644 --- a/src/browser/provider/built-in/firefox/index.js +++ b/src/browser/provider/built-in/firefox/index.js @@ -25,8 +25,8 @@ export default { }, async openBrowser (browserId, pageUrl, configString) { - var runtimeInfo = await getRuntimeInfo(configString); - var browserName = this.providerName.replace(':', ''); + const runtimeInfo = await getRuntimeInfo(configString); + const browserName = this.providerName.replace(':', ''); runtimeInfo.browserId = browserId; runtimeInfo.browserName = browserName; @@ -42,8 +42,8 @@ export default { }, async closeBrowser (browserId) { - var runtimeInfo = this.openedBrowsers[browserId]; - var { config, marionetteClient } = runtimeInfo; + const runtimeInfo = this.openedBrowsers[browserId]; + const { config, marionetteClient } = runtimeInfo; if (config.headless) await marionetteClient.quit(); @@ -60,19 +60,19 @@ export default { }, async isLocalBrowser (browserId, configString) { - var config = this.openedBrowsers[browserId] ? this.openedBrowsers[browserId].config : getConfig(configString); + const config = this.openedBrowsers[browserId] ? this.openedBrowsers[browserId].config : getConfig(configString); return !config.headless; }, async takeScreenshot (browserId, path) { - var { marionetteClient } = this.openedBrowsers[browserId]; + const { marionetteClient } = this.openedBrowsers[browserId]; await marionetteClient.takeScreenshot(path); }, async resizeWindow (browserId, width, height) { - var { marionetteClient } = this.openedBrowsers[browserId]; + const { marionetteClient } = this.openedBrowsers[browserId]; await marionetteClient.setWindowSize(width, height); }, @@ -84,7 +84,7 @@ export default { }, async hasCustomActionForBrowser (browserId) { - var { config, marionetteClient } = this.openedBrowsers[browserId]; + const { config, marionetteClient } = this.openedBrowsers[browserId]; return { hasCloseBrowser: true, diff --git a/src/browser/provider/built-in/firefox/marionette-client.js b/src/browser/provider/built-in/firefox/marionette-client.js index d795bd04..3e4db3e2 100644 --- a/src/browser/provider/built-in/firefox/marionette-client.js +++ b/src/browser/provider/built-in/firefox/marionette-client.js @@ -34,7 +34,7 @@ module.exports = class MarionetteClient { async _attemptToConnect (port, host) { this.socket.connect(port, host); - var connectionPromise = Promise.race([ + const connectionPromise = Promise.race([ promisifyEvent(this.socket, 'connect'), promisifyEvent(this.socket, 'error') ]); @@ -50,7 +50,7 @@ module.exports = class MarionetteClient { async _connectSocket (port, host) { const connectionStartTime = Date.now(); - var connected = await this._attemptToConnect(port, host); + let connected = await this._attemptToConnect(port, host); while (!connected && Date.now() - connectionStartTime < CONNECTION_TIMEOUT) connected = await this._attemptToConnect(port, host); @@ -77,7 +77,7 @@ module.exports = class MarionetteClient { _getPacket () { this.getPacketPromise = this.getPacketPromise.then(async () => { - var headerEndIndex = this.buffer.indexOf(HEADER_SEPARATOR); + let headerEndIndex = this.buffer.indexOf(HEADER_SEPARATOR); while (headerEndIndex < 0) { await promisifyEvent(this.events, 'new-data'); @@ -85,15 +85,15 @@ module.exports = class MarionetteClient { headerEndIndex = this.buffer.indexOf(HEADER_SEPARATOR); } - var packet = { + const packet = { length: NaN, body: null }; packet.length = parseInt(this.buffer.toString('utf8', 0, headerEndIndex), 10) || 0; - var bodyStartIndex = headerEndIndex + HEADER_SEPARATOR.length; - var bodyEndIndex = bodyStartIndex + packet.length; + const bodyStartIndex = headerEndIndex + HEADER_SEPARATOR.length; + const bodyEndIndex = bodyStartIndex + packet.length; if (packet.length) { while (this.buffer.length < bodyEndIndex) @@ -112,9 +112,9 @@ module.exports = class MarionetteClient { _sendPacket (payload) { this.sendPacketPromise = this.sendPacketPromise.then(async () => { - var body = [0, this.currentPacketNumber++, payload.command, payload.parameters]; - var serialized = JSON.stringify(body); - var message = Buffer.byteLength(serialized, 'utf8') + HEADER_SEPARATOR + serialized; + const body = [0, this.currentPacketNumber++, payload.command, payload.parameters]; + const serialized = JSON.stringify(body); + const message = Buffer.byteLength(serialized, 'utf8') + HEADER_SEPARATOR + serialized; this._writeSocket(message); }); @@ -127,11 +127,11 @@ module.exports = class MarionetteClient { } async _getResponse (packet) { - var packetNumber = this.currentPacketNumber; + const packetNumber = this.currentPacketNumber; await this._sendPacket(packet); - var responsePacket = await this._getPacket(); + let responsePacket = await this._getPacket(); while (!responsePacket.body || responsePacket.body[1] !== packetNumber) responsePacket = await this._getPacket(); @@ -145,7 +145,7 @@ module.exports = class MarionetteClient { async connect () { await this._connectSocket(this.port, this.host); - var infoPacket = await this._getPacket(); + const infoPacket = await this._getPacket(); this.protocolInfo = { applicationType: infoPacket.body.applicationType, @@ -165,17 +165,17 @@ module.exports = class MarionetteClient { } async takeScreenshot (path) { - var screenshot = await this._getResponse({ command: 'takeScreenshot' }); + const screenshot = await this._getResponse({ command: 'takeScreenshot' }); await writeFile(path, screenshot.value, { encoding: 'base64' }); } async setWindowSize (width, height) { - var { value: pageRect } = await this.executeScript(GET_WINDOW_DIMENSIONS_INFO_SCRIPT); - var attemptCounter = 0; + let { value: pageRect } = await this.executeScript(GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + let attemptCounter = 0; while (attemptCounter++ < MAX_RESIZE_RETRY_COUNT && (pageRect.width !== width || pageRect.height !== height)) { - var currentRect = await this._getResponse({ command: 'getWindowRect' }); + const currentRect = await this._getResponse({ command: 'getWindowRect' }); await this._getResponse({ command: 'setWindowRect', diff --git a/src/browser/provider/index.js b/src/browser/provider/index.js index 2379ec6d..a068263a 100644 --- a/src/browser/provider/index.js +++ b/src/browser/provider/index.js @@ -73,18 +73,18 @@ export default class BrowserProvider { if (!this._isBrowserIdle(browserId)) return; - var title = await this.plugin.runInitScript(browserId, GET_TITLE_SCRIPT); + const title = await this.plugin.runInitScript(browserId, GET_TITLE_SCRIPT); if (!await browserTools.isMaximized(title)) return; - var currentSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); - var etalonSize = subtractSizes(currentSize, RESIZE_DIFF_SIZE); + const currentSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + const etalonSize = subtractSizes(currentSize, RESIZE_DIFF_SIZE); await browserTools.resize(title, currentSize.width, currentSize.height, etalonSize.width, etalonSize.height); - var resizedSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); - var correctionSize = subtractSizes(resizedSize, etalonSize); + let resizedSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + let correctionSize = subtractSizes(resizedSize, etalonSize); await browserTools.resize(title, resizedSize.width, resizedSize.height, etalonSize.width, etalonSize.height); @@ -103,7 +103,7 @@ export default class BrowserProvider { if (!this._isBrowserIdle(browserId)) return; - var sizeInfo = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + const sizeInfo = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); if (this.localBrowsersInfo[browserId]) { this.localBrowsersInfo[browserId].maxScreenSize = { @@ -159,7 +159,7 @@ export default class BrowserProvider { if (!OS.mac) return true; - var maxScreenSize = this._getMaxScreenSize(browserId); + const maxScreenSize = this._getMaxScreenSize(browserId); return width <= maxScreenSize.width && height <= maxScreenSize.height; } @@ -169,7 +169,7 @@ export default class BrowserProvider { } async init () { - var initialized = await this.initPromise; + const initialized = await this.initPromise; if (initialized) return; @@ -189,7 +189,7 @@ export default class BrowserProvider { } async dispose () { - var initialized = await this.initPromise; + const initialized = await this.initPromise; if (!initialized) return; @@ -215,17 +215,17 @@ export default class BrowserProvider { async openBrowser (browserId, pageUrl, browserName) { await this.plugin.openBrowser(browserId, pageUrl, browserName); - var isLocalBrowser = await this.plugin.isLocalBrowser(browserId); + const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); if (isLocalBrowser) await this._ensureBrowserWindowParameters(browserId); } async closeBrowser (browserId) { - var isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - var customActionsInfo = await this.hasCustomActionForBrowser(browserId); - var hasCustomCloseBrowser = customActionsInfo.hasCloseBrowser; - var usePluginsCloseBrowser = hasCustomCloseBrowser || !isLocalBrowser; + const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); + const customActionsInfo = await this.hasCustomActionForBrowser(browserId); + const hasCustomCloseBrowser = customActionsInfo.hasCloseBrowser; + const usePluginsCloseBrowser = hasCustomCloseBrowser || !isLocalBrowser; if (usePluginsCloseBrowser) await this.plugin.closeBrowser(browserId); @@ -245,9 +245,9 @@ export default class BrowserProvider { } async resizeWindow (browserId, width, height, currentWidth, currentHeight) { - var isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - var customActionsInfo = await this.hasCustomActionForBrowser(browserId); - var hasCustomResizeWindow = customActionsInfo.hasResizeWindow; + const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); + const customActionsInfo = await this.hasCustomActionForBrowser(browserId); + const hasCustomResizeWindow = customActionsInfo.hasResizeWindow; if (isLocalBrowser && !hasCustomResizeWindow) { @@ -259,9 +259,9 @@ export default class BrowserProvider { } async canResizeWindowToDimensions (browserId, width, height) { - var isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - var customActionsInfo = await this.hasCustomActionForBrowser(browserId); - var hasCustomCanResizeToDimensions = customActionsInfo.hasCanResizeWindowToDimensions; + const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); + const customActionsInfo = await this.hasCustomActionForBrowser(browserId); + const hasCustomCanResizeToDimensions = customActionsInfo.hasCanResizeWindowToDimensions; if (isLocalBrowser && !hasCustomCanResizeToDimensions) @@ -271,9 +271,9 @@ export default class BrowserProvider { } async maximizeWindow (browserId) { - var isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - var customActionsInfo = await this.hasCustomActionForBrowser(browserId); - var hasCustomMaximizeWindow = customActionsInfo.hasMaximizeWindow; + const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); + const customActionsInfo = await this.hasCustomActionForBrowser(browserId); + const hasCustomMaximizeWindow = customActionsInfo.hasMaximizeWindow; if (isLocalBrowser && !hasCustomMaximizeWindow) return await this._maximizeLocalBrowserWindow(browserId); @@ -282,9 +282,9 @@ export default class BrowserProvider { } async takeScreenshot (browserId, screenshotPath, pageWidth, pageHeight) { - var isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - var customActionsInfo = await this.hasCustomActionForBrowser(browserId); - var hasCustomTakeScreenshot = customActionsInfo.hasTakeScreenshot; + const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); + const customActionsInfo = await this.hasCustomActionForBrowser(browserId); + const hasCustomTakeScreenshot = customActionsInfo.hasTakeScreenshot; if (isLocalBrowser && !hasCustomTakeScreenshot) { await this._takeLocalBrowserScreenshot(browserId, screenshotPath, pageWidth, pageHeight); diff --git a/src/browser/provider/plugin-host.js b/src/browser/provider/plugin-host.js index 553e1309..6d834df7 100644 --- a/src/browser/provider/plugin-host.js +++ b/src/browser/provider/plugin-host.js @@ -25,13 +25,13 @@ export default class BrowserProviderPluginHost { } runInitScript (browserId, code) { - var connection = BrowserConnection.getById(browserId); + const connection = BrowserConnection.getById(browserId); return connection.runInitScript(`(${code})()`); } waitForConnectionReady (browserId) { - var connection = BrowserConnection.getById(browserId); + const connection = BrowserConnection.getById(browserId); if (connection.ready) return Promise.resolve(); @@ -40,26 +40,26 @@ export default class BrowserProviderPluginHost { } reportWarning (browserId, ...args) { - var connection = BrowserConnection.getById(browserId); + const connection = BrowserConnection.getById(browserId); connection.addWarning(...args); } setUserAgentMetaInfo (browserId, message) { - var connection = BrowserConnection.getById(browserId); + const connection = BrowserConnection.getById(browserId); connection.setProviderMetaInfo(message); } async closeLocalBrowser (browserId) { - var connection = BrowserConnection.getById(browserId); + const connection = BrowserConnection.getById(browserId); await connection.provider._ensureBrowserWindowDescriptor(browserId); await connection.provider._closeLocalBrowser(browserId); } async resizeLocalBrowserWindow (browserId, width, height, currentWidth, currentHeight) { - var connection = BrowserConnection.getById(browserId); + const connection = BrowserConnection.getById(browserId); await connection.provider._ensureBrowserWindowParameters(browserId); await connection.provider._resizeLocalBrowserWindow(browserId, width, height, currentWidth, currentHeight); diff --git a/src/browser/provider/pool.js b/src/browser/provider/pool.js index 6be6eed2..a3e73ff9 100644 --- a/src/browser/provider/pool.js +++ b/src/browser/provider/pool.js @@ -13,23 +13,23 @@ export default { providersCache: {}, async _handlePathAndCmd (alias) { - var browserName = JSON.stringify(alias); - var providerName = 'path'; - var provider = await this.getProvider(providerName); + const browserName = JSON.stringify(alias); + const providerName = 'path'; + const provider = await this.getProvider(providerName); return { provider, providerName, browserName }; }, async _parseAliasString (alias) { - var providerRegExpMatch = BROWSER_PROVIDER_RE.exec(alias); + const providerRegExpMatch = BROWSER_PROVIDER_RE.exec(alias); if (!providerRegExpMatch) throw new GeneralError(MESSAGE.cantFindBrowser, alias); - var providerName = providerRegExpMatch[1]; - var browserName = providerRegExpMatch[2] || ''; + let providerName = providerRegExpMatch[1]; + let browserName = providerRegExpMatch[2] || ''; - var provider = await this.getProvider(providerName); + let provider = await this.getProvider(providerName); if (!provider && providerRegExpMatch[2]) provider = await this.getProvider(providerName + ':'); @@ -54,7 +54,7 @@ export default { }, async _getInfoForAllBrowserNames (provider, providerName) { - var allBrowserNames = provider.isMultiBrowser ? + const allBrowserNames = provider.isMultiBrowser ? await provider.getBrowserList() : []; @@ -67,7 +67,7 @@ export default { _getProviderModule (providerName, moduleName) { try { - var providerObject = require(moduleName); + const providerObject = require(moduleName); this.addProvider(providerName, providerObject); return this._getProviderFromCache(providerName); @@ -82,7 +82,7 @@ export default { }, _getBuiltinProvider (providerName) { - var providerObject = BUILT_IN_PROVIDERS[providerName]; + const providerObject = BUILT_IN_PROVIDERS[providerName]; if (!providerObject) return null; @@ -96,9 +96,9 @@ export default { if (alias instanceof BrowserConnection) return alias; - var browserInfo = await this._parseAlias(alias); + const browserInfo = await this._parseAlias(alias); - var { provider, providerName, browserName } = browserInfo; + const { provider, providerName, browserName } = browserInfo; if (browserName === 'all') return await this._getInfoForAllBrowserNames(provider, providerName); @@ -129,7 +129,7 @@ export default { providerName = parsedProviderName.providerName; - var provider = this._getProviderFromCache(providerName) || + const provider = this._getProviderFromCache(providerName) || this._getProviderModule(providerName, moduleName) || this._getBuiltinProvider(providerName); diff --git a/src/cli/cli.js b/src/cli/cli.js index 93feb81d..ed7f59f7 100644 --- a/src/cli/cli.js +++ b/src/cli/cli.js @@ -10,9 +10,9 @@ import remotesWizard from './remotes-wizard'; import createTestCafe from '../'; -var showMessageOnExit = true; -var exitMessageShown = false; -var exiting = false; +let showMessageOnExit = true; +let exitMessageShown = false; +let exiting = false; function exitHandler (terminationLevel) { if (showMessageOnExit && !exitMessageShown) { @@ -44,7 +44,7 @@ function exit (code) { function error (err) { log.hideSpinner(); - var message = null; + let message = null; // HACK: workaround for the `instanceof` problem // (see: http://stackoverflow.com/questions/33870684/why-doesnt-instanceof-work-on-instances-of-error-subclasses-under-babel-node) @@ -64,21 +64,21 @@ function error (err) { } async function runTests (argParser) { - var opts = argParser.opts; - var port1 = opts.ports && opts.ports[0]; - var port2 = opts.ports && opts.ports[1]; - var externalProxyHost = opts.proxy; - var proxyBypass = opts.proxyBypass; + const opts = argParser.opts; + const port1 = opts.ports && opts.ports[0]; + const port2 = opts.ports && opts.ports[1]; + const externalProxyHost = opts.proxy; + const proxyBypass = opts.proxyBypass; log.showSpinner(); const testCafe = await createTestCafe(opts.hostname, port1, port2, opts.ssl, opts.dev); - var concurrency = argParser.concurrency || 1; - var remoteBrowsers = await remotesWizard(testCafe, argParser.remoteCount, opts.qrCode); - var browsers = argParser.browsers.concat(remoteBrowsers); - var runner = testCafe.createRunner(); - var failed = 0; - var reporters = argParser.opts.reporters.map(r => { + const concurrency = argParser.concurrency || 1; + const remoteBrowsers = await remotesWizard(testCafe, argParser.remoteCount, opts.qrCode); + const browsers = argParser.browsers.concat(remoteBrowsers); + const runner = testCafe.createRunner(); + let failed = 0; + const reporters = argParser.opts.reporters.map(r => { return { name: r.name, outStream: r.outFile ? fs.createWriteStream(r.outFile) : void 0 @@ -111,13 +111,13 @@ async function runTests (argParser) { } async function listBrowsers (providerName = 'locally-installed') { - var provider = await browserProviderPool.getProvider(providerName); + const provider = await browserProviderPool.getProvider(providerName); if (!provider) throw new GeneralError(MESSAGE.browserProviderNotFound, providerName); if (provider.isMultiBrowser) { - var browserNames = await provider.getBrowserList(); + const browserNames = await provider.getBrowserList(); await browserProviderPool.dispose(); @@ -133,12 +133,12 @@ async function listBrowsers (providerName = 'locally-installed') { } (async function cli () { - var terminationHandler = new TerminationHandler(); + const terminationHandler = new TerminationHandler(); terminationHandler.on(TerminationHandler.TERMINATION_LEVEL_INCREASED_EVENT, exitHandler); try { - var argParser = new CliArgumentParser(); + const argParser = new CliArgumentParser(); await argParser.parse(process.argv); diff --git a/src/cli/log.js b/src/cli/log.js index ab0026ec..c4d99ac3 100644 --- a/src/cli/log.js +++ b/src/cli/log.js @@ -14,10 +14,10 @@ export default { // NOTE: we can use the spinner only if stderr is a TTY and we are not in CI environment (e.g. TravisCI), // otherwise we can't repaint animation frames. Thanks https://github.com/sindresorhus/ora for insight. if (this.isAnimated) { - var spinnerFrame = elegantSpinner(); + const spinnerFrame = elegantSpinner(); this.animation = setInterval(() => { - var frame = chalk.cyan(spinnerFrame()); + const frame = chalk.cyan(spinnerFrame()); logUpdate.stderr(frame); }, 50); diff --git a/src/cli/remotes-wizard.js b/src/cli/remotes-wizard.js index 1657a041..5459146e 100644 --- a/src/cli/remotes-wizard.js +++ b/src/cli/remotes-wizard.js @@ -7,12 +7,12 @@ import dedent from 'dedent'; export default async function (testCafe, remoteCount, showQRCode) { - var connectionPromises = []; + const connectionPromises = []; if (remoteCount) { log.hideSpinner(); - var description = dedent(` + const description = dedent(` Connecting ${remoteCount} remote browser(s)... Navigate to the following URL from each remote browser. `); @@ -22,14 +22,14 @@ export default async function (testCafe, remoteCount, showQRCode) { if (showQRCode) log.write('You can either enter the URL or scan the QR-code.'); - var connectionUrl = testCafe.browserConnectionGateway.connectUrl; + const connectionUrl = testCafe.browserConnectionGateway.connectUrl; log.write(`Connect URL: ${chalk.underline.blue(connectionUrl)}`); if (showQRCode) qrcode.generate(connectionUrl); - for (var i = 0; i < remoteCount; i++) { + for (let i = 0; i < remoteCount; i++) { connectionPromises.push(testCafe .createBrowserConnection() .then(bc => promisifyEvent(bc, 'ready').then(() => bc)) diff --git a/src/client-functions/client-function-builder.js b/src/client-functions/client-function-builder.js index d505072e..7014cee3 100644 --- a/src/client-functions/client-function-builder.js +++ b/src/client-functions/client-function-builder.js @@ -42,7 +42,7 @@ export default class ClientFunctionBuilder { if (typeof options === 'object') options = assign({}, this.options, options); - var builder = new this.constructor(this.fn, options, { + const builder = new this.constructor(this.fn, options, { instantiation: 'with', execution: this.callsiteNames.execution }); @@ -64,15 +64,15 @@ export default class ClientFunctionBuilder { } getFunction () { - var builder = this; + const builder = this; - var clientFn = function __$$clientFunction$$ () { - var testRun = builder._getTestRun(); - var callsite = getCallsiteForMethod(builder.callsiteNames.execution); - var args = []; + const clientFn = function __$$clientFunction$$ () { + const testRun = builder._getTestRun(); + const callsite = getCallsiteForMethod(builder.callsiteNames.execution); + const args = []; // OPTIMIZATION: don't leak `arguments` object. - for (var i = 0; i < arguments.length; i++) + for (let i = 0; i < arguments.length; i++) args.push(arguments[i]); return builder._executeCommand(args, testRun, callsite); @@ -84,8 +84,8 @@ export default class ClientFunctionBuilder { } getCommand (args) { - var encodedArgs = this.replicator.encode(args); - var encodedDependencies = this.replicator.encode(this.getFunctionDependencies()); + const encodedArgs = this.replicator.encode(args); + const encodedDependencies = this.replicator.encode(this.getFunctionDependencies()); return this._createTestRunCommand(encodedArgs, encodedDependencies); } @@ -119,11 +119,11 @@ export default class ClientFunctionBuilder { _executeCommand (args, testRun, callsite) { // NOTE: should be kept outside of lazy promise to preserve // correct callsite in case of replicator error. - var command = this.getCommand(args); + const command = this.getCommand(args); return ReExecutablePromise.fromFn(async () => { if (!testRun) { - var err = new ClientFunctionAPIError(this.callsiteNames.execution, this.callsiteNames.instantiation, MESSAGE.clientFunctionCantResolveTestRun); + const err = new ClientFunctionAPIError(this.callsiteNames.execution, this.callsiteNames.instantiation, MESSAGE.clientFunctionCantResolveTestRun); // NOTE: force callsite here, because more likely it will // be impossible to resolve it by method name from a lazy promise. @@ -132,7 +132,7 @@ export default class ClientFunctionBuilder { throw err; } - var result = await testRun.executeCommand(command, callsite); + const result = await testRun.executeCommand(command, callsite); return this._processResult(result, args); }); @@ -147,7 +147,7 @@ export default class ClientFunctionBuilder { if (!isNullOrUndefined(options.boundTestRun)) { // NOTE: `boundTestRun` can be either TestController or TestRun instance. - var boundTestRun = options.boundTestRun.testRun || options.boundTestRun; + const boundTestRun = options.boundTestRun.testRun || options.boundTestRun; if (!boundTestRun[testRunMarker]) throw new APIError(this.callsiteNames.instantiation, MESSAGE.invalidClientFunctionTestRunBinding); diff --git a/src/client-functions/replicator.js b/src/client-functions/replicator.js index e7231c8d..232da0e6 100644 --- a/src/client-functions/replicator.js +++ b/src/client-functions/replicator.js @@ -8,7 +8,7 @@ export function createReplicator (transforms) { // to JSON with a command or command result. // Therefore there is no need to do additional job here, // so we use identity functions for serialization. - var replicator = new Replicator({ + const replicator = new Replicator({ serialize: identity, deserialize: identity }); @@ -28,7 +28,7 @@ export class FunctionTransform { } toSerializable (fn) { - var clientFnBuilder = fn[functionBuilderSymbol]; + const clientFnBuilder = fn[functionBuilderSymbol]; if (clientFnBuilder) { return { diff --git a/src/client-functions/selectors/create-snapshot-methods.js b/src/client-functions/selectors/create-snapshot-methods.js index 41c89e8a..8a70ca16 100644 --- a/src/client-functions/selectors/create-snapshot-methods.js +++ b/src/client-functions/selectors/create-snapshot-methods.js @@ -1,5 +1,5 @@ export default function createSnapshotMethods (snapshot) { - var isElementSnapshot = !!snapshot.tagName; + const isElementSnapshot = !!snapshot.tagName; if (isElementSnapshot) { snapshot.hasClass = name => snapshot.classNames.indexOf(name) > -1; diff --git a/src/client-functions/selectors/selector-attribute-filter.js b/src/client-functions/selectors/selector-attribute-filter.js index 2698c30b..e8f69497 100644 --- a/src/client-functions/selectors/selector-attribute-filter.js +++ b/src/client-functions/selectors/selector-attribute-filter.js @@ -8,12 +8,12 @@ export default function selectorAttributeFilter (node, index, originNode, attrNa if (node.nodeType !== 1) return false; - var attributes = node.attributes; - var attr = null; + const attributes = node.attributes; + let attr = null; - var check = (actual, expect) => typeof expect === 'string' ? expect === actual : expect.test(actual); + const check = (actual, expect) => typeof expect === 'string' ? expect === actual : expect.test(actual); - for (var i = 0; i < attributes.length; i++) { + for (let i = 0; i < attributes.length; i++) { attr = attributes[i]; if (check(attr.nodeName, attrName) && (!attrValue || check(attr.nodeValue, attrValue))) diff --git a/src/client-functions/selectors/selector-text-filter.js b/src/client-functions/selectors/selector-text-filter.js index 4a009e23..d94d922c 100644 --- a/src/client-functions/selectors/selector-text-filter.js +++ b/src/client-functions/selectors/selector-text-filter.js @@ -7,9 +7,9 @@ export default function selectorTextFilter (node, index, originNode, textFilter) { function hasChildrenWithText (parentNode) { - var cnCount = parentNode.childNodes.length; + const cnCount = parentNode.childNodes.length; - for (var i = 0; i < cnCount; i++) { + for (let i = 0; i < cnCount; i++) { if (selectorTextFilter(parentNode.childNodes[i], index, originNode, textFilter)) return true; } @@ -25,12 +25,12 @@ export default function selectorTextFilter (node, index, originNode, textFilter) // Element if (node.nodeType === 1) { - var text = node.innerText; + let text = node.innerText; // NOTE: In Firefox,
- \ No newline at end of file + diff --git a/test/functional/fixtures/regression/gh-2282/pages/authorized.html b/test/functional/fixtures/regression/gh-2282/pages/authorized.html index 746d421c..24fb7943 100644 --- a/test/functional/fixtures/regression/gh-2282/pages/authorized.html +++ b/test/functional/fixtures/regression/gh-2282/pages/authorized.html @@ -8,7 +8,7 @@ if (!document.cookie || document.cookie === 'auth=false') location.href = './login.html'; else { - var result = document.getElementById('result'); + const result = document.getElementById('result'); result.innerHTML = 'logged' } @@ -24,4 +24,4 @@
no access
Reset cookie
- \ No newline at end of file + diff --git a/test/functional/fixtures/regression/gh-2450/testcafe-fixtures/index.js b/test/functional/fixtures/regression/gh-2450/testcafe-fixtures/index.js index d208663a..e4d103b8 100644 --- a/test/functional/fixtures/regression/gh-2450/testcafe-fixtures/index.js +++ b/test/functional/fixtures/regression/gh-2450/testcafe-fixtures/index.js @@ -11,7 +11,7 @@ const doScroll = ClientFunction(() => { }); const changeFixed = ClientFunction(() => { - var inversed = 'inversed'; + const inversed = 'inversed'; document.getElementById('fixedTop').className = inversed; document.getElementById('fixedLeft').className = inversed; diff --git a/test/functional/fixtures/regression/gh-423/pages/index.html b/test/functional/fixtures/regression/gh-423/pages/index.html index a1e078f7..14961fc0 100644 --- a/test/functional/fixtures/regression/gh-423/pages/index.html +++ b/test/functional/fixtures/regression/gh-423/pages/index.html @@ -21,85 +21,87 @@
- \ No newline at end of file + diff --git a/test/functional/fixtures/regression/gh-637/test.js b/test/functional/fixtures/regression/gh-637/test.js index 782b922b..d30155ab 100644 --- a/test/functional/fixtures/regression/gh-637/test.js +++ b/test/functional/fixtures/regression/gh-637/test.js @@ -1,16 +1,16 @@ -var tmp = require('tmp'); -var path = require('path'); -var copy = require('recursive-copy'); +const tmp = require('tmp'); +const path = require('path'); +const copy = require('recursive-copy'); describe('[Regression](GH-637)', function () { it("Should let test file locate babel-runtime if it's not installed on global or test file node_modules lookup scope", function () { tmp.setGracefulCleanup(); - var tmpDir = tmp.dirSync().name; - var srcDir = path.join(__dirname, './data'); + const tmpDir = tmp.dirSync().name; + const srcDir = path.join(__dirname, './data'); return copy(srcDir, tmpDir).then(function () { - var testFile = path.join(tmpDir, './testfile.js'); + const testFile = path.join(tmpDir, './testfile.js'); return runTests(testFile, 'Some test', { only: 'chrome' }); }); diff --git a/test/functional/fixtures/regression/gh-711/testcafe-fixtures/typing-in-content-editable-test.js b/test/functional/fixtures/regression/gh-711/testcafe-fixtures/typing-in-content-editable-test.js index 41b818e1..c0faab9f 100644 --- a/test/functional/fixtures/regression/gh-711/testcafe-fixtures/typing-in-content-editable-test.js +++ b/test/functional/fixtures/regression/gh-711/testcafe-fixtures/typing-in-content-editable-test.js @@ -6,8 +6,8 @@ fixture `GH-711` .page `http://localhost:3000/fixtures/regression/gh-711/pages/index.html`; -var getBodyPlainText = ClientFunction(() => { - var plainTextRE = /\s+|\n|\r/g; +const getBodyPlainText = ClientFunction(() => { + const plainTextRE = /\s+|\n|\r/g; return document.body.textContent.replace(plainTextRE, ''); }); @@ -22,7 +22,7 @@ test('Typing in contentEditable body', async t => { .click('body') .typeText('body', 'test'); - var actualText = await getBodyPlainText(); + const actualText = await getBodyPlainText(); expect(actualText.indexOf('test') !== -1).to.be.ok; }); @@ -32,8 +32,8 @@ test('Typing in contentEditable body with not-contentEditable children', async t .selectText('body') .typeText('body', 'test'); - var actualText = await getBodyPlainText(); - var expectedText = 'div1testdiv3'; + const actualText = await getBodyPlainText(); + const expectedText = 'div1testdiv3'; expect(actualText.indexOf(expectedText) !== -1).to.be.ok; }); diff --git a/test/functional/fixtures/regression/gh-743/testcafe-fixtures/two-tests-in-a-fixture.js b/test/functional/fixtures/regression/gh-743/testcafe-fixtures/two-tests-in-a-fixture.js index 19735595..8ec91b6d 100644 --- a/test/functional/fixtures/regression/gh-743/testcafe-fixtures/two-tests-in-a-fixture.js +++ b/test/functional/fixtures/regression/gh-743/testcafe-fixtures/two-tests-in-a-fixture.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; fixture `GH-743`; -var secondStarted = false; +let secondStarted = false; test('First test', async t => { await t.wait(100); diff --git a/test/functional/fixtures/regression/gh-751/pages/index.html b/test/functional/fixtures/regression/gh-751/pages/index.html index 51d5a3ab..e030469b 100644 --- a/test/functional/fixtures/regression/gh-751/pages/index.html +++ b/test/functional/fixtures/regression/gh-751/pages/index.html @@ -15,7 +15,7 @@ window.dblclickEvents.push(Date.now()); } - var dblclickBtn = document.getElementById('dblclick'); + const dblclickBtn = document.getElementById('dblclick'); dblclickBtn.addEventListener('mouseup', logDblclickPerformance); dblclickBtn.addEventListener('click', logDblclickPerformance); @@ -31,13 +31,13 @@ } function doHardWork () { - var startTime = Date.now(); + const startTime = Date.now(); while (Date.now() < startTime + window.HARD_WORK_TIME) { } } - var hardWorkMousedownBtn = document.getElementById('hardWorkMousedown'); + const hardWorkMousedownBtn = document.getElementById('hardWorkMousedown'); hardWorkMousedownBtn.addEventListener('mousedown', logClickPerformance); hardWorkMousedownBtn.addEventListener('mouseup', logClickPerformance); diff --git a/test/functional/fixtures/regression/gh-751/testcafe-fixtures/index-test.js b/test/functional/fixtures/regression/gh-751/testcafe-fixtures/index-test.js index 22a82ebc..4c995595 100644 --- a/test/functional/fixtures/regression/gh-751/testcafe-fixtures/index-test.js +++ b/test/functional/fixtures/regression/gh-751/testcafe-fixtures/index-test.js @@ -8,12 +8,13 @@ fixture `GH-751` test('Test dblclick performance', async t => { await t.doubleClick('#dblclick'); - var dblclickPerformanceLog = await ClientFunction(() => window.dblclickEvents)(); - var firstMouseupTime = null; - var firstClickTime = null; - var secondMouseupTime = null; - var secondClickTime = null; - var dblclickTime = null; + const dblclickPerformanceLog = await ClientFunction(() => window.dblclickEvents)(); + + let firstMouseupTime = null; + let firstClickTime = null; + let secondMouseupTime = null; + let secondClickTime = null; + let dblclickTime = null; [firstMouseupTime, firstClickTime, secondMouseupTime, secondClickTime, dblclickTime] = dblclickPerformanceLog; @@ -27,7 +28,7 @@ test('Test click performance with hard work', async t => { await t.click('#hardWorkMousedown'); - var [mousedownTime, mouseupTime] = await ClientFunction(() => window.clickEvents)(); + const [mousedownTime, mouseupTime] = await ClientFunction(() => window.clickEvents)(); expect(mouseupTime - mousedownTime).is.most(HARD_WORK_TIME + 30); }); diff --git a/test/functional/fixtures/regression/gh-770/pages/index.html b/test/functional/fixtures/regression/gh-770/pages/index.html index e7a38e1c..d96db06d 100644 --- a/test/functional/fixtures/regression/gh-770/pages/index.html +++ b/test/functional/fixtures/regression/gh-770/pages/index.html @@ -11,12 +11,14 @@
- \ No newline at end of file + diff --git a/test/functional/fixtures/regression/gh-845/testcafe-fixtures/index-test.js b/test/functional/fixtures/regression/gh-845/testcafe-fixtures/index-test.js index 8756b6c8..7a8b13d3 100644 --- a/test/functional/fixtures/regression/gh-845/testcafe-fixtures/index-test.js +++ b/test/functional/fixtures/regression/gh-845/testcafe-fixtures/index-test.js @@ -16,7 +16,7 @@ test('Click on a download link', async t => { await t.click('#link'); - var delay = await getDelay(); + const delay = await getDelay(); expect(delay).to.be.below(MAX_UNLOADING_TIMEOUT); }); @@ -28,7 +28,7 @@ test('Click on a download link in iframe', async t => { await t.click('#link'); - var delay = await getDelay(); + const delay = await getDelay(); expect(delay).to.be.below(MAX_UNLOADING_TIMEOUT); }); diff --git a/test/functional/fixtures/regression/gh-847/pages/index.html b/test/functional/fixtures/regression/gh-847/pages/index.html index 92f91931..6ff80f4a 100644 --- a/test/functional/fixtures/regression/gh-847/pages/index.html +++ b/test/functional/fixtures/regression/gh-847/pages/index.html @@ -23,7 +23,7 @@ diff --git a/test/functional/fixtures/regression/gh-850/pages/index.html b/test/functional/fixtures/regression/gh-850/pages/index.html index 64ea4242..fe5b97c5 100644 --- a/test/functional/fixtures/regression/gh-850/pages/index.html +++ b/test/functional/fixtures/regression/gh-850/pages/index.html @@ -12,11 +12,11 @@ - \ No newline at end of file + diff --git a/test/functional/fixtures/regression/gh-851/pages/index.html b/test/functional/fixtures/regression/gh-851/pages/index.html index fef4c5ea..5d8b57c4 100644 --- a/test/functional/fixtures/regression/gh-851/pages/index.html +++ b/test/functional/fixtures/regression/gh-851/pages/index.html @@ -9,69 +9,71 @@
- \ No newline at end of file + diff --git a/test/functional/fixtures/regression/gh-851/testcafe-fixtures/index.test.js b/test/functional/fixtures/regression/gh-851/testcafe-fixtures/index.test.js index 3c6b874e..9ccae79d 100644 --- a/test/functional/fixtures/regression/gh-851/testcafe-fixtures/index.test.js +++ b/test/functional/fixtures/regression/gh-851/testcafe-fixtures/index.test.js @@ -7,81 +7,81 @@ fixture `GH-851` const getEventStorage = ClientFunction(() => window.eventStorage); test('Raise click for common parent', async t => { - var expectedEvents = ['body click']; + const expectedEvents = ['body click']; await t.click('#div1'); - var actualEvents = await getEventStorage(); + const actualEvents = await getEventStorage(); expect(actualEvents).deep.eql(expectedEvents); }); test('Raise click for top element', async t => { - var expectedEvents = ['body click']; + const expectedEvents = ['body click']; await t.click('#div2'); - var actualEvents = await getEventStorage(); + const actualEvents = await getEventStorage(); expect(actualEvents).deep.eql(expectedEvents); }); test('Raise dblclick for common element', async t => { - var expectedEvents = ['div click', 'body click', 'body dblclick']; + const expectedEvents = ['div click', 'body click', 'body dblclick']; await t.doubleClick('#div3'); - var actualEvents = await getEventStorage(); + const actualEvents = await getEventStorage(); expect(actualEvents).deep.eql(expectedEvents); }); test('Raise dblclick for a top element', async t => { - var expectedEvents = ['div click', 'body click', 'body dblclick']; + const expectedEvents = ['div click', 'body click', 'body dblclick']; await t.doubleClick('#div4'); - var actualEvents = await getEventStorage(); + const actualEvents = await getEventStorage(); expect(actualEvents).deep.eql(expectedEvents); }); test("Don't raise click for common parent", async t => { - var expectedEvents = []; + const expectedEvents = []; await t.click('#div1'); - var actualEvents = await getEventStorage(); + const actualEvents = await getEventStorage(); expect(actualEvents).deep.eql(expectedEvents); }); test("Don't raise click for top element", async t => { - var expectedEvents = []; + const expectedEvents = []; await t.click('#div2'); - var actualEvents = await getEventStorage(); + const actualEvents = await getEventStorage(); expect(actualEvents).deep.eql(expectedEvents); }); test("Don't raise dblclick for common element", async t => { - var expectedEvents = ['div click']; + const expectedEvents = ['div click']; await t.doubleClick('#div3'); - var actualEvents = await getEventStorage(); + const actualEvents = await getEventStorage(); expect(actualEvents).deep.eql(expectedEvents); }); test("Don't raise dblclick for a top element", async t => { - var expectedEvents = ['div click']; + const expectedEvents = ['div click']; await t.doubleClick('#div4'); - var actualEvents = await getEventStorage(); + const actualEvents = await getEventStorage(); expect(actualEvents).deep.eql(expectedEvents); }); diff --git a/test/functional/fixtures/regression/gh-883/pages/index.html b/test/functional/fixtures/regression/gh-883/pages/index.html index 405ae2cc..e00c0366 100644 --- a/test/functional/fixtures/regression/gh-883/pages/index.html +++ b/test/functional/fixtures/regression/gh-883/pages/index.html @@ -8,14 +8,15 @@
FILLER
TARGET
- \ No newline at end of file + diff --git a/test/functional/fixtures/regression/gh-889/testcafe-fixtures/index.test.js b/test/functional/fixtures/regression/gh-889/testcafe-fixtures/index.test.js index d4e68e44..03cc8192 100644 --- a/test/functional/fixtures/regression/gh-889/testcafe-fixtures/index.test.js +++ b/test/functional/fixtures/regression/gh-889/testcafe-fixtures/index.test.js @@ -5,8 +5,8 @@ import { expect } from 'chai'; fixture `GH-889` .page `http://localhost:3000/fixtures/regression/gh-889/pages/index.html`; -var getTableFocusEventCount = ClientFunction(() => window.tableFocusEventCount); -var getTableBlurEventCount = ClientFunction(() => window.tableBlurEventCount); +const getTableFocusEventCount = ClientFunction(() => window.tableFocusEventCount); +const getTableBlurEventCount = ClientFunction(() => window.tableBlurEventCount); test('Click on children of table', async t => { await t @@ -18,8 +18,8 @@ test('Click on children of table', async t => { }); test('Click on children of table (for IE)', async t => { - var getFirstTableDataFocusEventCount = ClientFunction(() => window.firstTableDataFocusEventCount); - var getSecondTableDataFocusEventCount = ClientFunction(() => window.secondTableDataFocusEventCount); + const getFirstTableDataFocusEventCount = ClientFunction(() => window.firstTableDataFocusEventCount); + const getSecondTableDataFocusEventCount = ClientFunction(() => window.secondTableDataFocusEventCount); await t .click('#td1') diff --git a/test/functional/fixtures/regression/gh-965/test.js b/test/functional/fixtures/regression/gh-965/test.js index 0bf425ef..4f3f91ca 100644 --- a/test/functional/fixtures/regression/gh-965/test.js +++ b/test/functional/fixtures/regression/gh-965/test.js @@ -1,4 +1,4 @@ -var expect = require('chai').expect; +const expect = require('chai').expect; describe('[Regression](GH-965)', function () { diff --git a/test/functional/fixtures/regression/gh-973/pages/index.html b/test/functional/fixtures/regression/gh-973/pages/index.html index f193d586..c72de539 100644 --- a/test/functional/fixtures/regression/gh-973/pages/index.html +++ b/test/functional/fixtures/regression/gh-973/pages/index.html @@ -24,14 +24,15 @@
Lower right target
- \ No newline at end of file + diff --git a/test/functional/fixtures/run-options/selector-timeout/test.js b/test/functional/fixtures/run-options/selector-timeout/test.js index 0ef4b74b..11d832e8 100644 --- a/test/functional/fixtures/run-options/selector-timeout/test.js +++ b/test/functional/fixtures/run-options/selector-timeout/test.js @@ -1,4 +1,4 @@ -var expect = require('chai').expect; +const expect = require('chai').expect; describe('Selector timeout', function () { it('Should pass if selector timeout exceeds time required for the element to appear', function () { diff --git a/test/functional/fixtures/run-options/speed/testcafe-fixtures/speed-test.js b/test/functional/fixtures/run-options/speed/testcafe-fixtures/speed-test.js index 6a6f8850..d0f85527 100644 --- a/test/functional/fixtures/run-options/speed/testcafe-fixtures/speed-test.js +++ b/test/functional/fixtures/run-options/speed/testcafe-fixtures/speed-test.js @@ -7,7 +7,7 @@ test('Decrease speed', async t => { // NOTE: do the first click to wait while the page is loaded await t.click('#button1'); - var startTime = Date.now(); + const startTime = Date.now(); await t.click('#button1'); @@ -20,7 +20,7 @@ test('Decrease speed in iframe', async t => { .switchToIframe('#iframe') .click('#button1'); - var startTime = Date.now(); + const startTime = Date.now(); await t.click('#button1'); @@ -31,7 +31,7 @@ test('Default speed', async t => { // NOTE: do the first click to wait while the page is loaded await t.click('#button1'); - var startTime = Date.now(); + const startTime = Date.now(); await t.click('#button1'); diff --git a/test/functional/fixtures/screenshots-on-fails/pages/index.html b/test/functional/fixtures/screenshots-on-fails/pages/index.html index 30bac9fb..3985f155 100644 --- a/test/functional/fixtures/screenshots-on-fails/pages/index.html +++ b/test/functional/fixtures/screenshots-on-fails/pages/index.html @@ -6,7 +6,7 @@ + TestCafé + + +Just text +Wrapped in span +
+ + \ No newline at end of file diff --git a/test/functional/fixtures/regression/gh-2861/test.js b/test/functional/fixtures/regression/gh-2861/test.js new file mode 100644 index 00000000..8930f1f7 --- /dev/null +++ b/test/functional/fixtures/regression/gh-2861/test.js @@ -0,0 +1,5 @@ +describe('[Regression](GH-2861) - Should not hang on custom element click', function () { + it('Click on custom element', function () { + return runTests('testcafe-fixtures/index.js', null, { only: ['chrome'] }); + }); +}); diff --git a/test/functional/fixtures/regression/gh-2861/testcafe-fixtures/index.js b/test/functional/fixtures/regression/gh-2861/testcafe-fixtures/index.js new file mode 100644 index 00000000..1218a08f --- /dev/null +++ b/test/functional/fixtures/regression/gh-2861/testcafe-fixtures/index.js @@ -0,0 +1,18 @@ +import { Selector } from 'testcafe'; + +fixture `GH-2861` + .page `http://localhost:3000/fixtures/regression/gh-2861/pages/index.html`; + +const btn1 = Selector('#btn1'); +const btn2 = Selector('#btn2'); +const result = Selector('#result'); + +test('Should not hang on custom element click', async (t) => { + await t + .click(btn1) + .expect(result.innerText).eql('') + .click(btn1, { offsetX: 1, offsetY: 1 }) + .expect(result.innerText).eql('clicked') + .click(btn2) + .expect(result.innerText).eql('clickedclicked'); +}); From 0c0ea758db6230a653ca175750efb78750ab27d3 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Thu, 11 Oct 2018 19:01:08 +0300 Subject: [PATCH 115/184] Fix unstable legacy test (#2963) --- .../basic/before-unload-handlers.test.js | 9 +++++-- .../before-unload-handling/pages/index.html | 8 ++++++- .../before-unload-handling/test.js | 8 +++---- .../testcafe-fixtures/in-iframe.test.js | 22 +++++++++++++---- .../testcafe-fixtures/index.test.js | 24 ++++++++++++++----- 5 files changed, 53 insertions(+), 18 deletions(-) diff --git a/test/functional/fixtures/api/legacy/smoke/testcafe-fixtures/basic/before-unload-handlers.test.js b/test/functional/fixtures/api/legacy/smoke/testcafe-fixtures/basic/before-unload-handlers.test.js index eeb0ad1e..0371a10f 100644 --- a/test/functional/fixtures/api/legacy/smoke/testcafe-fixtures/basic/before-unload-handlers.test.js +++ b/test/functional/fixtures/api/legacy/smoke/testcafe-fixtures/basic/before-unload-handlers.test.js @@ -9,8 +9,13 @@ act.click('#enableBeforeUnload'); }), - '2.Click link "This page"': inIFrame('#iframe', function () { + '2.Click the reload button': inIFrame('#iframe', function () { + act.click('#reload'); + }), + + '3.Wait for dialog': inIFrame('#iframe', function () { handleBeforeUnload(); - act.click(':containsExcludeChildren(This page)'); + + act.wait(30000); }) }; diff --git a/test/functional/legacy-fixtures/before-unload-handling/pages/index.html b/test/functional/legacy-fixtures/before-unload-handling/pages/index.html index 0ba8ead2..c8bf3337 100644 --- a/test/functional/legacy-fixtures/before-unload-handling/pages/index.html +++ b/test/functional/legacy-fixtures/before-unload-handling/pages/index.html @@ -4,9 +4,15 @@ Index -This page + + + diff --git a/test/functional/fixtures/api/es-next/page-load-timeout/pages/window-load.html b/test/functional/fixtures/api/es-next/page-load-timeout/pages/window-load.html index 716a41f3..cd57a56c 100644 --- a/test/functional/fixtures/api/es-next/page-load-timeout/pages/window-load.html +++ b/test/functional/fixtures/api/es-next/page-load-timeout/pages/window-load.html @@ -4,11 +4,11 @@ PageLoadTimeout (window load) - + diff --git a/test/functional/fixtures/api/es-next/page-load-timeout/test.js b/test/functional/fixtures/api/es-next/page-load-timeout/test.js index 31bdda37..5bf18f0d 100644 --- a/test/functional/fixtures/api/es-next/page-load-timeout/test.js +++ b/test/functional/fixtures/api/es-next/page-load-timeout/test.js @@ -1,6 +1,6 @@ describe('Should wait for the window.load event if necessary', function () { it('Should wait for the window.load event if there are user event handlers for it (set timeout via an option)', function () { - return runTests('testcafe-fixtures/index-test.js', 'Wait for window.load (set timeout via an option)', { pageLoadTimeout: 3000 }); + return runTests('testcafe-fixtures/index-test.js', 'Wait for window.load (set timeout via an option)', { pageLoadTimeout: 10000 }); }); it('Should wait for the window.load event if there are user event handlers for it (set timeout via `t`)', function () { diff --git a/test/functional/fixtures/api/es-next/page-load-timeout/testcafe-fixtures/index-test.js b/test/functional/fixtures/api/es-next/page-load-timeout/testcafe-fixtures/index-test.js index eea50def..f7dd50e8 100644 --- a/test/functional/fixtures/api/es-next/page-load-timeout/testcafe-fixtures/index-test.js +++ b/test/functional/fixtures/api/es-next/page-load-timeout/testcafe-fixtures/index-test.js @@ -11,7 +11,7 @@ test test ('Wait for window.load (set timeout via `t`)', async t => { await t - .setPageLoadTimeout(3000) + .setPageLoadTimeout(10000) .navigateTo('http://localhost:3000/fixtures/api/es-next/page-load-timeout/pages/window-load.html') .expect(ClientFunction(() => window.loadEventRaised)()).ok('Test started before window.load', { timeout: 0 }); }); @@ -19,7 +19,7 @@ test test ('Wait for window.load in iframe', async t => { await t - .setPageLoadTimeout(3000) + .setPageLoadTimeout(10000) .navigateTo('http://localhost:3000/fixtures/api/es-next/page-load-timeout/pages/with-iframe.html') .switchToIframe('#iframe') .expect(ClientFunction(() => window.loadEventRaised)()).ok('Test started before window.load', { timeout: 0 }); diff --git a/test/functional/fixtures/concurrency/testcafe-fixtures/multibrowser-concurrent-test.js b/test/functional/fixtures/concurrency/testcafe-fixtures/multibrowser-concurrent-test.js index d30f9f72..43ade9c5 100644 --- a/test/functional/fixtures/concurrency/testcafe-fixtures/multibrowser-concurrent-test.js +++ b/test/functional/fixtures/concurrency/testcafe-fixtures/multibrowser-concurrent-test.js @@ -30,7 +30,7 @@ test('Short test', async t => { }); test('Results', async t => { - await t.wait(6000); + await t.wait(10000); await t.expect(Object.keys(timelines).length).gt(1); diff --git a/test/functional/fixtures/regression/gh-1057/pages/hiddenByFixedParent.html b/test/functional/fixtures/regression/gh-1057/pages/hiddenByFixedParent.html index c148f5cf..cad9ce83 100644 --- a/test/functional/fixtures/regression/gh-1057/pages/hiddenByFixedParent.html +++ b/test/functional/fixtures/regression/gh-1057/pages/hiddenByFixedParent.html @@ -13,8 +13,8 @@ position: absolute; left: 500px; top: 500px; - width: 20px; - height: 20px; + width: 200px; + height: 200px; background-color: red; } @@ -22,8 +22,8 @@ position: absolute; left: 2500px; top: 2500px; - width: 20px; - height: 20px; + width: 200px; + height: 200px; background-color: blue; } diff --git a/test/functional/fixtures/regression/gh-1057/test.js b/test/functional/fixtures/regression/gh-1057/test.js index 297469e1..3d9d27d5 100644 --- a/test/functional/fixtures/regression/gh-1057/test.js +++ b/test/functional/fixtures/regression/gh-1057/test.js @@ -6,6 +6,14 @@ describe('[Regression](GH-1057) - hidden by fixed parent', function () { skip: 'iphone,ipad,android' }); }); + + it('The target element should not be under the element with position:fixed after scroll when using custom offsets', function () { + return runTests('testcafe-fixtures/hiddenByFixedParent.js', 'gh-1057 with custom offsets', { + // NOTE: https://github.com/DevExpress/testcafe/issues/1237 + // TODO: Android disabled because of https://github.com/DevExpress/testcafe/issues/1492 + skip: 'iphone,ipad,android' + }); + }); }); describe('[Regression](GH-1057) - hidden by fixed ancestor', function () { diff --git a/test/functional/fixtures/regression/gh-1057/testcafe-fixtures/hiddenByFixedParent.js b/test/functional/fixtures/regression/gh-1057/testcafe-fixtures/hiddenByFixedParent.js index da59badf..302bdf06 100644 --- a/test/functional/fixtures/regression/gh-1057/testcafe-fixtures/hiddenByFixedParent.js +++ b/test/functional/fixtures/regression/gh-1057/testcafe-fixtures/hiddenByFixedParent.js @@ -12,3 +12,11 @@ test('gh-1057', async t => { .click('#target1') .expect(targetsClicked()).ok(); }); + +test('gh-1057 with custom offsets', async t => { + // NOTE: scrolling has issues in iOS Simulator https://github.com/DevExpress/testcafe/issues/1237 + await t + .click('#target2', { offsetX: -1, offsetY: -1 }) + .click('#target1', { offsetX: 1, offsetY: 1 }) + .expect(targetsClicked()).ok(); +}); diff --git a/test/functional/fixtures/regression/gh-2067/test.js b/test/functional/fixtures/regression/gh-2067/test.js index 2d018013..a23ebca8 100644 --- a/test/functional/fixtures/regression/gh-2067/test.js +++ b/test/functional/fixtures/regression/gh-2067/test.js @@ -4,7 +4,7 @@ describe('[Regression](GH-2067) - Radio button navigation by keyboard', function }); it('nonamed - chrome', function () { - return runTests('testcafe-fixtures/index.js', 'nonamed - chrome', { only: ['chrome', 'chrome-osx', 'android'] }); + return runTests('testcafe-fixtures/index.js', 'nonamed - chrome', { only: ['chrome', 'chrome-osx'] }); }); it('nonamed - ie, firefox', function () { diff --git a/test/server/runner-test.js b/test/server/runner-test.js index f6565d77..7c9f83fd 100644 --- a/test/server/runner-test.js +++ b/test/server/runner-test.js @@ -225,6 +225,22 @@ describe('Runner', () => { 'screenshots path pattern:\n \t":" at index 7\n'); }); }); + + it('Should allow to use relative paths in the screenshots base path and path patterns', () => { + const storedRunTaskFn = runner._runTask; + + runner._runTask = function () { + runner._runTask = storedRunTaskFn; + + return Promise.resolve({}); + }; + + return runner + .browsers(connection) + .screenshots('..', false, '${BROWSER}/./${TEST}') + .src('test/server/data/test-suites/basic/testfile2.js') + .run(); + }); }); describe('.src()', () => { diff --git a/test/server/test-run-error-formatting-test.js b/test/server/test-run-error-formatting-test.js index fcdfc39c..d9983e08 100644 --- a/test/server/test-run-error-formatting-test.js +++ b/test/server/test-run-error-formatting-test.js @@ -330,7 +330,7 @@ describe('Error formatting', () => { }); it('Should format "forbiddenCharactersInScreenshotPathError"', () => { - assertErrorMessage('forbidden-characters-in-screenshot-path-error', new ForbiddenCharactersInScreenshotPathError('/root/bla:bla', [{ char: ':', index: 9 }])); + assertErrorMessage('forbidden-characters-in-screenshot-path-error', new ForbiddenCharactersInScreenshotPathError('/root/bla:bla', [{ chars: ':', index: 9 }])); }); it('Should format "invalidElementScreenshotDimensionsError"', () => { From b849c2a1bf25f1000083262dee9d7fa5afeed412 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 24 Oct 2018 17:33:13 +0300 Subject: [PATCH 142/184] Bump version (v0.23.0-alpha.1) (#3024) --- azure-pipelines.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ba9f0545..0ef034a4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -14,7 +14,7 @@ steps: versionSpec: '11.x' - bash: | - npm install || npm install || npm install + npm install --no-progress --loglevel error npm test displayName: 'Run tests' condition: not(variables['isDocCommit']) diff --git a/package.json b/package.json index 7ca9fada..e45ff026 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.22.1-alpha.3", + "version": "0.23.0-alpha.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From 863fb48eef9cc5ea94655318639e2c49b7bb1976 Mon Sep 17 00:00:00 2001 From: Helen Dikareva Date: Thu, 25 Oct 2018 15:23:20 +0300 Subject: [PATCH 143/184] Fix options order (#3025) --- .../using-testcafe/command-line-interface.md | 36 +++++++++---------- src/cli/argument-parser.js | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 8bd4cddd..1266a58f 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -46,8 +46,8 @@ testcafe [options] * [--ports \](#--ports-port1port2) * [--hostname \](#--hostname-name) * [--proxy \](#--proxy-host) - * [--ssl \](#--ssl-options) * [--proxy-bypass \](#--proxy-bypass-rules) + * [--ssl \](#--ssl-options) * [--dev](#--dev) * [--qr-code](#--qr-code) * [--sf, --stop-on-first-fail](#--sf---stop-on-first-fail) @@ -555,23 +555,6 @@ You can also specify authentication credentials with the proxy host. testcafe chrome my-tests/**/*.js --proxy username:password@proxy.mycorp.com ``` -### --ssl \ - -Provides options that allow you to establish an HTTPS connection between the client browser and the TestCafe server. - -The `options` parameter contains options required to initialize -[a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). -The most commonly used SSL options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in Node.js documentation. -Options are specified in a semicolon-separated string. - -```sh -testcafe --ssl pfx=path/to/file.pfx;rejectUnauthorized=true;... -``` - -Provide the `--ssl` flag if the tested webpage uses browser features that require -secure origin ([Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API), [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API), [ApplePaySession](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession), [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto), etc). -See [Connect to the TestCafe Server over HTTPS](common-concepts/connect-to-the-testcafe-server-over-https.md) for more information. - ### --proxy-bypass \ Specifies the resources accessed bypassing the proxy server. @@ -598,6 +581,23 @@ The `*.mycompany.com` value means that all URLs in the `mycompany.com` subdomain testcafe chrome my-tests/**/*.js --proxy proxy.corp.mycompany.com --proxy-bypass *.mycompany.com ``` +### --ssl \ + +Provides options that allow you to establish an HTTPS connection between the client browser and the TestCafe server. + +The `options` parameter contains options required to initialize +[a Node.js HTTPS server](https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener). +The most commonly used SSL options are described in the [TLS topic](https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options) in Node.js documentation. +Options are specified in a semicolon-separated string. + +```sh +testcafe --ssl pfx=path/to/file.pfx;rejectUnauthorized=true;... +``` + +Provide the `--ssl` flag if the tested webpage uses browser features that require +secure origin ([Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API), [Geolocation API](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API), [ApplePaySession](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession), [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto), etc). +See [Connect to the TestCafe Server over HTTPS](common-concepts/connect-to-the-testcafe-server-over-https.md) for more information. + ### --dev Enables mechanisms to log and diagnose errors. You should enable this option if you are going to contact TestCafe Support to report an issue. diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index 95c14d67..157796ec 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -98,8 +98,8 @@ export default class CLIArgumentParser { .option('--ports ', 'specify custom port numbers') .option('--hostname ', 'specify the hostname') .option('--proxy ', 'specify the host of the proxy server') - .option('--ssl ', 'specify SSL options to run TestCafe proxy server over the HTTPS protocol') .option('--proxy-bypass ', 'specify a comma-separated list of rules that define URLs accessed bypassing the proxy server') + .option('--ssl ', 'specify SSL options to run TestCafe proxy server over the HTTPS protocol') .option('--disable-page-reloads', 'disable page reloads between tests') .option('--dev', 'enables mechanisms to log and diagnose errors') .option('--qr-code', 'outputs QR-code that repeats URLs used to connect the remote browsers') From 4d3547172ec967a0c290918ab43d2ef1995d367d Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Thu, 25 Oct 2018 15:56:15 +0300 Subject: [PATCH 144/184] Bump version (v0.23.0-alpha.2) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e45ff026..502d02ff 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.23.0-alpha.1", + "version": "0.23.0-alpha.2", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From 02ee09be8340b3794f7d1a3a5d04958c85e6022b Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Thu, 25 Oct 2018 17:32:40 +0300 Subject: [PATCH 145/184] [docs] Add changelog v0.23.0 (#2982) --- CHANGELOG.md | 55 ++++++++++++++++++ .../using-testcafe/command-line-interface.md | 2 +- .../programming-interface/runner.md | 2 +- .../images/client-error-stack-report.png | Bin 0 -> 139677 bytes 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 docs/articles/images/client-error-stack-report.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 4badb622..049e89c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,60 @@ # Changelog +## v0.23.0 (2018-10-18) + +### Enhancements + +#### :gear: Stop Test Run After the First Test Fail ([#1323](https://github.com/DevExpress/testcafe/issues/1323)) + +You can now configure TestCafe to stop the entire test run after the first test fail. This saves your time when you fix problems with your tests one by one. + +Specify the [--sf](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--sf---stop-on-first-fail) flag to enable this feature when you run tests from the command line. + +```sh +testcafe chrome my-tests --sf +``` + +In the API, use the [stopOnFirstFail](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#run) option. + +```js +runner.run({ stopOnFirstFail: true }) +``` + +#### :gear: View the JavaScript Errors' Stack Traces in Reports ([#2043](https://github.com/DevExpress/testcafe/issues/2043)) + +Now when a JavaScript error occurs on the tested webpage, the test run report includes a stack trace for this error (only if the [--skip-js-errors](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#-e---skip-js-errors) option is disabled). + +![A report that contains a stack trace for a client JS error](docs/articles/images/client-error-stack-report.png) + +#### :gear: Browsers are Automatically Restarted When They Stop Responding ([#1815](https://github.com/DevExpress/testcafe/issues/1815)) + +If a browser stops responding while it executes tests, TestCafe restarts the browser and reruns the current test in a new browser instance. +If the same problem occurs with this test two more times, the test run finishes and an error is thrown. + +### Bug Fixes + +* An error message about an unawaited call to an async function is no longer displayed when an uncaught error occurs ([#2557](https://github.com/DevExpress/testcafe/issues/2557)) +* A request hook is no longer added multiple times when a filter rule is used ([#2650](https://github.com/DevExpress/testcafe/issues/2650)) +* Screenshot links in test run reports now contain paths specified by the `--screenshot-pattern` option ([#2726](https://github.com/DevExpress/testcafe/issues/2726)) +* Assertion chains no longer produce unhandled promise rejections ([#2852](https://github.com/DevExpress/testcafe/issues/2852)) +* The `moment` loader now works correctly in the Jest environment ([#2500](https://github.com/DevExpress/testcafe/issues/2500)) +* TestCafe no longer hangs if the screenshot directory contains forbidden symbols ([#681](https://github.com/DevExpress/testcafe/issues/681)) +* The `--ssl` option's parameters are now parsed correctly ([#2924](https://github.com/DevExpress/testcafe/issues/2924)) +* TestCafe now throws a meaningful error if an assertion method is missing ([#1063](https://github.com/DevExpress/testcafe/issues/1063)) +* TestCafe no longer hangs when it clicks a custom element ([#2861](https://github.com/DevExpress/testcafe/issues/2861)) +* TestCafe now performs keyboard navigation between radio buttons/groups in a way that matches the native browser behavior ([#2067](https://github.com/DevExpress/testcafe/issues/2067), [#2045](https://github.com/DevExpress/testcafe/issues/2045)) +* The `fetch` method can now be used with data URLs ([#2865](https://github.com/DevExpress/testcafe/issues/2865)) +* The `switchToIframe` function no longer throws an error ([#2956](https://github.com/DevExpress/testcafe/issues/2956)) +* TestCafe can now scroll through fixed elements when the action has custom offsets ([#2978](https://github.com/DevExpress/testcafe/issues/2978)) +* You can now specify the current directory or its parent directories as the base path to store screenshots ([#2975](https://github.com/DevExpress/testcafe/issues/2975)) +* Tests no longer hang up when you try to debug in headless browsers ([#2846](https://github.com/DevExpress/testcafe/issues/2846)) +* The `removeEventListener` function now works correctly when an object is passed as its third argument ([testcafe-hammerhead/#1737](https://github.com/DevExpress/testcafe-hammerhead/issues/1737)) +* Hammerhead no longer adds the `event` property to a null `contentWindow` in IE11 ([testcafe-hammerhead/#1684](https://github.com/DevExpress/testcafe-hammerhead/issues/1684)) +* The browser no longer resets connection with the server for no reason ([testcafe-hammerhead/#1647](https://github.com/DevExpress/testcafe-hammerhead/issues/1647)) +* Hammerhead now stringifies values correctly before outputting them to the console ([testcafe-hammerhead/#1750](https://github.com/DevExpress/testcafe-hammerhead/issues/1750)) +* A document fragment from the top window can now be correctly appended to an iframe ([testcafe-hammerhead/#912](https://github.com/DevExpress/testcafe-hammerhead/issues/912)) +* Lifecycle callbacks that result from the `document.registerElement` method are no longer called twice ([testcafe-hammerhead/#695](https://github.com/DevExpress/testcafe-hammerhead/issues/695)) + ## v0.22.0 (2018-9-3) ### Enhancements diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 1266a58f..1d6812d4 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -59,7 +59,7 @@ testcafe [options] > where tests do not always execute correctly. If a browser stops responding while it executes tests, TestCafe restarts the browser and reruns the current test in a new browser instance. -If the same problem occurs with this test two more times, the test run finishes. +If the same problem occurs with this test two more times, the test run finishes and an error is thrown. ## Browser List diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index d28f2b80..9bba77e3 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -450,7 +450,7 @@ createTestCafe('localhost', 1337, 1338) ``` If a browser stops responding while it executes tests, TestCafe restarts the browser and reruns the current test in a new browser instance. -If the same problem occurs with this test two more times, the test run finishes. +If the same problem occurs with this test two more times, the test run finishes and an error is thrown. #### Cancelling Test Tasks diff --git a/docs/articles/images/client-error-stack-report.png b/docs/articles/images/client-error-stack-report.png new file mode 100644 index 0000000000000000000000000000000000000000..8486bafbae22c7015d00a69aa42b41c65f0f9092 GIT binary patch literal 139677 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 z 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 Date: Thu, 25 Oct 2018 17:42:32 +0300 Subject: [PATCH 146/184] [docs] Add an example about importing CF dependencies (#2999) --- .../obtaining-data-from-the-client.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/articles/documentation/test-api/obtaining-data-from-the-client.md b/docs/articles/documentation/test-api/obtaining-data-from-the-client.md index cef4fd95..fda06a32 100644 --- a/docs/articles/documentation/test-api/obtaining-data-from-the-client.md +++ b/docs/articles/documentation/test-api/obtaining-data-from-the-client.md @@ -20,6 +20,7 @@ This topic contains the following sections. * [Executing Client Functions](#executing-client-functions) * [Options](#options) * [One-Time Client Code Execution](#one-time-client-code-execution) +* [Import Functions to be Used as Client Function Dependencies](#import-functions-to-be-used-as-client-function-dependencies) * [Calling Client Functions from Node.js Callbacks](#calling-client-functions-from-nodejs-callbacks) * [Limitations](#limitations) @@ -176,6 +177,41 @@ test('My Test', async t => { }); ``` +## Import Functions to be Used as Client Function Dependencies + +Assume you have a JS file `utils.js` with a function you need to use as a client function dependency in your test file. + +**utils.js** + +```js +export function getDocumentURI() { + return document.documentURI; +} +``` + +Note that TestCafe internally processes test files with [Babel](https://babeljs.io). To avoid issues caused by code transpiling, use the [require](https://nodejs.org/api/modules.html#modules_require) function instead of the `import` statement to import client function dependencies. + +**test.js** + +```js +import { ClientFunction } from 'testcafe'; + +const getDocumentURI = require('./utils.js').getDocumentURI; + +fixture `My fixture` + .page `http://devexpress.github.io/testcafe/example/`; + +test('My test', async t => { + const getUri = ClientFunction(() => { + return getDocumentURI(); + }, { dependencies: { getDocumentURI } }); + + const uri = await getUri(); + + await t.expect(uri).eql('http://devexpress.github.io/testcafe/example/'); +}); +``` + ## Calling Client Functions from Node.js Callbacks Client functions need access to the [test controller](test-code-structure.md#test-controller) to be executed. From 53c8c3d184b1d7d07b4e4f86510054133709c98c Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Thu, 25 Oct 2018 17:44:30 +0300 Subject: [PATCH 147/184] [docs] Add actions to the page model (#2995) --- .../documentation/recipes/using-page-model.md | 290 ++++++++++++------ 1 file changed, 201 insertions(+), 89 deletions(-) diff --git a/docs/articles/documentation/recipes/using-page-model.md b/docs/articles/documentation/recipes/using-page-model.md index 2f3028b9..5ddabaf5 100644 --- a/docs/articles/documentation/recipes/using-page-model.md +++ b/docs/articles/documentation/recipes/using-page-model.md @@ -8,6 +8,18 @@ permalink: /documentation/recipes/using-page-model.html [Page Model](http://martinfowler.com/bliki/PageObject.html) is a test automation pattern that allows you to create an abstraction of the tested page and use it in test code to refer to page elements. +* [Why Use Page Model](#why-use-page-model) +* [Create a Page Model](#create-a-page-model) + * [Step 1 - Declare a Page Model Class](#step-1---declare-a-page-model-class) + * [Step 2 - Add a Page Element to the Page Model](#step-2---add-a-page-element-to-the-page-model) + * [Step 3 - Write a Test That Uses the Page Model](#step-3---write-a-test-that-uses-the-page-model) + * [Step 4 - Add a New Class for Check Boxes](#step-4---add-a-new-class-for-check-boxes) + * [Step 5 - Add a List of Check Boxes to the Page Model](#step-5---add-a-list-of-check-boxes-to-the-page-model) + * [Step 6 - Write a Test That Iterates Through Check Boxes](#step-6---write-a-test-that-iterates-through-check-boxes) + * [Step 7 - Add Actions to the Page Model](#step-7---add-actions-to-the-page-model) + * [Step 8 - Write a Test That Calls Actions From the Page Model](#step-8---write-a-test-that-calls-actions-from-the-page-model) +* [Page Model Example](#page-model-example) + ## Why Use Page Model Consider the following fixture with two tests: one that types and edits @@ -51,137 +63,230 @@ Generally speaking, the Page Model pattern allows you to follow the separation of concerns principle - you keep page representation in the Page Model, while tests remain focused on the behavior. -## Creating a Page Model +## Create a Page Model -1. Begin with a new `.js` file and declare the `Page` class there. +### Step 1 - Declare a Page Model Class - ```js - export default class Page { - constructor () { - } +Begin with a new `.js` file and declare the `Page` class there. + +```js +export default class Page { + constructor () { } - ``` +} +``` - This class will contain the Page Model, so name the file `page-model.js`. +This class will contain the Page Model, so name the file `page-model.js`. -2. Add the `Developer Name` input element to the model. To do this, - introduce the `nameInput` property and assign a [selector](../test-api/selecting-page-elements/selectors/README.md) to it. +### Step 2 - Add a Page Element to the Page Model - ```js - import { Selector } from 'testcafe'; +Add the `Developer Name` input element to the model. To do this, +introduce the `nameInput` property and assign a [selector](../test-api/selecting-page-elements/selectors/README.md) to it. + +```js +import { Selector } from 'testcafe'; - export default class Page { - constructor () { - this.nameInput = Selector('#developer-name'); - } +export default class Page { + constructor () { + this.nameInput = Selector('#developer-name'); } - ``` +} +``` -3. In the test file, import `page-model.js` and create an instance of the `Page` class. - After that, you can use the `page.nameInput` property to identify the `Developer Name` input element. +### Step 3 - Write a Test That Uses the Page Model - ```js - import Page from './page-model'; +In the test file, import `page-model.js` and create an instance of the `Page` class. +After that, you can use the `page.nameInput` property to identify the `Developer Name` input element. - const page = new Page(); +```js +import Page from './page-model'; - fixture `My fixture` - .page `https://devexpress.github.io/testcafe/example/`; +const page = new Page(); - test('Text typing basics', async t => { - await t - .typeText(page.nameInput, 'Peter') - .typeText(page.nameInput, 'Paker', { replace: true }) - .typeText(page.nameInput, 'r', { caretPos: 2 }) - .expect(page.nameInput.value).eql('Parker'); - }); - ``` +fixture `My fixture` + .page `https://devexpress.github.io/testcafe/example/`; -4. Add check boxes from the Features section to the Page Model. +test('Text typing basics', async t => { + await t + .typeText(page.nameInput, 'Peter') + .typeText(page.nameInput, 'Paker', { replace: true }) + .typeText(page.nameInput, 'r', { caretPos: 2 }) + .expect(page.nameInput.value).eql('Parker'); +}); +``` - As long as each item in the Features section contains a check box and a label, - introduce a new class `Feature` with two properties: `label` and `checkbox`. +### Step 4 - Add a New Class for Check Boxes - ```js - import { Selector } from 'testcafe'; +Add check boxes from the Features section to the Page Model. + +As long as each item in the Features section contains a check box and a label, +introduce a new class `Feature` with two properties: `label` and `checkbox`. - const label = Selector('label'); +```js +import { Selector } from 'testcafe'; + +const label = Selector('label'); - class Feature { - constructor (text) { - this.label = label.withText(text); - this.checkbox = this.label.find('input[type=checkbox]'); - } +class Feature { + constructor (text) { + this.label = label.withText(text); + this.checkbox = this.label.find('input[type=checkbox]'); } +} - export default class Page { - constructor () { - this.nameInput = Selector('#developer-name'); - } +export default class Page { + constructor () { + this.nameInput = Selector('#developer-name'); } - ``` +} +``` -5. In the `Page` class, add the `featureList` property with an array of `Feature` objects. +### Step 5 - Add a List of Check Boxes to the Page Model - ```js - import { Selector } from 'testcafe'; +In the `Page` class, add the `featureList` property with an array of `Feature` objects. + +```js +import { Selector } from 'testcafe'; - const label = Selector('label'); +const label = Selector('label'); - class Feature { - constructor (text) { - this.label = label.withText(text); - this.checkbox = this.label.find('input[type=checkbox]'); - } +class Feature { + constructor (text) { + this.label = label.withText(text); + this.checkbox = this.label.find('input[type=checkbox]'); } +} - export default class Page { - constructor () { - this.nameInput = Selector('#developer-name'); - this.featureList = [ - new Feature('Support for testing on remote devices'), - new Feature('Re-using existing JavaScript code for testing'), - new Feature('Easy embedding into a Continuous integration system') - ]; - } +export default class Page { + constructor () { + this.nameInput = Selector('#developer-name'); + this.featureList = [ + new Feature('Support for testing on remote devices'), + new Feature('Re-using existing JavaScript code for testing'), + new Feature('Easy embedding into a Continuous integration system') + ]; } - ``` +} +``` + +Organizing check boxes in an array makes the page model semantically correct and simplifies iterating through the check boxes. + +### Step 6 - Write a Test That Iterates Through Check Boxes + +The second test now boils down to a single loop. + +```js +import Page from './page-model'; - Organizing check boxes in an array makes the page model semantically correct and simplifies iterating through the check boxes. +fixture `My fixture` + .page `https://devexpress.github.io/testcafe/example/`; -6. The second test now boils down to a single loop. +const page = new Page(); + +test('Text typing basics', async t => { + await t + .typeText(page.nameInput, 'Peter') + .typeText(page.nameInput, 'Paker', { replace: true }) + .typeText(page.nameInput, 'r', { caretPos: 2 }) + .expect(page.nameInput.value).eql('Parker'); +}); + +test('Click check boxes and then verify their state', async t => { + for (const feature of page.featureList) { + await t + .click(feature.label) + .expect(feature.checkbox.checked).ok(); + } +}); +``` + +### Step 7 - Add Actions to the Page Model + +Add an action that enters the developer name and clicks the Submit button. + +1. Import `t`, a [test controller](../test-api/test-code-structure.md#test-controller), from the `testcafe` module. ```js - import Page from './page-model'; + import { Selector, t } from 'testcafe'; + ``` - fixture `My fixture` - .page `https://devexpress.github.io/testcafe/example/`; +2. Add a Submit button to the page model. - const page = new Page(); + ```js + this.submitButton = Selector('#submit-button'); + ``` + +3. Declare an [asynchronous function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) in the `Page` class. This function uses the test controller to perform several actions on the tested page: enter the developer name and click the Submit button. - test('Text typing basics', async t => { + ```js + async submitName (name) { await t - .typeText(page.nameInput, 'Peter') - .typeText(page.nameInput, 'Paker', { replace: true }) - .typeText(page.nameInput, 'r', { caretPos: 2 }) - .expect(page.nameInput.value).eql('Parker'); - }); - - test('Click check boxes and then verify their state', async t => { - for (const feature of page.featureList) { - await t - .click(feature.label) - .expect(feature.checkbox.checked).ok(); - } - }); + .typeText(this.nameInput, name) + .click(this.submitButton); + } ``` -**Example** +Here is how the page model looks now. -This sample shows a page model for the example page at [https://devexpress.github.io/testcafe/example/](https://devexpress.github.io/testcafe/example/). +```js +import { Selector, t } from 'testcafe'; + +const label = Selector('label'); + +class Feature { + constructor (text) { + this.label = label.withText(text); + this.checkbox = this.label.find('input[type=checkbox]'); + } +} + +export default class Page { + constructor () { + this.nameInput = Selector('#developer-name'); + + this.featureList = [ + new Feature('Support for testing on remote devices'), + new Feature('Re-using existing JavaScript code for testing'), + new Feature('Easy embedding into a Continuous integration system') + ]; + + this.submitButton = Selector('#submit-button'); + } + + async submitName (name) { + await t + .typeText(this.nameInput, name) + .click(this.submitButton); + } +} +``` + +### Step 8 - Write a Test That Calls Actions From the Page Model + +Now write a test that calls `page.submitName` and checks the message on the Thank You page. + +```js +test('Submit a developer name and check the header', async t => { + const header = Selector('#article-header'); + + await page.submitName('Peter'); + + await t.expect(header.innerText).eql('Thank you, Peter!'); +}); +``` + +This test works with a different page for which there is no page model. That is why it uses a selector. Don't forget to import it to the test file. ```js import { Selector } from 'testcafe'; +``` + +## Page Model Example + +This sample shows a page model for the example page at [https://devexpress.github.io/testcafe/example/](https://devexpress.github.io/testcafe/example/). + +```js +import { Selector, t } from 'testcafe'; const label = Selector('label'); @@ -229,6 +334,13 @@ export default class Page { this.interfaceSelect = Selector('#preferred-interface'); this.interfaceSelectOption = this.interfaceSelect.find('option'); + this.submitButton = Selector('#submit-button'); + } + + async submitName (name) { + await t + .typeText(this.nameInput, name) + .click(this.submitButton); } } ``` \ No newline at end of file From bf84558f7b6db5e4f156b26d51f1375f6979e199 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Thu, 25 Oct 2018 18:30:54 +0300 Subject: [PATCH 148/184] Add an announcement blog post for v0.23.0 (#3033) --- .../2018-10-25-testcafe-v0-23-0-released.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docs/articles/blog/2018-10-25-testcafe-v0-23-0-released.md diff --git a/docs/articles/blog/2018-10-25-testcafe-v0-23-0-released.md b/docs/articles/blog/2018-10-25-testcafe-v0-23-0-released.md new file mode 100644 index 00000000..d6de7f34 --- /dev/null +++ b/docs/articles/blog/2018-10-25-testcafe-v0-23-0-released.md @@ -0,0 +1,63 @@ +--- +layout: post +title: TestCafe v0.23.0 Released +permalink: /blog/:title.html +--- +# TestCafe v0.23.0 Released + +Stop a test run after the first test fail, view JavaScript errors' stack trace in test run reports and let TestCafe restart browsers when they stop responding. + + + +## Enhancements + +### ⚙ Stop Test Run After the First Test Fail ([#1323](https://github.com/DevExpress/testcafe/issues/1323)) + +You can now configure TestCafe to stop the entire test run after the first test fail. This saves your time when you fix problems with your tests one by one. + +Specify the [--sf](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--sf---stop-on-first-fail) flag to enable this feature when you run tests from the command line. + +```sh +testcafe chrome my-tests --sf +``` + +In the API, use the [stopOnFirstFail](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#run) option. + +```js +runner.run({ stopOnFirstFail: true }) +``` + +### ⚙ View the JavaScript Errors' Stack Traces in Reports ([#2043](https://github.com/DevExpress/testcafe/issues/2043)) + +Now when a JavaScript error occurs on the tested webpage, the test run report includes a stack trace for this error (only if the [--skip-js-errors](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#-e---skip-js-errors) option is disabled). + +![A report that contains a stack trace for a client JS error](../images/client-error-stack-report.png) + +### ⚙ Browsers are Automatically Restarted When They Stop Responding ([#1815](https://github.com/DevExpress/testcafe/issues/1815)) + +If a browser stops responding while it executes tests, TestCafe restarts the browser and reruns the current test in a new browser instance. +If the same problem occurs with this test two more times, the test run finishes and an error is thrown. + +## Bug Fixes + +* An error message about an unawaited call to an async function is no longer displayed when an uncaught error occurs ([#2557](https://github.com/DevExpress/testcafe/issues/2557)) +* A request hook is no longer added multiple times when a filter rule is used ([#2650](https://github.com/DevExpress/testcafe/issues/2650)) +* Screenshot links in test run reports now contain paths specified by the `--screenshot-pattern` option ([#2726](https://github.com/DevExpress/testcafe/issues/2726)) +* Assertion chains no longer produce unhandled promise rejections ([#2852](https://github.com/DevExpress/testcafe/issues/2852)) +* The `moment` loader now works correctly in the Jest environment ([#2500](https://github.com/DevExpress/testcafe/issues/2500)) +* TestCafe no longer hangs if the screenshot directory contains forbidden symbols ([#681](https://github.com/DevExpress/testcafe/issues/681)) +* The `--ssl` option's parameters are now parsed correctly ([#2924](https://github.com/DevExpress/testcafe/issues/2924)) +* TestCafe now throws a meaningful error if an assertion method is missing ([#1063](https://github.com/DevExpress/testcafe/issues/1063)) +* TestCafe no longer hangs when it clicks a custom element ([#2861](https://github.com/DevExpress/testcafe/issues/2861)) +* TestCafe now performs keyboard navigation between radio buttons/groups in a way that matches the native browser behavior ([#2067](https://github.com/DevExpress/testcafe/issues/2067), [#2045](https://github.com/DevExpress/testcafe/issues/2045)) +* The `fetch` method can now be used with data URLs ([#2865](https://github.com/DevExpress/testcafe/issues/2865)) +* The `switchToIframe` function no longer throws an error ([#2956](https://github.com/DevExpress/testcafe/issues/2956)) +* TestCafe can now scroll through fixed elements when the action has custom offsets ([#2978](https://github.com/DevExpress/testcafe/issues/2978)) +* You can now specify the current directory or its parent directories as the base path to store screenshots ([#2975](https://github.com/DevExpress/testcafe/issues/2975)) +* Tests no longer hang up when you try to debug in headless browsers ([#2846](https://github.com/DevExpress/testcafe/issues/2846)) +* The `removeEventListener` function now works correctly when an object is passed as its third argument ([testcafe-hammerhead/#1737](https://github.com/DevExpress/testcafe-hammerhead/issues/1737)) +* Hammerhead no longer adds the `event` property to a null `contentWindow` in IE11 ([testcafe-hammerhead/#1684](https://github.com/DevExpress/testcafe-hammerhead/issues/1684)) +* The browser no longer resets connection with the server for no reason ([testcafe-hammerhead/#1647](https://github.com/DevExpress/testcafe-hammerhead/issues/1647)) +* Hammerhead now stringifies values correctly before outputting them to the console ([testcafe-hammerhead/#1750](https://github.com/DevExpress/testcafe-hammerhead/issues/1750)) +* A document fragment from the top window can now be correctly appended to an iframe ([testcafe-hammerhead/#912](https://github.com/DevExpress/testcafe-hammerhead/issues/912)) +* Lifecycle callbacks that result from the `document.registerElement` method are no longer called twice ([testcafe-hammerhead/#695](https://github.com/DevExpress/testcafe-hammerhead/issues/695)) From 6e8e806430ba650a6abe24317971c2317139f595 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Thu, 25 Oct 2018 19:04:06 +0300 Subject: [PATCH 149/184] Bump version (v0.23.0) (#3031) --- .publishrc | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.publishrc b/.publishrc index 2414a453..5727c783 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "alpha", + "publishTag": "latest", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index 502d02ff..2cc4521d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.23.0-alpha.2", + "version": "0.23.0", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From 95b3829b7b7dfc38d2ee91610fa6405f04044a84 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 26 Oct 2018 12:32:02 +0300 Subject: [PATCH 150/184] Fix the release date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 049e89c6..50b2f3c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## v0.23.0 (2018-10-18) +## v0.23.0 (2018-10-25) ### Enhancements From a0736748724d02f7b5cdfdec49df4b994818b671 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 26 Oct 2018 13:20:16 +0300 Subject: [PATCH 151/184] Add info that TestCafe Studio is a Preview (#3038) --- README.md | 2 +- docs/articles/faq/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 66910af3..c1c8a982 100644 --- a/README.md +++ b/README.md @@ -264,7 +264,7 @@ There is a line of products called `TestCafe`. Below are the similarities and ke * You can extend it with [plugins](#plugins) and other Node.js modules. * [**TestCafe Studio**](https://testcafe-studio.devexpress.com/)
- *first released in 2018, commercial desktop application* + *Preview released in 2018, commercial desktop application* * Based on the open-source TestCafe, and supports its major features. * You can record tests or edit them as JavaScript or TypeScript code. * New [Visual Test Recorder](https://testcafe-studio.devexpress.com/documentation/guides/record-tests/) and [IDE-like GUI](https://testcafe-studio.devexpress.com/documentation/guides/write-test-code.html) to record, edit, run and debug tests. diff --git a/docs/articles/faq/README.md b/docs/articles/faq/README.md index 92a948e0..68b6e416 100644 --- a/docs/articles/faq/README.md +++ b/docs/articles/faq/README.md @@ -56,7 +56,7 @@ All three versions share the same core features: * You can extend it with [plugins](https://github.com/DevExpress/testcafe#plugins) and other Node.js modules. [TestCafe Studio](https://testcafe-studio.devexpress.com) -*first released in 2018, commercial desktop application* +*Preview released in 2018, commercial desktop application* * Based on the open-source TestCafe, and supports its major features. * You can record tests or edit them as JavaScript or TypeScript code. From 520a6114fa3f99ee4c24d005f618ef6b55aeb51a Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 26 Oct 2018 16:07:13 +0300 Subject: [PATCH 152/184] [docs] Fix a bug with a duplicated CF topic (#3035) --- .../obtaining-data-from-the-client.md | 261 ------------------ .../obtaining-data-from-the-client/README.md | 39 ++- .../examples-of-using-client-functions.md | 2 +- 3 files changed, 39 insertions(+), 263 deletions(-) delete mode 100644 docs/articles/documentation/test-api/obtaining-data-from-the-client.md diff --git a/docs/articles/documentation/test-api/obtaining-data-from-the-client.md b/docs/articles/documentation/test-api/obtaining-data-from-the-client.md deleted file mode 100644 index fda06a32..00000000 --- a/docs/articles/documentation/test-api/obtaining-data-from-the-client.md +++ /dev/null @@ -1,261 +0,0 @@ ---- -layout: docs -title: Obtaining Data from the Client -permalink: /documentation/test-api/obtaining-data-from-the-client.html -checked: true ---- -# Obtaining Data from the Client - -TestCafe allows you to create *client functions* that can return any -serializable value from the client side, like the current URL -or custom data calculated by a client script. - -> Important! Do not modify the tested webpage within client functions. -> To interact with the page, use [test actions](actions/README.md). - -This topic contains the following sections. - -* [Creating Client Functions](#creating-client-functions) - * [Running Asynchronous Client Code](#running-asynchronous-client-code) -* [Executing Client Functions](#executing-client-functions) -* [Options](#options) -* [One-Time Client Code Execution](#one-time-client-code-execution) -* [Import Functions to be Used as Client Function Dependencies](#import-functions-to-be-used-as-client-function-dependencies) -* [Calling Client Functions from Node.js Callbacks](#calling-client-functions-from-nodejs-callbacks) -* [Limitations](#limitations) - -## Creating Client Functions - -To create a client function, use the `ClientFunction` constructor. - -```text -ClientFunction( fn [, options] ) -``` - -Parameter | Type | Description ----------------------- | -------- | --------------------------------------------- -`fn` | Function | A function to be executed on the client side. -`options` *(optional)* | Object | See [Options](#options). - -> Important! Client functions cannot return DOM nodes. Use [selectors](selecting-page-elements/selectors/README.md) for this. - -The following example shows how to create a client function. - -```js -import { ClientFunction } from 'testcafe'; - -const getWindowLocation = ClientFunction(() => window.location); -``` - -### Running Asynchronous Client Code - -You can create client functions that run asynchronous code. -To this end, pass a function that returns a Promise to the `ClientFunction` constructor. -In this instance, the client function will complete only when this Promise resolves. - -```js -import { ClientFunction } from 'testcafe'; - -const performAsyncOperation = ClientFunction(() => { - return Promise(resolve => { - window.setTimeout(resolve, 500); // some async operations - }); -}); -``` - -## Executing Client Functions - -To execute a client function, call it with the `await` keyword. - -```js -import { ClientFunction } from 'testcafe'; - -const getWindowLocation = ClientFunction(() => window.location); - -fixture `My fixture` - .page `http://www.example.com/`; - -test('My Test', async t => { - const location = await getWindowLocation(); -}); -``` - -## Options - -You can pass the following options to the -[ClientFunction constructor](#creating-client-functions) and the -[t.eval](#one-time-client-code-execution) function. - -### options.dependencies - -**Type**: Object - -Contains functions, variables or objects used by the client function internally. -Properties of the `dependencies` object will be added to the client function's scope as variables. - -The following sample demonstrates a client function (`getArticleHeaderHTML`) that -calls a [selector](selecting-page-elements/selectors/README.md) (`articleHeader`) internally. -This selector is passed to `getArticleHeaderHTML` as a dependency. - -```js -import { Selector, ClientFunction } from 'testcafe'; - -const articleHeader = Selector('#article-header'); - -const getArticleHeaderHTML = ClientFunction(() => articleHeader().innerHTML, { - dependencies: { articleHeader } -}); -``` - -> When a client function calls a [selector](selecting-page-elements/selectors/README.md) internally, -> the selector does not wait for the element to appear in the DOM -> but is executed at once, like a client function. - -### options.boundTestRun - -**Type**: Object - -If you need to call a client function from a Node.js callback, -assign the current [test controller](test-code-structure.md#test-controller) -to the `boundTestRun` option. - -For details, see [Calling Client Functions from Node.js Callbacks](#calling-client-functions-from-nodejs-callbacks). - -### Overwriting Options - -You can overwrite client function options by using the ClientFunction's `with` function. - -```text -clientFunction.with( options ) → ClientFunction -``` - -`with` returns a new client function with a different set of options that includes options -from the original function and new `options` that overwrite the original ones. - -The sample below shows how to overwrite the client function options. - -```js -import { Selector, ClientFunction } from 'testcafe'; - -const option = Selector('option'); - -const thirdOption = option.nth(2); - -const getThirdOptionHTML = ClientFunction(() => option().innerHTML, { - dependencies: { option: thirdOption } -}); - -const fourthOption = option.nth(3); - -const getFourthOptionHTML = getThirdOptionHTML.with({ - dependencies: { option: fourthOption } -}); -``` - -## One-Time Client Code Execution - -To create a client function and immediately execute it without saving it, -use the `eval` method of the [test controller](test-code-structure.md#test-controller). - -```text -t.eval( fn [, options] ) -``` - -Parameter | Type | Description ----------------------- | -------- | -------------------------------------------------------------------------- -`fn` | Function | A function to be executed on the client side. -`options` *(optional)* | Object | See [Options](#options). - -The following example shows how to get the document's URI with `t.eval`. - -```js -fixture `My fixture` - .page `http://www.example.com/`; - -test('My Test', async t => { - const docURI = await t.eval(() => document.documentURI); -}); -``` - -## Import Functions to be Used as Client Function Dependencies - -Assume you have a JS file `utils.js` with a function you need to use as a client function dependency in your test file. - -**utils.js** - -```js -export function getDocumentURI() { - return document.documentURI; -} -``` - -Note that TestCafe internally processes test files with [Babel](https://babeljs.io). To avoid issues caused by code transpiling, use the [require](https://nodejs.org/api/modules.html#modules_require) function instead of the `import` statement to import client function dependencies. - -**test.js** - -```js -import { ClientFunction } from 'testcafe'; - -const getDocumentURI = require('./utils.js').getDocumentURI; - -fixture `My fixture` - .page `http://devexpress.github.io/testcafe/example/`; - -test('My test', async t => { - const getUri = ClientFunction(() => { - return getDocumentURI(); - }, { dependencies: { getDocumentURI } }); - - const uri = await getUri(); - - await t.expect(uri).eql('http://devexpress.github.io/testcafe/example/'); -}); -``` - -## Calling Client Functions from Node.js Callbacks - -Client functions need access to the [test controller](test-code-structure.md#test-controller) to be executed. -When called right from the test function, they implicitly obtain the test controller. - -However, if you need to call a client function from a Node.js callback that fires during the test run, -you will have to manually bind this function to the test controller. - -Use the [boundTestRun](#optionsboundtestrun) option for this. - -```js -import fs from 'fs'; -import { ClientFunction } from 'testcafe'; - -fixture `My fixture` - .page `http://www.example.com/`; - -const getDataFromClient = ClientFunction(() => getSomeData()); - -test('Check client data', async t => { - const boundGetDataFromClient = getDataFromClient.with({ boundTestRun: t }); - - const equal = await new Promise(resolve => { - fs.readFile('/home/user/tests/reference/clientData.json', (err, data) => { - boundGetDataFromClient().then(clientData => { - resolve(JSON.stringify(clientData) === data); - }); - }); - }); - - await t.expect(equal).ok(); -}); -``` - -This approach only works for Node.js callbacks that fire during the test run. To ensure that the test function -does not finish before the callback is executed, suspend the test until the callback fires. You can do this -by introducing a promise and synchronously waiting for it to complete as shown in the example above. - -## Limitations - -* You cannot use generators or `async/await` syntax within client functions. - -* Client functions cannot access variables defined in the outer scope in test code. - However, you can use arguments to pass data inside these functions, except for self-invoking functions - that cannot take any parameters from the outside. - - Likewise, the return value is the only way to obtain data from client functions. diff --git a/docs/articles/documentation/test-api/obtaining-data-from-the-client/README.md b/docs/articles/documentation/test-api/obtaining-data-from-the-client/README.md index 0a428b29..70580116 100644 --- a/docs/articles/documentation/test-api/obtaining-data-from-the-client/README.md +++ b/docs/articles/documentation/test-api/obtaining-data-from-the-client/README.md @@ -2,7 +2,8 @@ layout: docs title: Obtaining Data from the Client permalink: /documentation/test-api/obtaining-data-from-the-client/ -checked: true +redirect_from: + - /documentation/test-api/obtaining-data-from-the-client.html --- # Obtaining Data from the Client @@ -20,6 +21,7 @@ This topic contains the following sections. * [Executing Client Functions](#executing-client-functions) * [Options](#options) * [One-Time Client Code Execution](#one-time-client-code-execution) +* [Import Functions to be Used as Client Function Dependencies](#import-functions-to-be-used-as-client-function-dependencies) * [Calling Client Functions from Node.js Callbacks](#calling-client-functions-from-nodejs-callbacks) * [Limitations](#limitations) @@ -178,6 +180,41 @@ test('My Test', async t => { > Since the `eval` method returns a value, not an object, you cannot call other methods of the test controller in the chain after calling 'eval'. +## Import Functions to be Used as Client Function Dependencies + +Assume you have a JS file `utils.js` with a function you need to use as a client function dependency in your test file. + +**utils.js** + +```js +export function getDocumentURI() { + return document.documentURI; +} +``` + +Note that TestCafe internally processes test files with [Babel](https://babeljs.io). To avoid issues caused by code transpiling, use the [require](https://nodejs.org/api/modules.html#modules_require) function instead of the `import` statement to import client function dependencies. + +**test.js** + +```js +import { ClientFunction } from 'testcafe'; + +const getDocumentURI = require('./utils.js').getDocumentURI; + +fixture `My fixture` + .page `http://devexpress.github.io/testcafe/example/`; + +test('My test', async t => { + const getUri = ClientFunction(() => { + return getDocumentURI(); + }, { dependencies: { getDocumentURI } }); + + const uri = await getUri(); + + await t.expect(uri).eql('http://devexpress.github.io/testcafe/example/'); +}); +``` + ## Calling Client Functions from Node.js Callbacks Client functions need access to the [test controller](../test-code-structure.md#test-controller) to be executed. diff --git a/docs/articles/documentation/test-api/obtaining-data-from-the-client/examples-of-using-client-functions.md b/docs/articles/documentation/test-api/obtaining-data-from-the-client/examples-of-using-client-functions.md index 242a2cb0..2001e73e 100644 --- a/docs/articles/documentation/test-api/obtaining-data-from-the-client/examples-of-using-client-functions.md +++ b/docs/articles/documentation/test-api/obtaining-data-from-the-client/examples-of-using-client-functions.md @@ -136,7 +136,7 @@ test('My Test', async t => { }); ``` -> Note that the `getChildNodeText` client function uses the `testedPage` selector that is passed to it as a dependency. See [options.dependencies](../obtaining-data-from-the-client.md#optionsdependencies) for more information. +> Note that the `getChildNodeText` client function uses the `testedPage` selector that is passed to it as a dependency. See [options.dependencies](README.md#optionsdependencies) for more information. ## Complex DOM Queries From 17b720d284b7e5a3b1be7cc06e9181dba06f9a2b Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Fri, 26 Oct 2018 17:13:13 +0300 Subject: [PATCH 153/184] Fix a typo --- docs/articles/documentation/getting-started/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/documentation/getting-started/README.md b/docs/articles/documentation/getting-started/README.md index 99c2bd38..dc9feca2 100644 --- a/docs/articles/documentation/getting-started/README.md +++ b/docs/articles/documentation/getting-started/README.md @@ -160,7 +160,7 @@ A functional test should also check the result of actions performed. For example, the article header on the "Thank you" page should address a user using the entered name. To check if the header is correct, you have to add an assertion to the test. -The following test demonstrates how to use [build-in assertions](../test-api/assertions/README.md). +The following test demonstrates how to use [built-in assertions](../test-api/assertions/README.md). ```js import { Selector } from 'testcafe'; From a9ee9c63893642321e765a24b8d0a830d5986663 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Fri, 26 Oct 2018 17:48:34 +0300 Subject: [PATCH 154/184] Split headless tests into two tasks (#3041) --- .travis.yml | 4 +++- Gulpfile.js | 12 +++++++++--- test/functional/config.js | 15 ++++++++++++--- .../functional/fixtures/api/es-next/hooks/test.js | 4 ++-- .../hooks/testcafe-fixtures/fixture-ctx.js | 5 +++-- .../browser-provider/browser-reconnect/test.js | 7 ++++--- test/functional/fixtures/concurrency/test.js | 5 +++-- 7 files changed, 36 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0e669e6d..00441430 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,9 @@ matrix: - node_js: "stable" env: GULP_TASK="test-client-travis-mobile" - node_js: "stable" - env: GULP_TASK="test-functional-local-headless" + env: GULP_TASK="test-functional-local-headless-chrome" + - node_js: "stable" + env: GULP_TASK="test-functional-local-headless-firefox" fast_finish: true cache: diff --git a/Gulpfile.js b/Gulpfile.js index d1845d4b..83dffe00 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -664,11 +664,17 @@ gulp.step('test-functional-local-chrome-firefox-run', () => { gulp.task('test-functional-local-chrome-firefox', gulp.series('build', 'test-functional-local-chrome-firefox-run')); -gulp.step('test-functional-local-headless-run', () => { - return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.localHeadlessBrowsers); +gulp.step('test-functional-local-headless-chrome-run', () => { + return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.localHeadlessChrome); }); -gulp.task('test-functional-local-headless', gulp.series('build', 'test-functional-local-headless-run')); +gulp.task('test-functional-local-headless-chrome', gulp.series('build', 'test-functional-local-headless-chrome-run')); + +gulp.step('test-functional-local-headless-firefox-run', () => { + return testFunctional('test/functional/fixtures', functionalTestConfig.testingEnvironmentNames.localHeadlessFirefox); +}); + +gulp.task('test-functional-local-headless-firefox', gulp.series('build', 'test-functional-local-headless-firefox-run')); gulp.step('test-functional-local-legacy-run', () => { return testFunctional('test/functional/legacy-fixtures', functionalTestConfig.testingEnvironmentNames.legacy); diff --git a/test/functional/config.js b/test/functional/config.js index b68be4a9..3dbc35be 100644 --- a/test/functional/config.js +++ b/test/functional/config.js @@ -14,7 +14,8 @@ const testingEnvironmentNames = { localBrowsersIE: 'local-browsers-ie', localBrowsersChromeFirefox: 'local-browsers-chrome-firefox', localBrowsers: 'local-browsers', - localHeadlessBrowsers: 'local-headless-browsers', + localHeadlessChrome: 'local-headless-chrome', + localHeadlessFirefox: 'local-headless-firefox', oldBrowsers: 'old-browsers', legacy: 'legacy' }; @@ -136,7 +137,7 @@ testingEnvironments[testingEnvironmentNames.localBrowsersChromeFirefox] = { ] }; -testingEnvironments[testingEnvironmentNames.localHeadlessBrowsers] = { +testingEnvironments[testingEnvironmentNames.localHeadlessChrome] = { isLocalBrowsers: true, isHeadlessBrowsers: true, @@ -146,7 +147,15 @@ testingEnvironments[testingEnvironmentNames.localHeadlessBrowsers] = { browserName: 'chrome:headless --no-sandbox', userAgent: 'headlesschrome', alias: 'chrome' - }, + } + ] +}; + +testingEnvironments[testingEnvironmentNames.localHeadlessFirefox] = { + isLocalBrowsers: true, + isHeadlessBrowsers: true, + + browsers: [ { platform: 'Windows 10', browserName: 'firefox:headless:disableMultiprocessing=true', diff --git a/test/functional/fixtures/api/es-next/hooks/test.js b/test/functional/fixtures/api/es-next/hooks/test.js index 97bfd61b..b8d8203b 100644 --- a/test/functional/fixtures/api/es-next/hooks/test.js +++ b/test/functional/fixtures/api/es-next/hooks/test.js @@ -119,9 +119,9 @@ describe('[API] fixture.before/fixture.after hooks', () => { shouldFail: true, only: 'chrome, firefox' }).catch(errs => { - const allErrors = errs['chrome'].concat(errs['firefox']); + const allErrors = config.currentEnvironment.browsers.length === 1 ? errs : errs['chrome'].concat(errs['firefox']); - expect(allErrors.length).eql(6); + expect(allErrors.length).eql(config.currentEnvironment.browsers.length * 3); allErrors.forEach(err => { expect(err).contains('Error in fixture.before hook'); diff --git a/test/functional/fixtures/api/es-next/hooks/testcafe-fixtures/fixture-ctx.js b/test/functional/fixtures/api/es-next/hooks/testcafe-fixtures/fixture-ctx.js index ea7d5ff1..bca825e7 100644 --- a/test/functional/fixtures/api/es-next/hooks/testcafe-fixtures/fixture-ctx.js +++ b/test/functional/fixtures/api/es-next/hooks/testcafe-fixtures/fixture-ctx.js @@ -1,4 +1,5 @@ import { expect } from 'chai'; +import config from '../../../../../config'; fixture `Fixture1` @@ -9,8 +10,8 @@ fixture `Fixture1` const items = ctx.prop.split('|'); expect(items.filter(item => item === 'before').length).eql(1); - expect(items.filter(item => item === 'test1').length).eql(2); - expect(items.filter(item => item === 'test2').length).eql(2); + expect(items.filter(item => item === 'test1').length).eql(config.currentEnvironment.browsers.length); + expect(items.filter(item => item === 'test2').length).eql(config.currentEnvironment.browsers.length); }); test('Test1', async t => { diff --git a/test/functional/fixtures/browser-provider/browser-reconnect/test.js b/test/functional/fixtures/browser-provider/browser-reconnect/test.js index bafc8675..8341758d 100644 --- a/test/functional/fixtures/browser-provider/browser-reconnect/test.js +++ b/test/functional/fixtures/browser-provider/browser-reconnect/test.js @@ -50,17 +50,18 @@ async function run (pathToTest, filter) { }); } -describe('Browser reconnect', function () { +// NOTE: don't work on TravisCI, fix it ASAP +describe.skip('Browser reconnect', function () { if (config.useLocalBrowsers) { it('Should restart browser when it does not respond', function () { - return run('./testcafe-fixtures/index-test.js', 'Should restart browser when it does not respond') + return run('./testcafe-fixtures/index-test.js', 'Should restart browser when it does not respond', { only: 'chrome' }) .then(() => { expect(errors.length).eql(0); }); }); it('Should fail on 3 disconnects in one browser', function () { - return run('./testcafe-fixtures/index-test.js', 'Should fail on 3 disconnects in one browser') + return run('./testcafe-fixtures/index-test.js', 'Should fail on 3 disconnects in one browser', { only: 'chrome' }) .then(() => { throw new Error('Test should have failed but it succeeded'); }) diff --git a/test/functional/fixtures/concurrency/test.js b/test/functional/fixtures/concurrency/test.js index 281e11c0..05845a95 100644 --- a/test/functional/fixtures/concurrency/test.js +++ b/test/functional/fixtures/concurrency/test.js @@ -118,8 +118,9 @@ if (config.useLocalBrowsers) { }); }); - it('Should run tests concurrently in different browser kinds', function () { - return run(['chrome:headless --no-sandbox', 'firefox:headless'], 2, './testcafe-fixtures/multibrowser-concurrent-test.js') + // NOTE: don't work on TravisCI, fix it ASAP + it.skip('Should run tests concurrently in different browser kinds', function () { + return run(['chrome:headless --no-sandbox', 'chrome:headless --no-sandbox --user-agent="TestAgent"'], 2, './testcafe-fixtures/multibrowser-concurrent-test.js') .then(failedCount => { const results = getResults(data); From 6dcb4a2c547867d1944ee921743b6abcd00010f4 Mon Sep 17 00:00:00 2001 From: Natu <11683678+Nuarat@users.noreply.github.com> Date: Mon, 29 Oct 2018 11:27:29 +0300 Subject: [PATCH 155/184] [docs] Updated "General Discussion" (#3013) --- CONTRIBUTING.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 43d0585d..2a5f90d0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,15 +16,14 @@ TestCafe has adopted a [Contributor Code of Conduct](CODE_OF_CONDUCT.md), abide ## General Discussion -If you have a question about TestCafe feel free to ask us on StackOverflow. We review and answer questions with the [TestCafe](https://stackoverflow.com/questions/tagged/testcafe) tag. +Join the TestCafe community on Stack Overflow: ask and answer [questions with the TestCafe tag](https://stackoverflow.com/questions/tagged/testcafe). ## Reporting a Problem If you find a problem when using TestCafe, please file an issue in our [GitHub repository](https://github.com/DevExpress/testcafe/issues). However, to save some time, please search through the existing issues to see if the problem has already been reported or addressed. -When you create a new issue, template text is automatically added to its body. -To help us understand the issue you're describing, be sure to fill in all sections in this template. +When you create a new issue, template text is automatically added to its body. To help us understand the issue you're describing, be sure to fill in all sections in this template. We process issues with insufficient details after all the others, which may take significant time without any guarantees. ## Code Contribution @@ -69,4 +68,4 @@ Please follow the steps below when submitting your code. with an appropriate issue number. Documentation pull requests should have the `[docs]` prefix in their title. - This ensures that documentation tests are triggered against these pull requests. \ No newline at end of file + This ensures that documentation tests are triggered against these pull requests. From 4a8999ce20061ce825f76d314490748407a033e4 Mon Sep 17 00:00:00 2001 From: aha-oretama Date: Mon, 29 Oct 2018 21:10:39 +0900 Subject: [PATCH 156/184] Fix typo. (#3046) --- .../using-testcafe/command-line-interface.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 1d6812d4..14d0ba7d 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -286,13 +286,13 @@ testcafe all tests/sample-fixture.js -s screenshots The captured screenshots are organized into subdirectories within the base directory. The following path patterns are used to define a relative path and name for screenshots the [Take Screenshot](../test-api/actions/take-screenshot.md) actions take: -* `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is disabled; -* `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is enabled. +* `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\${FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is disabled; +* `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\${FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is enabled. If TestCafe takes screenshots when a test fails (see [--screenshots-on-fails](#-s---screenshots-on-fails) option), the following path patterns are used: -* `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\errors\{$FILE_INDEX}.png`; -* `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\errors\{$FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is enabled. +* `${DATE}_${TIME}\test-${TEST_INDEX}\${USERAGENT}\errors\${FILE_INDEX}.png`; +* `${DATE}_${TIME}\test-${TEST_INDEX}\run-${QUARANTINE_ATTEMPT}\${USERAGENT}\errors\${FILE_INDEX}.png` if the [quarantine mode](#-q---quarantine-mode) is enabled. You can also use the [--screenshot-path-pattern](#-p---screenshot-path-pattern) option to specify a custom pattern. From 2e2ab20d4a541fd4f13b86b67d5eccf3264ffb4c Mon Sep 17 00:00:00 2001 From: Nicolas Cisco Date: Mon, 29 Oct 2018 09:37:01 -0300 Subject: [PATCH 157/184] Add "group" metadata to define which tests will be run (#2841) * Passign meta to `Runner::filter` callback * Cli: adding `meta` option and filtering tests by meta * Adding argument parser tests * Adding runner filter meta test * Passing test`s and fixture`s metas as separate arguments. Updated cli arguments * Updating `--test-meta` and `--fixture-meta` cli texts * cli: test/fixture meta using `key=value[,key2=value2,...]` instead of json --- src/cli/argument-parser.js | 33 +++++++- src/errors/runtime/message.js | 1 + src/runner/bootstrapper.js | 2 +- test/server/cli-argument-parser-test.js | 91 +++++++++++++++++++++ test/server/data/test-suites/filter/meta.js | 17 ++++ test/server/runner-test.js | 24 +++++- 6 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 test/server/data/test-suites/filter/meta.js diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index 157796ec..983881fa 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -8,6 +8,7 @@ import MESSAGE from '../errors/runtime/message'; import { assertType, is } from '../errors/runtime/type-assertions'; import getViewPortWidth from '../utils/get-viewport-width'; import { wordWrap, splitQuotedText } from '../utils/string'; +import { isMatch } from 'lodash'; import parseSslOptions from './parse-ssl-options'; const REMOTE_ALIAS_RE = /^remote(?::(\d*))?$/; @@ -60,6 +61,26 @@ export default class CLIArgumentParser { } } + static _optionValueToKeyValue (name, value) { + if (value === void 0) + return value; + + const keyValue = value.split(',').reduce((obj, pair) => { + const [key, val] = pair.split('='); + + if (!key || !val) + throw new GeneralError(MESSAGE.optionValueIsNotValidKeyValue, name); + + obj[key] = val; + return obj; + }, {}); + + if (Object.keys(keyValue).length === 0) + throw new GeneralError(MESSAGE.optionValueIsNotValidKeyValue, name); + + return keyValue; + } + static _getDescription () { // NOTE: add empty line to workaround commander-forced indentation on the first line. return '\n' + wordWrap(DESCRIPTION, 2, getViewPortWidth(process.stdout)); @@ -89,6 +110,8 @@ export default class CLIArgumentParser { .option('-F, --fixture-grep ', 'run only fixtures matching the specified pattern') .option('-a, --app ', 'launch the tested app using the specified command before running tests') .option('-c, --concurrency ', 'run tests concurrently') + .option('--test-meta ', 'run only tests with matching metadata') + .option('--fixture-meta ', 'run only fixtures with matching metadata') .option('--debug-on-fail', 'pause the test if it fails') .option('--app-init-delay ', 'specify how much time it takes for the tested app to initialize') .option('--selector-timeout ', 'set the amount of time within which selectors make attempts to obtain a node to be returned') @@ -124,8 +147,10 @@ export default class CLIArgumentParser { _parseFilteringOptions () { this.opts.testGrep = CLIArgumentParser._optionValueToRegExp('--test-grep', this.opts.testGrep); this.opts.fixtureGrep = CLIArgumentParser._optionValueToRegExp('--fixture-grep', this.opts.fixtureGrep); + this.opts.testMeta = CLIArgumentParser._optionValueToKeyValue('--test-meta', this.opts.testMeta); + this.opts.fixtureMeta = CLIArgumentParser._optionValueToKeyValue('--fixture-meta', this.opts.fixtureMeta); - this.filter = (testName, fixtureName) => { + this.filter = (testName, fixtureName, fixturePath, testMeta, fixtureMeta) => { if (this.opts.test && testName !== this.opts.test) return false; @@ -139,6 +164,12 @@ export default class CLIArgumentParser { if (this.opts.fixtureGrep && !this.opts.fixtureGrep.test(fixtureName)) return false; + if (this.opts.testMeta && !isMatch(testMeta, this.opts.testMeta)) + return false; + + if (this.opts.fixtureMeta && !isMatch(fixtureMeta, this.opts.fixtureMeta)) + return false; + return true; }; } diff --git a/src/errors/runtime/message.js b/src/errors/runtime/message.js index f75f7f2a..48d8785b 100644 --- a/src/errors/runtime/message.js +++ b/src/errors/runtime/message.js @@ -16,6 +16,7 @@ export default { cantFindReporterForAlias: 'The provided "{name}" reporter does not exist. Check that you have specified the report format correctly.', multipleStdoutReporters: 'Multiple reporters attempting to write to stdout: "{reporters}". Only one reporter can write to stdout.', optionValueIsNotValidRegExp: 'The "{optionName}" option value is not a valid regular expression.', + optionValueIsNotValidKeyValue: 'The "{optionName}" option value is not a valid key-value pair.', testedAppFailedWithError: 'Tested app failed with an error:\n\n{errMessage}', invalidSpeedValue: 'Speed should be a number between 0.01 and 1.', invalidConcurrencyFactor: 'The concurrency factor should be an integer greater or equal to 1.', diff --git a/src/runner/bootstrapper.js b/src/runner/bootstrapper.js index 2cfa3aeb..63b6c4b6 100644 --- a/src/runner/bootstrapper.js +++ b/src/runner/bootstrapper.js @@ -82,7 +82,7 @@ export default class Bootstrapper { tests = testsWithOnlyFlag; if (this.filter) - tests = tests.filter(test => this.filter(test.name, test.fixture.name, test.fixture.path)); + tests = tests.filter(test => this.filter(test.name, test.fixture.name, test.fixture.path, test.meta, test.fixture.meta)); if (!tests.length) throw new GeneralError(MESSAGE.noTestsToRun); diff --git a/test/server/cli-argument-parser-test.js b/test/server/cli-argument-parser-test.js index 1eae1ff2..d1857b46 100644 --- a/test/server/cli-argument-parser-test.js +++ b/test/server/cli-argument-parser-test.js @@ -215,6 +215,35 @@ describe('CLI argument parser', function () { return assertRaisesError('-F *+', 'The "--fixture-grep" option value is not a valid regular expression.'); }); + it('Should filter by test meta with "--test-meta" option', function () { + return parse('--test-meta meta=test') + .then(function (parser) { + expect(parser.filter(null, null, null, { meta: 'test' })).to.be.true; + expect(parser.filter(null, null, null, { another: 'meta', meta: 'test' })).to.be.true; + expect(parser.filter(null, null, null, {})).to.be.false; + expect(parser.filter(null, null, null, { meta: 'notest' })).to.be.false; + }); + }); + + it('Should filter by fixture meta with "--fixture-meta" option', function () { + return parse('--fixture-meta meta=test,more=meta') + .then(function (parser) { + expect(parser.filter(null, null, null, null, { meta: 'test', more: 'meta' })).to.be.true; + expect(parser.filter(null, null, null, null, { another: 'meta', meta: 'test', more: 'meta' })).to.be.true; + expect(parser.filter(null, null, null, null, {})).to.be.false; + expect(parser.filter(null, null, null, null, { meta: 'test' })).to.be.false; + expect(parser.filter(null, null, null, null, { meta: 'test', more: 'another' })).to.be.false; + }); + }); + + it('Should raise error if "--test-meta" value is invalid json', function () { + return assertRaisesError('--test-meta error', 'The "--test-meta" option value is not a valid key-value pair.'); + }); + + it('Should raise error if "--fixture-meta" value is invalid json', function () { + return assertRaisesError('--fixture-meta error', 'The "--fixture-meta" option value is not a valid key-value pair.'); + }); + it('Should combine filters provided by multiple options', function () { return parse('-t thetest1 -T test\\d+$') .then(function (parser) { @@ -257,6 +286,66 @@ describe('CLI argument parser', function () { expect(parser.filter('thetest1', 'thefixture1')).to.be.true; expect(parser.filter('thetest', 'thefixture1')).to.be.false; expect(parser.filter('thetest1', 'thefixture')).to.be.false; + }) + .then(function () { + return parse('-t thetest1 --test-meta meta=test'); + }) + .then(function (parser) { + expect(parser.filter('thetest1', null, null, { meta: 'test' })).to.be.true; + expect(parser.filter('thetest1', null, null, {})).to.be.false; + expect(parser.filter('thetest2', null, null, { meta: 'test' })).to.be.false; + }) + .then(function () { + return parse('-f thefixture1 --test-meta meta=test'); + }) + .then(function (parser) { + expect(parser.filter(null, 'thefixture1', null, { meta: 'test' })).to.be.true; + expect(parser.filter(null, 'thefixture1', null, {})).to.be.false; + expect(parser.filter(null, 'thefixture2', null, { meta: 'test' })).to.be.false; + }) + .then(function () { + return parse('-t thetest1 -f thefixture1 --test-meta meta=test'); + }) + .then(function (parser) { + expect(parser.filter('thetest1', 'thefixture1', null, { meta: 'test' })).to.be.true; + expect(parser.filter('thetest1', 'thefixture1', null, {})).to.be.false; + expect(parser.filter('thetest1', 'thefixture2', null, { meta: 'test' })).to.be.false; + expect(parser.filter('thetest2', 'thefixture1', null, { meta: 'test' })).to.be.false; + }) + .then(function () { + return parse('-t thetest1 --fixture-meta meta=test'); + }) + .then(function (parser) { + expect(parser.filter('thetest1', null, null, null, { meta: 'test' })).to.be.true; + expect(parser.filter('thetest1', null, null, null, {})).to.be.false; + expect(parser.filter('thetest2', null, null, null, { meta: 'test' })).to.be.false; + }) + .then(function () { + return parse('-f thefixture1 --fixture-meta meta=test'); + }) + .then(function (parser) { + expect(parser.filter(null, 'thefixture1', null, null, { meta: 'test' })).to.be.true; + expect(parser.filter(null, 'thefixture1', null, null, {})).to.be.false; + expect(parser.filter(null, 'thefixture2', null, null, { meta: 'test' })).to.be.false; + }) + .then(function () { + return parse('-t thetest1 -f thefixture1 --fixture-meta meta=test'); + }) + .then(function (parser) { + expect(parser.filter('thetest1', 'thefixture1', null, null, { meta: 'test' })).to.be.true; + expect(parser.filter('thetest1', 'thefixture1', null, null, {})).to.be.false; + expect(parser.filter('thetest1', 'thefixture2', null, null, { meta: 'test' })).to.be.false; + expect(parser.filter('thetest2', 'thefixture1', null, null, { meta: 'test' })).to.be.false; + }) + .then(function () { + return parse('-t thetest1 -f thefixture1 --test-meta test=test --fixture-meta fixture=test'); + }) + .then(function (parser) { + expect(parser.filter('thetest1', 'thefixture1', null, { test: 'test' }, { fixture: 'test' })).to.be.true; + expect(parser.filter('thetest1', 'thefixture1', null, {}, { fixture: 'test' })).to.be.false; + expect(parser.filter('thetest1', 'thefixture1', null, { test: 'test' }, {})).to.be.false; + expect(parser.filter('thetest1', 'thefixture2', null, { test: 'test' }, { fixture: 'test' })).to.be.false; + expect(parser.filter('thetest2', 'thefixture1', null, { test: 'test' }, { fixture: 'test' })).to.be.false; }); }); }); @@ -367,6 +456,8 @@ describe('CLI argument parser', function () { { long: '--fixture-grep', short: '-F' }, { long: '--app', short: '-a' }, { long: '--concurrency', short: '-c' }, + { long: '--test-meta' }, + { long: '--fixture-meta' }, { long: '--debug-on-fail' }, { long: '--app-init-delay' }, { long: '--selector-timeout' }, diff --git a/test/server/data/test-suites/filter/meta.js b/test/server/data/test-suites/filter/meta.js new file mode 100644 index 00000000..52754227 --- /dev/null +++ b/test/server/data/test-suites/filter/meta.js @@ -0,0 +1,17 @@ +fixture('Fixture4') + .page `https://example.com` + .meta('meta', 'test') + .meta('another', 'more'); + +test('Fixture4Test1', async () => {}); + +fixture('Fixture5') + .meta('not', 'match') + .page `https://example.com` + +test('Fixture5Test1', async () => {}); + +test + .meta('meta', 'test') + .meta('more', 'meta') + ('Fixture5Test2', async () => {}); diff --git a/test/server/runner-test.js b/test/server/runner-test.js index 7c9f83fd..e143c254 100644 --- a/test/server/runner-test.js +++ b/test/server/runner-test.js @@ -303,7 +303,8 @@ describe('Runner', () => { .reporter('list') .src([ 'test/server/data/test-suites/basic/testfile1.js', - 'test/server/data/test-suites/basic/testfile2.js' + 'test/server/data/test-suites/basic/testfile2.js', + 'test/server/data/test-suites/filter/meta.js' ]); }); @@ -334,7 +335,10 @@ describe('Runner', () => { const expectedTestNames = [ 'Fixture1Test1', 'Fixture1Test2', - 'Fixture3Test1' + 'Fixture3Test1', + 'Fixture4Test1', + 'Fixture5Test1', + 'Fixture5Test2' ]; return testFilter(filter, expectedTestNames); @@ -359,6 +363,22 @@ describe('Runner', () => { return testFilter(filter, expectedTestNames); }); + it('Should filter by test meta', () => { + const filter = (testName, fixtureName, fixturePath, testMeta) => testMeta.meta === 'test'; + + const expectedTestNames = ['Fixture5Test2']; + + return testFilter(filter, expectedTestNames); + }); + + it('Should filter by fixture meta', () => { + const filter = (testName, fixtureName, fixturePath, testMeta, fixtureMeta) => fixtureMeta.meta === 'test'; + + const expectedTestNames = ['Fixture4Test1']; + + return testFilter(filter, expectedTestNames); + }); + it('Should raise an error if all tests are rejected by the filter', () => { return runner .filter(() => false) From a530707136b034cad44d95796f2fcc37160acddf Mon Sep 17 00:00:00 2001 From: Nicolas Cisco Date: Mon, 29 Oct 2018 09:37:27 -0300 Subject: [PATCH 158/184] [docs] Add "group" metadata to define which tests will be run (#2954) * Updated filter docs. closes #2527 * Updated filter cli docs. closes #2527 * updated doc * fix lint --- .../using-testcafe/command-line-interface.md | 22 +++++++++++++++++ .../programming-interface/runner.md | 24 +++++++++++-------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 14d0ba7d..d14d847d 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -37,6 +37,8 @@ testcafe [options] * [-F \, --fixture-grep \](#-f-pattern---fixture-grep-pattern) * [-a \, --app \](#-a-command---app-command) * [-c \, --concurrency \](#-c-n---concurrency-n) + * [--test-meta \](#--test-meta-keyvaluekey2value2) + * [--fixture-meta \](#--fixture-meta-keyvaluekey2value2) * [--debug-on-fail](#--debug-on-fail) * [--app-init-delay \](#--app-init-delay-ms) * [--selector-timeout \](#--selector-timeout-ms) @@ -449,6 +451,26 @@ The following example shows how to run tests in three Chrome instances: testcafe -c 3 chrome tests/sample-fixture.js ``` +### --test-meta \ + +TestCafe runs tests whose [metadata](../test-api/test-code-structure.html#specifying-testing-metadata) [matches](https://lodash.com/docs/#isMatch) the specified key-value pair. + +For example, the following command runs tests whose metadata have a `device` property with the value `mobile` and a `env` property with the value `production`. + +```sh +testcafe ie my-tests --test-meta device=mobile,env=production +``` + +### --fixture-meta \ + +TestCafe runs tests whose fixture's [metadata](../test-api/test-code-structure.html#specifying-testing-metadata) [matches](https://lodash.com/docs/#isMatch) the specified key-value pair. + +For example, the following command runs tests whose fixture's metadata have a `device` property with the value `mobile` and a `env` property with the value `production`. + +```sh +testcafe ie my-tests --fixture-meta device=mobile,env=production +``` + ### --debug-on-fail Specifies whether to automatically enter the [debug mode](#-d---debug-mode) when a test fails. diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index 9bba77e3..3fdcb259 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -87,9 +87,9 @@ Allows you to select which tests should be run. filter(callback) → this ``` -Parameter | Type | Description ----------- | ---------------------------------------------- | ---------------------------------------------------------------- -`callback` | `function(testName, fixtureName, fixturePath)` | The callback that determines if a particular test should be run. +Parameter | Type | Description +---------- | --------------------------------------------------------------------- | ---------------------------------------------------------------- +`callback` | `function(testName, fixtureName, fixturePath, testMeta, fixtureMeta)` | The callback that determines if a particular test should be run. The callback function is called for each test in the files specified using the [src](#src) method. @@ -97,19 +97,23 @@ Return `true` from the callback to include the current test or `false` to exclud The callback function accepts the following arguments: -Parameter | Type | Description -------------- | ------ | ---------------------------------- -`testName` | String | The name of the test. -`fixtureName` | String | The name of the test fixture. -`fixturePath` | String | The path to the test fixture file. +Parameter | Type | Description +------------- | ------------------------ | ---------------------------------- +`testName` | String | The name of the test. +`fixtureName` | String | The name of the test fixture. +`fixturePath` | String | The path to the test fixture file. +`testMeta` | Object\ | The test metadata. +`fixtureMeta` | Object\ | The fixture metadata. **Example** ```js -runner.filter((testName, fixtureName, fixturePath) => { +runner.filter((testName, fixtureName, fixturePath, testMeta, fixtureMeta) => { return fixturePath.startsWith('D') && testName.match(someRe) && - fixtureName.match(anotherRe); + fixtureName.match(anotherRe) && + testMeta.mobile === 'true' && + fixtureMeta.env === 'staging'; }); ``` From 181c0f306a8624202228307f0b8c1bbe4577eba6 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Tue, 30 Oct 2018 10:53:52 +0300 Subject: [PATCH 159/184] Revert "[docs] Add "group" metadata to define which tests will be run (#2954)" (#3050) This reverts commit a530707136b034cad44d95796f2fcc37160acddf. --- .../using-testcafe/command-line-interface.md | 22 ----------------- .../programming-interface/runner.md | 24 ++++++++----------- 2 files changed, 10 insertions(+), 36 deletions(-) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index d14d847d..14d0ba7d 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -37,8 +37,6 @@ testcafe [options] * [-F \, --fixture-grep \](#-f-pattern---fixture-grep-pattern) * [-a \, --app \](#-a-command---app-command) * [-c \, --concurrency \](#-c-n---concurrency-n) - * [--test-meta \](#--test-meta-keyvaluekey2value2) - * [--fixture-meta \](#--fixture-meta-keyvaluekey2value2) * [--debug-on-fail](#--debug-on-fail) * [--app-init-delay \](#--app-init-delay-ms) * [--selector-timeout \](#--selector-timeout-ms) @@ -451,26 +449,6 @@ The following example shows how to run tests in three Chrome instances: testcafe -c 3 chrome tests/sample-fixture.js ``` -### --test-meta \ - -TestCafe runs tests whose [metadata](../test-api/test-code-structure.html#specifying-testing-metadata) [matches](https://lodash.com/docs/#isMatch) the specified key-value pair. - -For example, the following command runs tests whose metadata have a `device` property with the value `mobile` and a `env` property with the value `production`. - -```sh -testcafe ie my-tests --test-meta device=mobile,env=production -``` - -### --fixture-meta \ - -TestCafe runs tests whose fixture's [metadata](../test-api/test-code-structure.html#specifying-testing-metadata) [matches](https://lodash.com/docs/#isMatch) the specified key-value pair. - -For example, the following command runs tests whose fixture's metadata have a `device` property with the value `mobile` and a `env` property with the value `production`. - -```sh -testcafe ie my-tests --fixture-meta device=mobile,env=production -``` - ### --debug-on-fail Specifies whether to automatically enter the [debug mode](#-d---debug-mode) when a test fails. diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index 3fdcb259..9bba77e3 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -87,9 +87,9 @@ Allows you to select which tests should be run. filter(callback) → this ``` -Parameter | Type | Description ----------- | --------------------------------------------------------------------- | ---------------------------------------------------------------- -`callback` | `function(testName, fixtureName, fixturePath, testMeta, fixtureMeta)` | The callback that determines if a particular test should be run. +Parameter | Type | Description +---------- | ---------------------------------------------- | ---------------------------------------------------------------- +`callback` | `function(testName, fixtureName, fixturePath)` | The callback that determines if a particular test should be run. The callback function is called for each test in the files specified using the [src](#src) method. @@ -97,23 +97,19 @@ Return `true` from the callback to include the current test or `false` to exclud The callback function accepts the following arguments: -Parameter | Type | Description -------------- | ------------------------ | ---------------------------------- -`testName` | String | The name of the test. -`fixtureName` | String | The name of the test fixture. -`fixturePath` | String | The path to the test fixture file. -`testMeta` | Object\ | The test metadata. -`fixtureMeta` | Object\ | The fixture metadata. +Parameter | Type | Description +------------- | ------ | ---------------------------------- +`testName` | String | The name of the test. +`fixtureName` | String | The name of the test fixture. +`fixturePath` | String | The path to the test fixture file. **Example** ```js -runner.filter((testName, fixtureName, fixturePath, testMeta, fixtureMeta) => { +runner.filter((testName, fixtureName, fixturePath) => { return fixturePath.startsWith('D') && testName.match(someRe) && - fixtureName.match(anotherRe) && - testMeta.mobile === 'true' && - fixtureMeta.env === 'staging'; + fixtureName.match(anotherRe); }); ``` From cb47bbbce2cdec2f903a6ed247c277a9d3d85432 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Tue, 30 Oct 2018 13:58:59 +0300 Subject: [PATCH 160/184] do not check regex optionally (closes #2074) (#2980) --- src/cli/argument-parser.js | 2 + src/compiler/index.js | 6 +- src/compiler/test-file/base.js | 4 +- src/runner/bootstrapper.js | 17 +-- src/runner/index.js | 4 +- .../regression/gh-2074/pages/index.html | 9 ++ .../fixtures/regression/gh-2074/test.js | 17 +++ .../gh-2074/testcafe-fixtures/index.js | 3 + .../gh-2074/testcafe-fixtures/lib.js | 9 ++ test/functional/setup.js | 50 +++++---- test/server/cli-argument-parser-test.js | 3 +- test/server/compiler-test.js | 100 ++++++++++++++++++ .../test-as-module/with-tests/lib.js | 7 ++ .../test-as-module/with-tests/testfile.coffee | 3 + .../test-as-module/with-tests/testfile.js | 3 + .../test-as-module/with-tests/testfile.ts | 3 + .../test-as-module/without-tests/lib.js | 2 + .../test-as-module/without-tests/testfile.js | 3 + test/server/helpers/compile.js | 4 +- test/server/runner-test.js | 10 ++ 20 files changed, 220 insertions(+), 39 deletions(-) create mode 100644 test/functional/fixtures/regression/gh-2074/pages/index.html create mode 100644 test/functional/fixtures/regression/gh-2074/test.js create mode 100644 test/functional/fixtures/regression/gh-2074/testcafe-fixtures/index.js create mode 100644 test/functional/fixtures/regression/gh-2074/testcafe-fixtures/lib.js create mode 100644 test/server/data/test-suites/test-as-module/with-tests/lib.js create mode 100644 test/server/data/test-suites/test-as-module/with-tests/testfile.coffee create mode 100644 test/server/data/test-suites/test-as-module/with-tests/testfile.js create mode 100644 test/server/data/test-suites/test-as-module/with-tests/testfile.ts create mode 100644 test/server/data/test-suites/test-as-module/without-tests/lib.js create mode 100644 test/server/data/test-suites/test-as-module/without-tests/testfile.js diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index 983881fa..2b53ec3b 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -127,6 +127,8 @@ export default class CLIArgumentParser { .option('--dev', 'enables mechanisms to log and diagnose errors') .option('--qr-code', 'outputs QR-code that repeats URLs used to connect the remote browsers') .option('--sf, --stop-on-first-fail', 'stop an entire test run if any test fails') + .option('--disable-test-syntax-validation', 'disables checks for \'test\' and \'fixture\' directives to run dynamically loaded tests') + // NOTE: these options will be handled by chalk internally .option('--color', 'force colors in command line') diff --git a/src/compiler/index.js b/src/compiler/index.js index e06065e2..318050c4 100644 --- a/src/compiler/index.js +++ b/src/compiler/index.js @@ -23,8 +23,10 @@ const testFileCompilers = [ ]; export default class Compiler { - constructor (sources) { + constructor (sources, disableTestSyntaxValidation) { this.sources = sources; + + this.disableTestSyntaxValidation = disableTestSyntaxValidation; } static getSupportedTestFileExtensions () { @@ -43,7 +45,7 @@ export default class Compiler { code = stripBom(code).toString(); - const compiler = find(testFileCompilers, c => c.canCompile(code, filename)); + const compiler = find(testFileCompilers, c => c.canCompile(code, filename, this.disableTestSyntaxValidation)); return compiler ? await compiler.compile(code, filename) : null; } diff --git a/src/compiler/test-file/base.js b/src/compiler/test-file/base.js index e3df1ab3..7a7421d9 100644 --- a/src/compiler/test-file/base.js +++ b/src/compiler/test-file/base.js @@ -19,8 +19,8 @@ export default class TestFileCompilerBase { throw new Error('Not implemented'); } - canCompile (code, filename) { - return this.supportedExtensionRe.test(filename) && this._hasTests(code); + canCompile (code, filename, disableTestSyntaxValidation) { + return this.supportedExtensionRe.test(filename) && (disableTestSyntaxValidation || this._hasTests(code)); } cleanUp () { diff --git a/src/runner/bootstrapper.js b/src/runner/bootstrapper.js index 63b6c4b6..5f6511fd 100644 --- a/src/runner/bootstrapper.js +++ b/src/runner/bootstrapper.js @@ -15,13 +15,14 @@ export default class Bootstrapper { constructor (browserConnectionGateway) { this.browserConnectionGateway = browserConnectionGateway; - this.concurrency = 1; - this.sources = []; - this.browsers = []; - this.reporters = []; - this.filter = null; - this.appCommand = null; - this.appInitDelay = DEFAULT_APP_INIT_DELAY; + this.concurrency = 1; + this.sources = []; + this.browsers = []; + this.reporters = []; + this.filter = null; + this.appCommand = null; + this.appInitDelay = DEFAULT_APP_INIT_DELAY; + this.disableTestSyntaxValidation = false; } static _splitBrowserInfo (browserInfo) { @@ -73,7 +74,7 @@ export default class Bootstrapper { throw new GeneralError(MESSAGE.testSourcesNotSet); const parsedFileList = await parseFileList(this.sources, process.cwd()); - const compiler = new Compiler(parsedFileList); + const compiler = new Compiler(parsedFileList, this.disableTestSyntaxValidation); let tests = await compiler.getTests(); const testsWithOnlyFlag = tests.filter(test => test.only); diff --git a/src/runner/index.js b/src/runner/index.js index 37e2ebda..c6348152 100644 --- a/src/runner/index.js +++ b/src/runner/index.js @@ -249,7 +249,7 @@ export default class Runner extends EventEmitter { return this; } - run ({ skipJsErrors, disablePageReloads, quarantineMode, debugMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed = 1, debugOnFail, skipUncaughtErrors, stopOnFirstFail } = {}) { + run ({ skipJsErrors, disablePageReloads, quarantineMode, debugMode, selectorTimeout, assertionTimeout, pageLoadTimeout, speed = 1, debugOnFail, skipUncaughtErrors, stopOnFirstFail, disableTestSyntaxValidation } = {}) { this.opts.skipJsErrors = !!skipJsErrors; this.opts.disablePageReloads = !!disablePageReloads; this.opts.quarantineMode = !!quarantineMode; @@ -262,6 +262,8 @@ export default class Runner extends EventEmitter { this.opts.skipUncaughtErrors = !!skipUncaughtErrors; this.opts.stopOnFirstFail = !!stopOnFirstFail; + this.bootstrapper.disableTestSyntaxValidation = disableTestSyntaxValidation; + const runTaskPromise = Promise.resolve() .then(() => { this._validateRunOptions(); diff --git a/test/functional/fixtures/regression/gh-2074/pages/index.html b/test/functional/fixtures/regression/gh-2074/pages/index.html new file mode 100644 index 00000000..c353009b --- /dev/null +++ b/test/functional/fixtures/regression/gh-2074/pages/index.html @@ -0,0 +1,9 @@ + + + + + gh-2074 + + + + \ No newline at end of file diff --git a/test/functional/fixtures/regression/gh-2074/test.js b/test/functional/fixtures/regression/gh-2074/test.js new file mode 100644 index 00000000..62df508e --- /dev/null +++ b/test/functional/fixtures/regression/gh-2074/test.js @@ -0,0 +1,17 @@ +const expect = require('chai').expect; + +describe('[Regression](GH-2074)', function () { + it('Should execute test located in external module', function () { + return runTests('testcafe-fixtures/index.js', null, { shouldFail: true, disableTestSyntaxValidation: true }) + .catch(errors => { + if (Array.isArray(errors)) + expect(errors[0]).contains('test is executed'); + else { + Object.values(errors).forEach(err => { + expect(err[0]).contains('test is executed'); + }); + } + }); + }); +}); + diff --git a/test/functional/fixtures/regression/gh-2074/testcafe-fixtures/index.js b/test/functional/fixtures/regression/gh-2074/testcafe-fixtures/index.js new file mode 100644 index 00000000..0be3f5b0 --- /dev/null +++ b/test/functional/fixtures/regression/gh-2074/testcafe-fixtures/index.js @@ -0,0 +1,3 @@ +import libraryTest from './lib'; + +libraryTest(); diff --git a/test/functional/fixtures/regression/gh-2074/testcafe-fixtures/lib.js b/test/functional/fixtures/regression/gh-2074/testcafe-fixtures/lib.js new file mode 100644 index 00000000..b02b5cfb --- /dev/null +++ b/test/functional/fixtures/regression/gh-2074/testcafe-fixtures/lib.js @@ -0,0 +1,9 @@ +export default function libraryTests () { + fixture('gh-2074').page('../pages/index.html'); + + test('Do nothing', async () => { + throw new Error('test is executed'); + }); +} + + diff --git a/test/functional/setup.js b/test/functional/setup.js index 874fa9a9..e8439799 100644 --- a/test/functional/setup.js +++ b/test/functional/setup.js @@ -157,28 +157,30 @@ before(function () { global.testCafe = testCafe; global.runTests = (fixture, testName, opts) => { - const stream = createTestStream(); - const runner = testCafe.createRunner(); - const fixturePath = typeof fixture !== 'string' || path.isAbsolute(fixture) ? fixture : path.join(path.dirname(caller()), fixture); - const skipJsErrors = opts && opts.skipJsErrors; - const disablePageReloads = opts && opts.disablePageReloads; - const quarantineMode = opts && opts.quarantineMode; - const selectorTimeout = opts && opts.selectorTimeout || FUNCTIONAL_TESTS_SELECTOR_TIMEOUT; - const assertionTimeout = opts && opts.assertionTimeout || FUNCTIONAL_TESTS_ASSERTION_TIMEOUT; - const pageLoadTimeout = opts && opts.pageLoadTimeout || FUNCTIONAL_TESTS_PAGE_LOAD_TIMEOUT; - const onlyOption = opts && opts.only; - const skipOption = opts && opts.skip; - const screenshotPath = opts && opts.setScreenshotPath ? '___test-screenshots___' : ''; - const screenshotPathPattern = opts && opts.screenshotPathPattern; - const screenshotsOnFails = opts && opts.screenshotsOnFails; - const speed = opts && opts.speed; - const appCommand = opts && opts.appCommand; - const appInitDelay = opts && opts.appInitDelay; - const externalProxyHost = opts && opts.useProxy; - const proxyBypass = opts && opts.proxyBypass; - const customReporters = opts && opts.reporters; - const skipUncaughtErrors = opts && opts.skipUncaughtErrors; - const stopOnFirstFail = opts && opts.stopOnFirstFail; + const stream = createTestStream(); + const runner = testCafe.createRunner(); + const fixturePath = typeof fixture !== 'string' || + path.isAbsolute(fixture) ? fixture : path.join(path.dirname(caller()), fixture); + const skipJsErrors = opts && opts.skipJsErrors; + const disablePageReloads = opts && opts.disablePageReloads; + const quarantineMode = opts && opts.quarantineMode; + const selectorTimeout = opts && opts.selectorTimeout || FUNCTIONAL_TESTS_SELECTOR_TIMEOUT; + const assertionTimeout = opts && opts.assertionTimeout || FUNCTIONAL_TESTS_ASSERTION_TIMEOUT; + const pageLoadTimeout = opts && opts.pageLoadTimeout || FUNCTIONAL_TESTS_PAGE_LOAD_TIMEOUT; + const onlyOption = opts && opts.only; + const skipOption = opts && opts.skip; + const screenshotPath = opts && opts.setScreenshotPath ? '___test-screenshots___' : ''; + const screenshotPathPattern = opts && opts.screenshotPathPattern; + const screenshotsOnFails = opts && opts.screenshotsOnFails; + const speed = opts && opts.speed; + const appCommand = opts && opts.appCommand; + const appInitDelay = opts && opts.appInitDelay; + const externalProxyHost = opts && opts.useProxy; + const proxyBypass = opts && opts.proxyBypass; + const customReporters = opts && opts.reporters; + const skipUncaughtErrors = opts && opts.skipUncaughtErrors; + const stopOnFirstFail = opts && opts.stopOnFirstFail; + const disableTestSyntaxValidation = opts && opts.disableTestSyntaxValidation; const actualBrowsers = browsersInfo.filter(browserInfo => { const { alias, userAgent } = browserInfo.settings; @@ -216,6 +218,7 @@ before(function () { return runner .useProxy(externalProxyHost, proxyBypass) .browsers(connections) + .filter(test => { return testName ? test === testName : true; }) @@ -231,7 +234,8 @@ before(function () { pageLoadTimeout, speed, stopOnFirstFail, - skipUncaughtErrors + skipUncaughtErrors, + disableTestSyntaxValidation }) .then(failedCount => { if (customReporters) diff --git a/test/server/cli-argument-parser-test.js b/test/server/cli-argument-parser-test.js index d1857b46..c3bd9e17 100644 --- a/test/server/cli-argument-parser-test.js +++ b/test/server/cli-argument-parser-test.js @@ -475,7 +475,8 @@ describe('CLI argument parser', function () { { long: '--skip-uncaught-errors' }, { long: '--color' }, { long: '--no-color' }, - { long: '--stop-on-first-fail', short: '--sf' } + { long: '--stop-on-first-fail', short: '--sf' }, + { long: '--disable-test-syntax-validation' } ]; const parser = new CliArgumentParser(''); diff --git a/test/server/compiler-test.js b/test/server/compiler-test.js index dde9886b..c0546df4 100644 --- a/test/server/compiler-test.js +++ b/test/server/compiler-test.js @@ -47,6 +47,39 @@ describe('Compiler', function () { }); describe('ES-next', function () { + it('Should compile test defined in separate module if option is enabled', function () { + const sources = [ + 'test/server/data/test-suites/test-as-module/with-tests/testfile.js' + ]; + + return compile(sources, true) + .then(function (compiled) { + const tests = compiled.tests; + const fixtures = compiled.fixtures; + + expect(tests.length).eql(1); + expect(fixtures.length).eql(1); + + expect(tests[0].name).eql('test'); + expect(fixtures[0].name).eql('Library tests'); + }); + }); + + it('Should not compile test defined in separate module if option is disabled', function () { + const sources = [ + 'test/server/data/test-suites/test-as-module/with-tests/testfile.js' + ]; + + return compile(sources) + .then(function (compiled) { + const tests = compiled.tests; + const fixtures = compiled.fixtures; + + expect(tests.length).eql(0); + expect(fixtures.length).eql(0); + }); + }); + it('Should compile test files and their dependencies', function () { const sources = [ 'test/server/data/test-suites/basic/testfile1.js', @@ -140,6 +173,39 @@ describe('Compiler', function () { describe('TypeScript', function () { + it('Should compile test defined in separate module if option is enabled', function () { + const sources = [ + 'test/server/data/test-suites/test-as-module/with-tests/testfile.ts' + ]; + + return compile(sources, true) + .then(function (compiled) { + const tests = compiled.tests; + const fixtures = compiled.fixtures; + + expect(tests.length).eql(1); + expect(fixtures.length).eql(1); + + expect(tests[0].name).eql('test'); + expect(fixtures[0].name).eql('Library tests'); + }); + }); + + it('Should not compile test defined in separate module if option is disabled', function () { + const sources = [ + 'test/server/data/test-suites/test-as-module/with-tests/testfile.ts' + ]; + + return compile(sources) + .then(function (compiled) { + const tests = compiled.tests; + const fixtures = compiled.fixtures; + + expect(tests.length).eql(0); + expect(fixtures.length).eql(0); + }); + }); + it('Should compile test files and their dependencies', function () { const sources = [ 'test/server/data/test-suites/typescript-basic/testfile1.ts', @@ -248,6 +314,40 @@ describe('Compiler', function () { describe('CoffeeScript', function () { + it('Should compile test defined in separate module if option is enabled', function () { + const sources = [ + 'test/server/data/test-suites/test-as-module/with-tests/testfile.coffee' + ]; + + return compile(sources, true) + .then(function (compiled) { + const tests = compiled.tests; + const fixtures = compiled.fixtures; + + expect(tests.length).eql(1); + expect(fixtures.length).eql(1); + + expect(tests[0].name).eql('test'); + expect(fixtures[0].name).eql('Library tests'); + }); + }); + + it('Should not compile test defined in separate module if option is disabled', function () { + const sources = [ + 'test/server/data/test-suites/test-as-module/with-tests/testfile.coffee' + ]; + + return compile(sources) + .then(function (compiled) { + const tests = compiled.tests; + const fixtures = compiled.fixtures; + + expect(tests.length).eql(0); + expect(fixtures.length).eql(0); + }); + }); + + it('Should compile test files and their dependencies', function () { const sources = [ 'test/server/data/test-suites/coffeescript-basic/testfile1.coffee', diff --git a/test/server/data/test-suites/test-as-module/with-tests/lib.js b/test/server/data/test-suites/test-as-module/with-tests/lib.js new file mode 100644 index 00000000..17870332 --- /dev/null +++ b/test/server/data/test-suites/test-as-module/with-tests/lib.js @@ -0,0 +1,7 @@ +export default function libraryTests () { + fixture('Library tests').page('http://example.com'); + + test('test', async t => { + await t.click('h1'); + }); +} diff --git a/test/server/data/test-suites/test-as-module/with-tests/testfile.coffee b/test/server/data/test-suites/test-as-module/with-tests/testfile.coffee new file mode 100644 index 00000000..0be3f5b0 --- /dev/null +++ b/test/server/data/test-suites/test-as-module/with-tests/testfile.coffee @@ -0,0 +1,3 @@ +import libraryTest from './lib'; + +libraryTest(); diff --git a/test/server/data/test-suites/test-as-module/with-tests/testfile.js b/test/server/data/test-suites/test-as-module/with-tests/testfile.js new file mode 100644 index 00000000..0be3f5b0 --- /dev/null +++ b/test/server/data/test-suites/test-as-module/with-tests/testfile.js @@ -0,0 +1,3 @@ +import libraryTest from './lib'; + +libraryTest(); diff --git a/test/server/data/test-suites/test-as-module/with-tests/testfile.ts b/test/server/data/test-suites/test-as-module/with-tests/testfile.ts new file mode 100644 index 00000000..0be3f5b0 --- /dev/null +++ b/test/server/data/test-suites/test-as-module/with-tests/testfile.ts @@ -0,0 +1,3 @@ +import libraryTest from './lib'; + +libraryTest(); diff --git a/test/server/data/test-suites/test-as-module/without-tests/lib.js b/test/server/data/test-suites/test-as-module/without-tests/lib.js new file mode 100644 index 00000000..55aae668 --- /dev/null +++ b/test/server/data/test-suites/test-as-module/without-tests/lib.js @@ -0,0 +1,2 @@ +export default function libraryTests () { +} diff --git a/test/server/data/test-suites/test-as-module/without-tests/testfile.js b/test/server/data/test-suites/test-as-module/without-tests/testfile.js new file mode 100644 index 00000000..0be3f5b0 --- /dev/null +++ b/test/server/data/test-suites/test-as-module/without-tests/testfile.js @@ -0,0 +1,3 @@ +import libraryTest from './lib'; + +libraryTest(); diff --git a/test/server/helpers/compile.js b/test/server/helpers/compile.js index aa9cb955..b07ba898 100644 --- a/test/server/helpers/compile.js +++ b/test/server/helpers/compile.js @@ -2,14 +2,14 @@ const sortBy = require('lodash').sortBy; const resolve = require('path').resolve; const Compiler = require('../../../lib/compiler'); -module.exports = function compile (sources) { +module.exports = function compile (sources, disableTestSyntaxValidation = false) { sources = Array.isArray(sources) ? sources : [sources]; sources = sources.map(function (filename) { return resolve(filename); }); - const compiler = new Compiler(sources); + const compiler = new Compiler(sources, disableTestSyntaxValidation); return compiler.getTests() .then(function (tests) { diff --git a/test/server/runner-test.js b/test/server/runner-test.js index e143c254..1bc3245c 100644 --- a/test/server/runner-test.js +++ b/test/server/runner-test.js @@ -294,6 +294,16 @@ describe('Runner', () => { expect(err.message).eql('No test file specified.'); }); }); + + it('Should raise an error if the source and imported module have no tests', () => { + return runner + .browsers(connection) + .src(['test/server/data/test-suites/test-as-module/without-tests/testfile.js']) + .run() + .catch(err => { + expect(err.message).eql('No tests to run. Either the test files contain no tests or the filter function is too restrictive.'); + }); + }); }); describe('.filter()', () => { From 36f4b7fb716a61380ec153e5959a417cde746633 Mon Sep 17 00:00:00 2001 From: Natu <11683678+Nuarat@users.noreply.github.com> Date: Tue, 30 Oct 2018 17:47:26 +0300 Subject: [PATCH 161/184] [docs] Update issues, questions and contributing (#3012) * [docs] Update issues, questions and contributing 1. Moved stackoverflow questions to the 'community' section 2. Updated links for bug reports and feature requests 3. Updated the contributing descrtiption, added a 'thank you note' for contributors. Now we can just add a list to the end of this section. 4. Moved the 'badge' section to the end. * Removed an extra empty line * Update README.md Updated according to Vasily's comment * Fixed a typo in "Issue Tracker" * Changed http to https Co-Authored-By: Nuarat * Added a comma Co-Authored-By: Nuarat * Put "Issue Tracker" after the "Get Help" section --- README.md | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index c1c8a982..d691d472 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,13 @@ * [IDE for End-to-End Web Testing](#ide-for-end-to-end-web-testing) * [Getting Started](#getting-started) * [Documentation](#documentation) -* [Community](#community) -* [Badge](#badge) +* [Get Help](#get-help) +* [Issue Tracker](#issue-tracker) +* [Stay in Touch](#stay-in-touch) * [Contributing](#contributing) * [Plugins](#plugins) -* [Different versions of TestCafe](#different-versions-of-testcafe) +* [Different Versions of TestCafe](#different-versions-of-testcafe) +* [Badge](#badge) * [License](#license) * [Creators](#creators) @@ -158,31 +160,25 @@ Read the [Getting Started](https://devexpress.github.io/testcafe/documentation/g ## Documentation -Go to our website for full [documentation](http://devexpress.github.io/testcafe/documentation/using-testcafe/) on TestCafe. +Go to our website for full [documentation](https://devexpress.github.io/testcafe/documentation/getting-started/) on TestCafe. -## Community +## Get Help -Follow us on [Twitter](https://twitter.com/DXTestCafe). We post TestCafe news and updates, several times a week. +Join the TestCafe community on Stack Overflow to get help. Ask and answer [questions with the TestCafe tag](https://stackoverflow.com/questions/tagged/testcafe). -## Badge +## Issue Tracker -Show everyone you are using TestCafe: ![Tested with TestCafe](https://img.shields.io/badge/tested%20with-TestCafe-2fa4cf.svg) +Use our GitHub issues page to [report bugs](https://github.com/DevExpress/testcafe/issues/new?template=bug-report.md) and [suggest improvements](https://github.com/DevExpress/testcafe/issues/new?template=feature_request.md). -To display this badge, add the following code to your repository readme: +## Stay in Touch -```html - - Tested with TestCafe - -``` +Follow us on [Twitter](https://twitter.com/DXTestCafe). We post TestCafe news and updates, several times a week. ## Contributing -Report bugs and request features on our [issues page](https://github.com/DevExpress/testcafe/issues).
-Ask and answer questions on StackOverflow. We review and answer [questions with the TestCafe tag](https://stackoverflow.com/questions/tagged/testcafe).
-For more information on how to help us improve TestCafe, see the [CONTRIBUTING.md](https://github.com/DevExpress/testcafe/blob/master/CONTRIBUTING.md). +Read our [Contributing Guide](https://github.com/DevExpress/testcafe/blob/master/CONTRIBUTING.md) to learn how to contribute to the project. -You can use these plugin generators to create your own plugins: +To create your own plugin for TestCafe, you can use these plugin generators: * [Build a browser provider](https://devexpress.github.io/testcafe/documentation/extending-testcafe/browser-provider-plugin/) to set up tests on your on-premises server farm, to use a cloud testing platform, or to start your local browsers in a special way. Use this [Yeoman generator](https://www.npmjs.com/package/generator-testcafe-browser-provider) to write only a few lines of code. @@ -191,6 +187,8 @@ You can use these plugin generators to create your own plugins: If you want your plugin to be listed below, [send us a note in a Github issue](https://github.com/DevExpress/testcafe/issues/new). +Thank you to all the people who already contributed to TestCafe! + ## Plugins TestCafe developers and community members made these plugins: @@ -241,7 +239,7 @@ TestCafe developers and community members made these plugins: Use ESLint when writing and editing TestCafe tests. * [ESLint plugin](https://github.com/miherlosev/eslint-plugin-testcafe) (by [@miherlosev](https://github.com/miherlosev)) -## Different versions of TestCafe +## Different Versions of TestCafe There is a line of products called `TestCafe`. Below are the similarities and key differences between them. @@ -270,6 +268,18 @@ There is a line of products called `TestCafe`. Below are the similarities and ke * New [Visual Test Recorder](https://testcafe-studio.devexpress.com/documentation/guides/record-tests/) and [IDE-like GUI](https://testcafe-studio.devexpress.com/documentation/guides/write-test-code.html) to record, edit, run and debug tests. * Currently available as a free preview version. The release version will replace the 2013 version of TestCafe. +## Badge + +Show everyone you are using TestCafe: ![Tested with TestCafe](https://img.shields.io/badge/tested%20with-TestCafe-2fa4cf.svg) + +To display this badge, add the following code to your repository readme: + +```html + + Tested with TestCafe + +``` + ## Thanks to BrowserStack We are grateful to BrowserStack for providing the infrastructure that we use to test code in this repository. From b2ef19c2cde012b69c759f9704664790192ef88a Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Tue, 30 Oct 2018 19:39:15 +0300 Subject: [PATCH 162/184] Fix task cancellation --- azure-pipelines.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0ef034a4..215428a4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,8 @@ steps: - task: NodeTool@0 displayName: 'Install Node.js' - condition: not(variables['isDocCommit']) + condition: and(succeeded(), not(variables['isDocCommit'])) + timeoutInMinutes: 40 inputs: versionSpec: '11.x' @@ -17,4 +18,5 @@ steps: npm install --no-progress --loglevel error npm test displayName: 'Run tests' - condition: not(variables['isDocCommit']) + condition: and(succeeded(), not(variables['isDocCommit'])) + timeoutInMinutes: 40 From f14772fc2b44a844b9f5357ee57564f06a3e05a7 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Wed, 31 Oct 2018 11:35:05 +0300 Subject: [PATCH 163/184] Get rid of ps-node module (closes #2860) (#3047) --- .../provider/built-in/chrome/local-chrome.js | 2 +- .../built-in/firefox/local-firefox.js | 2 +- src/utils/kill-browser-process.js | 63 -------- src/utils/process.js | 147 ++++++++++++++++++ src/utils/promisified-functions.js | 4 - .../temp-directory/cleanup-process/worker.js | 2 +- 6 files changed, 150 insertions(+), 70 deletions(-) delete mode 100644 src/utils/kill-browser-process.js create mode 100644 src/utils/process.js diff --git a/src/browser/provider/built-in/chrome/local-chrome.js b/src/browser/provider/built-in/chrome/local-chrome.js index 9a652375..819eddf3 100644 --- a/src/browser/provider/built-in/chrome/local-chrome.js +++ b/src/browser/provider/built-in/chrome/local-chrome.js @@ -1,5 +1,5 @@ import browserTools from 'testcafe-browser-tools'; -import killBrowserProcess from '../../../../utils/kill-browser-process'; +import { killBrowserProcess } from '../../../../utils/process'; import BrowserStarter from '../../utils/browser-starter'; diff --git a/src/browser/provider/built-in/firefox/local-firefox.js b/src/browser/provider/built-in/firefox/local-firefox.js index a480fcdc..2493e3d3 100644 --- a/src/browser/provider/built-in/firefox/local-firefox.js +++ b/src/browser/provider/built-in/firefox/local-firefox.js @@ -1,6 +1,6 @@ import OS from 'os-family'; import browserTools from 'testcafe-browser-tools'; -import killBrowserProcess from '../../../../utils/kill-browser-process'; +import { killBrowserProcess } from '../../../../utils/process'; import BrowserStarter from '../../utils/browser-starter'; diff --git a/src/utils/kill-browser-process.js b/src/utils/kill-browser-process.js deleted file mode 100644 index 730239ef..00000000 --- a/src/utils/kill-browser-process.js +++ /dev/null @@ -1,63 +0,0 @@ -import { spawn } from 'child_process'; -import OS from 'os-family'; -import promisifyEvent from 'promisify-event'; -import Promise from 'pinkie'; -import { findProcess, killProcess } from './promisified-functions'; - - -const BROWSER_CLOSING_TIMEOUT = 5; - -async function runWMIC (args) { - const wmicProcess = spawn('wmic.exe', args, { detached: true }); - - let wmicOutput = ''; - - wmicProcess.stdout.on('data', data => { - wmicOutput += data.toString(); - }); - - try { - await Promise.race([ - promisifyEvent(wmicProcess.stdout, 'end'), - promisifyEvent(wmicProcess, 'error') - ]); - - return wmicOutput; - } - catch (e) { - return ''; - } -} - -async function findProcessWin (processOptions) { - const wmicArgs = ['process', 'where', `commandline like '%${processOptions.arguments}%' and name <> 'cmd.exe' and name <> 'wmic.exe'`, 'get', 'processid']; - const wmicOutput = await runWMIC(wmicArgs); - let processList = wmicOutput.split(/\s*\n/); - - processList = processList - // NOTE: remove list's header and empty last element, caused by trailing newline - .slice(1, -1) - .map(pid => ({ pid: Number(pid) })); - - return processList; -} - -export default async function (browserId) { - const processOptions = { arguments: browserId, psargs: '-ef' }; - const processList = OS.win ? await findProcessWin(processOptions) : await findProcess(processOptions); - - if (!processList.length) - return true; - - try { - if (OS.win) - process.kill(processList[0].pid); - else - await killProcess(processList[0].pid, { timeout: BROWSER_CLOSING_TIMEOUT }); - - return true; - } - catch (e) { - return false; - } -} diff --git a/src/utils/process.js b/src/utils/process.js new file mode 100644 index 00000000..345ebcd6 --- /dev/null +++ b/src/utils/process.js @@ -0,0 +1,147 @@ +import { spawn } from 'child_process'; +import Promise from 'pinkie'; +import OS from 'os-family'; +import promisifyEvent from 'promisify-event'; +import delay from '../utils/delay'; + +const CHECK_PROCESS_IS_KILLED_TIMEOUT = 5000; +const CHECK_KILLED_DELAY = 1000; +const NEW_LINE_SEPERATOR_RE = /(\r\n)|(\n\r)|\n|\r/g; +const cantGetListOfProcessError = 'Can not get list of processes'; +const killProcessTimeoutError = 'Kill process timeout'; + +function getProcessOutputUnix () { + const error = new Error(cantGetListOfProcessError); + + return new Promise((resolve, reject) => { + const child = spawn('ps', ['-eo', 'pid,command']); + let stdout = ''; + let stderr = ''; + + child.stdout.on('data', data => { + stdout += data.toString(); + }); + + child.stderr.on('data', data => { + stderr += data.toString(); + }); + + child.on('exit', () => { + if (stderr) + reject(error); + else + resolve(stdout); + }); + + child.on('error', () => { + reject(error); + }); + }); +} + +function findProcessIdUnix (browserId, psOutput) { + const processIdRegex = new RegExp('^\\s*(\\d+)\\s+.*' + browserId); + const lines = psOutput.split(NEW_LINE_SEPERATOR_RE); + + for (let i = 0; i < lines.length; i++) { + const match = processIdRegex.exec(lines[i]); + + if (match) + return parseInt(match[1], 10); + } + + return null; +} + +function isProcessExistUnix (processId, psOutput) { + const processIdRegex = new RegExp('^\\s*' + processId + '\\s+.*'); + const lines = psOutput.split(NEW_LINE_SEPERATOR_RE); + + return lines.some(line => processIdRegex.test(line)); +} + +async function findProcessUnix (browserId) { + const output = await getProcessOutputUnix(); + + return findProcessIdUnix(browserId, output); +} + +async function checkUnixProcessIsKilled (processId) { + const output = await getProcessOutputUnix(); + + if (isProcessExistUnix(processId, output)) { + await delay(CHECK_KILLED_DELAY); + + await checkUnixProcessIsKilled(); + } +} + +async function killProcessUnix (processId) { + let timeoutError = false; + + process.kill(processId); + + const killTimeoutTimer = delay(CHECK_PROCESS_IS_KILLED_TIMEOUT) + .then(() => { + timeoutError = true; + }); + + return Promise.race([killTimeoutTimer, checkUnixProcessIsKilled(processId)]).then(() => { + if (timeoutError) + throw new Error(killProcessTimeoutError); + }); +} + +async function runWMIC (args) { + const wmicProcess = spawn('wmic.exe', args, { detached: true }); + + let wmicOutput = ''; + + wmicProcess.stdout.on('data', data => { + wmicOutput += data.toString(); + }); + + try { + await Promise.race([ + promisifyEvent(wmicProcess.stdout, 'end'), + promisifyEvent(wmicProcess, 'error') + ]); + + return wmicOutput; + } + catch (e) { + return ''; + } +} + +async function findProcessWin (browserId) { + const wmicArgs = ['process', 'where', `commandline like '%${browserId}%' and name <> 'cmd.exe' and name <> 'wmic.exe'`, 'get', 'processid']; + const wmicOutput = await runWMIC(wmicArgs); + let processList = wmicOutput.split(/\s*\n/); + + processList = processList + // NOTE: remove list's header and empty last element, caused by trailing newline + .slice(1, -1) + .map(pid => ({ pid: Number(pid) })); + + return processList[0] ? processList[0].pid : null; +} + +export async function killBrowserProcess (browserId) { + const processId = OS.win ? await findProcessWin(browserId) : await findProcessUnix(browserId); + + if (!processId) + return true; + + try { + if (OS.win) + process.kill(processId); + else + await killProcessUnix(processId); + + return true; + } + catch (e) { + return false; + } +} diff --git a/src/utils/promisified-functions.js b/src/utils/promisified-functions.js index 52a0185d..eb2dc08c 100644 --- a/src/utils/promisified-functions.js +++ b/src/utils/promisified-functions.js @@ -1,6 +1,5 @@ import childProcess from 'child_process'; import fs from 'graceful-fs'; -import psNode from 'ps-node'; import promisify from './promisify'; @@ -10,9 +9,6 @@ export const writeFile = promisify(fs.writeFile); export const readFile = promisify(fs.readFile); export const deleteFile = promisify(fs.unlink); -export const findProcess = promisify(psNode.lookup); -export const killProcess = promisify(psNode.kill); - export const exec = promisify(childProcess.exec); export const sendMessageToChildProcess = promisify((process, ...args) => process.send(...args)); diff --git a/src/utils/temp-directory/cleanup-process/worker.js b/src/utils/temp-directory/cleanup-process/worker.js index 338c0096..6fa3e1db 100644 --- a/src/utils/temp-directory/cleanup-process/worker.js +++ b/src/utils/temp-directory/cleanup-process/worker.js @@ -3,7 +3,7 @@ import { inspect } from 'util'; import del from 'del'; import Promise from 'pinkie'; import { noop } from 'lodash'; -import killBrowserProcess from '../../kill-browser-process'; +import { killBrowserProcess } from '../../process'; import COMMANDS from './commands'; From b699f08dd874c0a48544cc4149b5d428d775c243 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 31 Oct 2018 12:49:12 +0300 Subject: [PATCH 164/184] Disable testing for new-docs branch (#3059) --- .travis.yml | 4 ++++ appveyor.yml | 4 ++++ azure-pipelines.yml | 15 +++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/.travis.yml b/.travis.yml index 00441430..2fb59f68 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,9 @@ if: NOT (commit_message =~ /^\[docs\]/) +branches: + except: + - new-docs + addons: chrome: stable firefox: latest diff --git a/appveyor.yml b/appveyor.yml index fb08b65b..a7c1ef13 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,6 +4,10 @@ clone_depth: 1 skip_commits: message: /^\[docs\]/ +branches: + except: + - new-docs + environment: NODEJS_VERSION: "stable" diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 215428a4..371da70f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,3 +1,18 @@ +trigger: + branches: + exclude: + - build-bot-temp-* + - new-docs + + paths: + include: + - /bin + - /src + - /test + - /azure-pipelines.yml + - /Gulpfile.js + - /package.json + pool: 'BrowserStack agents' steps: From 3d915d9490af8945309954f75afc1636a673242e Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 31 Oct 2018 12:55:37 +0300 Subject: [PATCH 165/184] Disable tests on Travis for new-docs --- .travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2fb59f68..5b2ce778 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,4 @@ -if: NOT (commit_message =~ /^\[docs\]/) - -branches: - except: - - new-docs +if: NOT (commit_message =~ /^\[docs\]/ OR branch = 'new-docs') addons: chrome: stable From f188d038ad527a1c6b016c3fffae1886508ff1c5 Mon Sep 17 00:00:00 2001 From: Artem Lavrov Date: Wed, 31 Oct 2018 13:24:00 +0300 Subject: [PATCH 166/184] bump version (0.23.1-alpha.1) (#3058) --- .publishrc | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.publishrc b/.publishrc index 5727c783..2414a453 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "latest", + "publishTag": "alpha", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index 2cc4521d..b8352296 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.23.0", + "version": "0.23.1-alpha.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" @@ -109,7 +109,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.5", - "testcafe-hammerhead": "14.3.1", + "testcafe-hammerhead": "14.4.0", "testcafe-legacy-api": "3.1.8", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", From 7bcfdfb00737548335050fc4a0cf52da829daabb Mon Sep 17 00:00:00 2001 From: aleks-pro Date: Wed, 31 Oct 2018 15:59:41 +0300 Subject: [PATCH 167/184] Should not add execute expression command to queue (#3042) --- src/test-run/commands/utils.js | 12 +++++++++- src/test-run/index.js | 10 +++----- test/functional/fixtures/test-run/test.js | 4 ++++ .../get-real-queue-length.js | 23 +++++++++++++++++++ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/test-run/commands/utils.js b/src/test-run/commands/utils.js index f1bd8372..7793983d 100644 --- a/src/test-run/commands/utils.js +++ b/src/test-run/commands/utils.js @@ -20,7 +20,8 @@ function isClientFunctionCommand (command) { function isObservationCommand (command) { return isClientFunctionCommand(command) || command.type === TYPE.wait || - command.type === TYPE.assertion; + command.type === TYPE.assertion || + command.type === TYPE.executeExpression; } function isWindowSwitchingCommand (command) { @@ -77,3 +78,12 @@ export function isJSExpression (val) { return val !== null && typeof val === 'object' && val.type === RAW_API_JS_EXPRESSION_TYPE && typeof val.value === 'string'; } + +export function isExecutableOnClientCommand (command) { + return command.type !== TYPE.wait && + command.type !== TYPE.setPageLoadTimeout && + command.type !== TYPE.debug && + command.type !== TYPE.useRole && + command.type !== TYPE.assertion && + command.type !== TYPE.executeExpression; +} diff --git a/src/test-run/index.js b/src/test-run/index.js index 375ab6b4..1bfa09eb 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -44,7 +44,8 @@ import { isBrowserManipulationCommand, isScreenshotCommand, isServiceCommand, - canSetDebuggerBreakpointBeforeCommand + canSetDebuggerBreakpointBeforeCommand, + isExecutableOnClientCommand } from './commands/utils'; const TEST_RUN_TEMPLATE = read('../client/test-run/index.js.mustache'); @@ -474,11 +475,6 @@ export default class TestRun extends EventEmitter { } // Execute command - static _shouldAddCommandToQueue (command) { - return command.type !== COMMAND_TYPE.wait && command.type !== COMMAND_TYPE.setPageLoadTimeout && - command.type !== COMMAND_TYPE.debug && command.type !== COMMAND_TYPE.useRole && command.type !== COMMAND_TYPE.assertion; - } - async _executeExpression (command) { const { resultVariableName, isAsyncExpression } = command; @@ -552,7 +548,7 @@ export default class TestRun extends EventEmitter { if (this.pendingPageError && isCommandRejectableByPageError(command)) return this._rejectCommandWithPageError(callsite); - if (TestRun._shouldAddCommandToQueue(command)) + if (isExecutableOnClientCommand(command)) this.addingDriverTasksCount++; this._adjustConfigurationWithCommand(command); diff --git a/test/functional/fixtures/test-run/test.js b/test/functional/fixtures/test-run/test.js index f4d37791..26d48940 100644 --- a/test/functional/fixtures/test-run/test.js +++ b/test/functional/fixtures/test-run/test.js @@ -12,4 +12,8 @@ describe('Driver task queue', function () { it('Should return real queue length after all server commands are added', function () { return runTests('testcafe-fixtures/get-real-queue-length.js', 'Check real driver task queue length (server command)'); }); + + it('Should return real queue length after execute-expression commands are added', function () { + return runTests('testcafe-fixtures/get-real-queue-length.js', 'Check driver task queue length (execute-expression command)'); + }); }); diff --git a/test/functional/fixtures/test-run/testcafe-fixtures/get-real-queue-length.js b/test/functional/fixtures/test-run/testcafe-fixtures/get-real-queue-length.js index dab4bbb3..de646013 100644 --- a/test/functional/fixtures/test-run/testcafe-fixtures/get-real-queue-length.js +++ b/test/functional/fixtures/test-run/testcafe-fixtures/get-real-queue-length.js @@ -1,5 +1,6 @@ import { PressKeyCommand } from '../../../../../lib/test-run/commands/actions'; import { WaitCommand } from '../../../../../lib/test-run/commands/observation'; +import { ExecuteExpressionCommand } from '../../../../../src/test-run/commands/actions'; fixture `Test run commands queue` @@ -36,3 +37,25 @@ test('Check real driver task queue length (server command)', async t => { .expect(driverTaskQueueLength).eql(0) .expect(realDriverTaskQueueLength).eql(0); }); + +test('Check driver task queue length (execute-expression command)', async t => { + const commandExecutionPromises = [ + t.testRun.executeCommand(new ExecuteExpressionCommand({ + resultVariableName: 'el1', + expression: 'Selector(\'div\')' + })), + t.testRun.executeCommand(new ExecuteExpressionCommand({ + resultVariableName: 'el2', + expression: 'Selector(\'div\')' + })) + ]; + + const driverTaskQueueLength = t.testRun.driverTaskQueue.length; + const realDriverTaskQueueLength = await t.testRun.driverTaskQueueLength; + + await Promise.all(commandExecutionPromises); + + await t + .expect(driverTaskQueueLength).eql(0) + .expect(realDriverTaskQueueLength).eql(0); +}); From 1500fbc44ab271e0db10cd384ce7b5abab0f9bd5 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 31 Oct 2018 16:47:02 +0300 Subject: [PATCH 168/184] Bump version (v0.23.1-alpha.2) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b8352296..fb5b0d14 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.23.1-alpha.1", + "version": "0.23.1-alpha.2", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From a49b72bceb25adc3f65bf991a9cb5c3ad34bb1f5 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Thu, 1 Nov 2018 12:28:56 +0300 Subject: [PATCH 169/184] Use node 8 for testing (#3063) * Debug * Use node 6 * Use node 8 --- .travis.yml | 8 ++++---- appveyor.yml | 2 +- azure-pipelines.yml | 2 +- test/functional/config.js | 6 ++++++ .../fixtures/api/es-next/take-screenshot/test.js | 4 ++-- .../fixtures/browser-provider/browser-reconnect/test.js | 2 +- test/functional/fixtures/screenshots-on-fails/test.js | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5b2ce778..b0ca9d0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,13 +14,13 @@ matrix: env: GULP_TASK="test-server" - node_js: "stable" env: GULP_TASK="test-server" - - node_js: "stable" + - node_js: "8" env: GULP_TASK="test-client-travis" - - node_js: "stable" + - node_js: "8" env: GULP_TASK="test-client-travis-mobile" - - node_js: "stable" + - node_js: "8" env: GULP_TASK="test-functional-local-headless-chrome" - - node_js: "stable" + - node_js: "8" env: GULP_TASK="test-functional-local-headless-firefox" fast_finish: true diff --git a/appveyor.yml b/appveyor.yml index a7c1ef13..80b869ef 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ branches: - new-docs environment: - NODEJS_VERSION: "stable" + NODEJS_VERSION: "8" matrix: - GULP_TASK: "test-functional-local-ie" diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 371da70f..7815703e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -27,7 +27,7 @@ steps: condition: and(succeeded(), not(variables['isDocCommit'])) timeoutInMinutes: 40 inputs: - versionSpec: '11.x' + versionSpec: '8.x' - bash: | npm install --no-progress --loglevel error diff --git a/test/functional/config.js b/test/functional/config.js index 3dbc35be..0410bc8a 100644 --- a/test/functional/config.js +++ b/test/functional/config.js @@ -110,6 +110,8 @@ testingEnvironments[testingEnvironmentNames.localBrowsers] = { testingEnvironments[testingEnvironmentNames.localBrowsersIE] = { isLocalBrowsers: true, + retryTestPages: true, + browsers: [ { platform: 'Windows 10', @@ -141,6 +143,8 @@ testingEnvironments[testingEnvironmentNames.localHeadlessChrome] = { isLocalBrowsers: true, isHeadlessBrowsers: true, + retryTestPages: true, + browsers: [ { platform: 'Windows 10', @@ -155,6 +159,8 @@ testingEnvironments[testingEnvironmentNames.localHeadlessFirefox] = { isLocalBrowsers: true, isHeadlessBrowsers: true, + retryTestPages: true, + browsers: [ { platform: 'Windows 10', diff --git a/test/functional/fixtures/api/es-next/take-screenshot/test.js b/test/functional/fixtures/api/es-next/take-screenshot/test.js index a02505f8..8cfbdfb5 100644 --- a/test/functional/fixtures/api/es-next/take-screenshot/test.js +++ b/test/functional/fixtures/api/es-next/take-screenshot/test.js @@ -48,7 +48,7 @@ const getReporter = function (scope) { }; describe('[API] t.takeScreenshot()', function () { - if (config.useLocalBrowsers) { + if (config.useLocalBrowsers && config.currentEnvironmentName !== config.testingEnvironmentNames.localBrowsersIE) { afterEach(assertionHelper.removeScreenshotDir); it('Should take a screenshot', function () { @@ -250,7 +250,7 @@ describe('[API] t.takeScreenshot()', function () { }); describe('[API] t.takeElementScreenshot()', function () { - if (config.useLocalBrowsers) { + if (config.useLocalBrowsers && config.currentEnvironmentName !== config.testingEnvironmentNames.localBrowsersIE) { afterEach(assertionHelper.removeScreenshotDir); it('Should take screenshot of an element', function () { diff --git a/test/functional/fixtures/browser-provider/browser-reconnect/test.js b/test/functional/fixtures/browser-provider/browser-reconnect/test.js index 8341758d..60b7238b 100644 --- a/test/functional/fixtures/browser-provider/browser-reconnect/test.js +++ b/test/functional/fixtures/browser-provider/browser-reconnect/test.js @@ -27,7 +27,7 @@ function createConnection (browser) { .then(browserInfo => new BrowserConnection(testCafe.browserConnectionGateway, browserInfo, false)); } -async function run (pathToTest, filter) { +function run (pathToTest, filter) { const src = path.join(__dirname, pathToTest); const browserNames = config.currentEnvironment.browsers.map(browser => browser.browserName || browser.alias); diff --git a/test/functional/fixtures/screenshots-on-fails/test.js b/test/functional/fixtures/screenshots-on-fails/test.js index 328c1339..cedae652 100644 --- a/test/functional/fixtures/screenshots-on-fails/test.js +++ b/test/functional/fixtures/screenshots-on-fails/test.js @@ -7,7 +7,7 @@ const REPORT_SCREENSHOT_PATH_TEXT_RE = /___test-screenshots___[\\/]\d{4,4}-\ const ERROR_SCREENSHOT_PATH_RE = /Screenshot: .*?___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1[\\/]\S+[\\/]errors[\\/]\d.png/; const QUARANTINE_MODE_SCREENSHOT_PATH_RE = /Screenshot: .*?___test-screenshots___[\\/]\d{4,4}-\d{2,2}-\d{2,2}_\d{2,2}-\d{2,2}-\d{2,2}[\\/]test-1[\\/]run-3[\\/]\S+[\\/]errors[\\/]\d.png/; -if (config.useLocalBrowsers) { +if (config.useLocalBrowsers && config.currentEnvironmentName !== config.testingEnvironmentNames.localBrowsersIE) { describe('Screenshots on fails', function () { afterEach(assertionHelper.removeScreenshotDir); From 4182d8e3937e8ed3004636ba176a962dcfee6903 Mon Sep 17 00:00:00 2001 From: aleks-pro Date: Fri, 2 Nov 2018 14:27:29 +0300 Subject: [PATCH 170/184] export getNextFocusableElement method (#3068) --- src/client/automation/index.js | 2 ++ src/client/automation/playback/press/utils.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/automation/index.js b/src/client/automation/index.js index da4ebe83..b5e13df3 100644 --- a/src/client/automation/index.js +++ b/src/client/automation/index.js @@ -19,6 +19,7 @@ import { } from '../../test-run/commands/options'; import AutomationSettings from './settings'; import { getOffsetOptions } from './utils/offsets'; +import { getNextFocusableElement } from './playback/press/utils'; import calculateSelectTextArguments from './playback/select/calculate-select-text-arguments'; import ERROR_TYPES from './errors'; import cursor from './cursor'; @@ -46,6 +47,7 @@ exports.AutomationSettings = AutomationSettings; exports.getOffsetOptions = getOffsetOptions; exports.calculateSelectTextArguments = calculateSelectTextArguments; exports.cursor = cursor; +exports.getNextFocusableElement = getNextFocusableElement; exports.get = require; diff --git a/src/client/automation/playback/press/utils.js b/src/client/automation/playback/press/utils.js index a63f980a..7c94d627 100644 --- a/src/client/automation/playback/press/utils.js +++ b/src/client/automation/playback/press/utils.js @@ -140,7 +140,7 @@ function correctFocusableElement (elements, element, skipRadioGroups) { return checkedRadioButtonElementWithSameName || element; } -function getNextFocusableElement (element, reverse, skipRadioGroups) { +export function getNextFocusableElement (element, reverse, skipRadioGroups) { const offset = reverse ? -1 : 1; let allFocusable = domUtils.getFocusableElements(findDocument(element), true); From b2f3b36ddb9a7278fd47e23e2acfacf716593642 Mon Sep 17 00:00:00 2001 From: Mikhail Losev Date: Fri, 2 Nov 2018 16:25:28 +0300 Subject: [PATCH 171/184] alpha 3 (#3072) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fb5b0d14..c9b425fc 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.23.1-alpha.2", + "version": "0.23.1-alpha.3", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From 7b868d852fb3c304854d80e659c40ccfb3dda5ba Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Tue, 6 Nov 2018 14:04:25 +0300 Subject: [PATCH 172/184] Change the main menu in light of the new support page (#3053) --- docs/nav/top-menu-items.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/nav/top-menu-items.yml b/docs/nav/top-menu-items.yml index 7593ee1c..001497d7 100644 --- a/docs/nav/top-menu-items.yml +++ b/docs/nav/top-menu-items.yml @@ -6,16 +6,10 @@ external: true - text: FAQ url: /faq/ -# - text: Publications -# url: /publications/ - text: Release Notes url: /blog/ -- text: Issues - url: https://github.com/DevExpress/testcafe/issues - external: true -- text: Q&A - url: https://stackoverflow.com/questions/tagged/testcafe - external: true +- text: Support + url: /support/ - text: TestCafe Studio url: https://testcafe-studio.devexpress.com external: true From 6decba50f93cde0cf5a11b0fa6e7a7b14c15a6d1 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Tue, 6 Nov 2018 17:13:55 +0300 Subject: [PATCH 173/184] Fix importing pure TS module from a TS test file (#3061) * Fix origExt is not a function while using TypeScript node modules * Add a test --- .gitignore | 2 +- src/compiler/test-file/api-based.js | 2 +- test/server/compiler-test.js | 10 ++++++++++ .../node_modules/test-module/index.ts | 1 + .../node_modules/test-module/package.json | 11 +++++++++++ .../typescript-pure-ts-module-dep/testfile.ts | 11 +++++++++++ 6 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 test/server/data/test-suites/typescript-pure-ts-module-dep/node_modules/test-module/index.ts create mode 100644 test/server/data/test-suites/typescript-pure-ts-module-dep/node_modules/test-module/package.json create mode 100644 test/server/data/test-suites/typescript-pure-ts-module-dep/testfile.ts diff --git a/.gitignore b/.gitignore index f28c0e62..bedcb6f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -node_modules +/node_modules .idea .vscode /lib diff --git a/src/compiler/test-file/api-based.js b/src/compiler/test-file/api-based.js index 61eb9bff..f3124706 100644 --- a/src/compiler/test-file/api-based.js +++ b/src/compiler/test-file/api-based.js @@ -72,7 +72,7 @@ export default class APIBasedTestFileCompilerBase extends TestFileCompilerBase { // NOTE: remove global API so that it will be unavailable for the dependencies this._removeGlobalAPI(); - if (APIBasedTestFileCompilerBase._isNodeModulesDep(filename)) + if (APIBasedTestFileCompilerBase._isNodeModulesDep(filename) && origExt) origExt(mod, filename); else { diff --git a/test/server/compiler-test.js b/test/server/compiler-test.js index c0546df4..f2e2eaf5 100644 --- a/test/server/compiler-test.js +++ b/test/server/compiler-test.js @@ -310,6 +310,16 @@ describe('Compiler', function () { }); }); + it('Should import pure TypeScript dependency module', () => { + return compile('test/server/data/test-suites/typescript-pure-ts-module-dep/testfile.ts') + .then(function (compiled) { + return compiled.tests[0].fn(testRunMock); + }) + .then(function (result) { + expect(result.exportableLib).eql(exportableLib); + expect(result.exportableLib).eql(result.exportableLibInDep); + }); + }); }); diff --git a/test/server/data/test-suites/typescript-pure-ts-module-dep/node_modules/test-module/index.ts b/test/server/data/test-suites/typescript-pure-ts-module-dep/node_modules/test-module/index.ts new file mode 100644 index 00000000..1382ec43 --- /dev/null +++ b/test/server/data/test-suites/typescript-pure-ts-module-dep/node_modules/test-module/index.ts @@ -0,0 +1 @@ +export * from 'testcafe'; diff --git a/test/server/data/test-suites/typescript-pure-ts-module-dep/node_modules/test-module/package.json b/test/server/data/test-suites/typescript-pure-ts-module-dep/node_modules/test-module/package.json new file mode 100644 index 00000000..d9d4ad1a --- /dev/null +++ b/test/server/data/test-suites/typescript-pure-ts-module-dep/node_modules/test-module/package.json @@ -0,0 +1,11 @@ +{ + "name": "test-module", + "version": "1.0.0", + "description": "", + "main": "index.ts", + "scripts": { + "test": "echo \"OK\"" + }, + "author": "", + "license": "ISC" +} diff --git a/test/server/data/test-suites/typescript-pure-ts-module-dep/testfile.ts b/test/server/data/test-suites/typescript-pure-ts-module-dep/testfile.ts new file mode 100644 index 00000000..01065f37 --- /dev/null +++ b/test/server/data/test-suites/typescript-pure-ts-module-dep/testfile.ts @@ -0,0 +1,11 @@ +import * as exportableLib from 'testcafe'; +import * as exportableLibInDep from 'test-module'; + +fixture `Fixture`; + +test('Get common runtime funcs', async() => { + return { + exportableLibInDep, + exportableLib + }; +}); From fdc9df6749cce4f25523c4ed9e1932941706a432 Mon Sep 17 00:00:00 2001 From: Artem Lavrov Date: Wed, 7 Nov 2018 13:45:15 +0300 Subject: [PATCH 174/184] bump version (v0.23.1-alpha.4) --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c9b425fc..ddd22fb0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.23.1-alpha.3", + "version": "0.23.1-alpha.4", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" @@ -109,7 +109,7 @@ "source-map-support": "^0.5.5", "strip-bom": "^2.0.0", "testcafe-browser-tools": "1.6.5", - "testcafe-hammerhead": "14.4.0", + "testcafe-hammerhead": "14.4.1", "testcafe-legacy-api": "3.1.8", "testcafe-reporter-json": "^2.1.0", "testcafe-reporter-list": "^2.1.0", From b5dc8893731c9e08518daaac3a54fe9fd7dcc1f7 Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Wed, 7 Nov 2018 19:00:28 +0300 Subject: [PATCH 175/184] [docs] Merge documentation for v0.23.1 (#3087) --- CHANGELOG.md | 53 ++++++++++++++++ .../2018-11-7-testcafe-v0-23-1-released.md | 61 +++++++++++++++++++ .../using-testcafe/command-line-interface.md | 58 ++++++++++++++++++ .../programming-interface/runner.md | 25 +++++--- 4 files changed, 187 insertions(+), 10 deletions(-) create mode 100644 docs/articles/blog/2018-11-7-testcafe-v0-23-1-released.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 50b2f3c4..34a82ea9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,58 @@ # Changelog +## v0.23.1 (2018-11-7) + +### Enhancements + +#### :gear: Select Tests and Fixtures to Run by Their Metadata ([#2527](https://github.com/DevExpress/testcafe/issues/2527)) by [@NickCis](https://github.com/NickCis) + +You can now run only those tests or fixtures whose [metadata](https://devexpress.github.io/testcafe/documentation/test-api/test-code-structure.html#specifying-testing-metadata) contains a specific set of values. + +Use the [--test-meta](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--test-meta-keyvaluekey2value2) flag to specify values to look for in test metadata. + +```sh +testcafe chrome my-tests --test-meta device=mobile,env=production +``` + +To select fixtures by their metadata, use the [--fixture-meta](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--fixture-meta-keyvaluekey2value2) flag. + +```sh +testcafe chrome my-tests --fixture-meta subsystem=payments,type=regression +``` + +In the API, test and fixture metadata is now passed to the [runner.filter](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#filter) method in the `testMeta` and `fixtureMeta` parameters. Use this metadata to decide whether to run the current test. + +```js +runner.filter((testName, fixtureName, fixturePath, testMeta, fixtureMeta) => { + return testMeta.mobile === 'true' && + fixtureMeta.env === 'staging'; +}); +``` + +#### :gear: Run Dynamically Loaded Tests ([#2074](https://github.com/DevExpress/testcafe/issues/2074)) + +You can now run tests imported from external libraries or generated dynamically even if the `.js` file you provide to TestCafe does not contain any tests. + +Previously, this was not possible because TestCafe required test files to contain the [fixture](https://devexpress.github.io/testcafe/documentation/test-api/test-code-structure.html#fixtures) and [test](https://devexpress.github.io/testcafe/documentation/test-api/test-code-structure.html#tests) directives. Now you can bypass this check. To do this, provide the [--disable-test-syntax-validation](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--disable-test-syntax-validation) command line flag. + +```sh +testcafe safari test.js --disable-test-syntax-validation +``` + +In the API, use the [disableTestSyntaxValidation](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#run) option. + +```js +runner.run({ disableTestSyntaxValidation: true }) +``` + +### Bug Fixes + +* Touch events are now simulated with correct touch properties (`touches`, `targetTouches`, `changedTouches`) ([#2856](https://github.com/DevExpress/testcafe/issues/2856)) +* Google Chrome now closes correctly on macOS after tests are finished ([#2860](https://github.com/DevExpress/testcafe/issues/2860)) +* Internal attribute and node changes no longer provoke `MutationObserver` notifications ([testcafe-hammerhead/#1769](https://github.com/DevExpress/testcafe-hammerhead/issues/1769)) +* The `ECONNABORTED` error is no longer raised ([testcafe-hammerhead/#1744](https://github.com/DevExpress/testcafe-hammerhead/issues/1744)) +* Websites that use `Location.ancestorOrigins` are now proxied correctly ([testcafe-hammerhead/#1342](https://github.com/DevExpress/testcafe-hammerhead/issues/1342)) + ## v0.23.0 (2018-10-25) ### Enhancements diff --git a/docs/articles/blog/2018-11-7-testcafe-v0-23-1-released.md b/docs/articles/blog/2018-11-7-testcafe-v0-23-1-released.md new file mode 100644 index 00000000..f7b8d7cf --- /dev/null +++ b/docs/articles/blog/2018-11-7-testcafe-v0-23-1-released.md @@ -0,0 +1,61 @@ +--- +layout: post +title: TestCafe v0.23.1 Released +permalink: /blog/:title.html +--- +# TestCafe v0.23.1 Released + +Select tests and fixtures to run by their metadata and run dynamically loaded tests. + + + +## Enhancements + +### ⚙ Select Tests and Fixtures to Run by Their Metadata ([#2527](https://github.com/DevExpress/testcafe/issues/2527)) by [@NickCis](https://github.com/NickCis) + +You can now run only those tests or fixtures whose [metadata](https://devexpress.github.io/testcafe/documentation/test-api/test-code-structure.html#specifying-testing-metadata) contains a specific set of values. + +Use the [--test-meta](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--test-meta-keyvaluekey2value2) flag to specify values to look for in test metadata. + +```sh +testcafe chrome my-tests --test-meta device=mobile,env=production +``` + +To select fixtures by their metadata, use the [--fixture-meta](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--fixture-meta-keyvaluekey2value2) flag. + +```sh +testcafe chrome my-tests --fixture-meta subsystem=payments,type=regression +``` + +In the API, test and fixture metadata is now passed to the [runner.filter](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#filter) method in the `testMeta` and `fixtureMeta` parameters. Use this metadata to decide whether to run the current test. + +```js +runner.filter((testName, fixtureName, fixturePath, testMeta, fixtureMeta) => { + return testMeta.mobile === 'true' && + fixtureMeta.env === 'staging'; +}); +``` + +### ⚙ Run Dynamically Loaded Tests ([#2074](https://github.com/DevExpress/testcafe/issues/2074)) + +You can now run tests imported from external libraries or generated dynamically even if the `.js` file you provide to TestCafe does not contain any tests. + +Previously, this was not possible because TestCafe required test files to contain the [fixture](https://devexpress.github.io/testcafe/documentation/test-api/test-code-structure.html#fixtures) and [test](https://devexpress.github.io/testcafe/documentation/test-api/test-code-structure.html#tests) directives. Now you can bypass this check. To do this, provide the [--disable-test-syntax-validation](https://devexpress.github.io/testcafe/documentation/using-testcafe/command-line-interface.html#--disable-test-syntax-validation) command line flag. + +```sh +testcafe safari test.js --disable-test-syntax-validation +``` + +In the API, use the [disableTestSyntaxValidation](https://devexpress.github.io/testcafe/documentation/using-testcafe/programming-interface/runner.html#run) option. + +```js +runner.run({ disableTestSyntaxValidation: true }) +``` + +## Bug Fixes + +* Touch events are now simulated with correct touch properties (`touches`, `targetTouches`, `changedTouches`) ([#2856](https://github.com/DevExpress/testcafe/issues/2856)) +* Google Chrome now closes correctly on macOS after tests are finished ([#2860](https://github.com/DevExpress/testcafe/issues/2860)) +* Internal attribute and node changes no longer provoke `MutationObserver` notifications ([testcafe-hammerhead/#1769](https://github.com/DevExpress/testcafe-hammerhead/issues/1769)) +* The `ECONNABORTED` error is no longer raised ([testcafe-hammerhead/#1744](https://github.com/DevExpress/testcafe-hammerhead/issues/1744)) +* Websites that use `Location.ancestorOrigins` are now proxied correctly ([testcafe-hammerhead/#1342](https://github.com/DevExpress/testcafe-hammerhead/issues/1342)) diff --git a/docs/articles/documentation/using-testcafe/command-line-interface.md b/docs/articles/documentation/using-testcafe/command-line-interface.md index 14d0ba7d..691cb2b6 100644 --- a/docs/articles/documentation/using-testcafe/command-line-interface.md +++ b/docs/articles/documentation/using-testcafe/command-line-interface.md @@ -35,6 +35,8 @@ testcafe [options] * [-T \, --test-grep \](#-t-pattern---test-grep-pattern) * [-f \, --fixture \](#-f-name---fixture-name) * [-F \, --fixture-grep \](#-f-pattern---fixture-grep-pattern) + * [--test-meta \](#--test-meta-keyvaluekey2value2) + * [--fixture-meta \](#--fixture-meta-keyvaluekey2value2) * [-a \, --app \](#-a-command---app-command) * [-c \, --concurrency \](#-c-n---concurrency-n) * [--debug-on-fail](#--debug-on-fail) @@ -51,6 +53,7 @@ testcafe [options] * [--dev](#--dev) * [--qr-code](#--qr-code) * [--sf, --stop-on-first-fail](#--sf---stop-on-first-fail) + * [--disable-test-syntax-validation](#--disable-test-syntax-validation) * [--color](#--color) * [--no-color](#--no-color) @@ -420,6 +423,26 @@ For example, the following command runs fixtures whose names match `Page.*`. The testcafe ie my-tests -F "Page.*" ``` +### --test-meta \ + +TestCafe runs tests whose [metadata](../test-api/test-code-structure.md#specifying-testing-metadata) [matches](https://lodash.com/docs/#isMatch) the specified key-value pair. + +For example, the following command runs tests whose metadata has the `device` property set to the `mobile` value and the `env` property set to the `production` value. + +```sh +testcafe chrome my-tests --test-meta device=mobile,env=production +``` + +### --fixture-meta \ + +TestCafe runs tests whose fixture's [metadata](../test-api/test-code-structure.md#specifying-testing-metadata) [matches](https://lodash.com/docs/#isMatch) the specified key-value pair. + +For example, the following command runs tests whose fixture's metadata has the `device` property set to the `mobile` value and the `env` property set to the `production` value. + +```sh +testcafe chrome my-tests --fixture-meta device=mobile,env=production +``` + ### -a \, --app \ Executes the specified shell command before running tests. Use it to launch or deploy the application you are going to test. @@ -622,6 +645,41 @@ Stops an entire test run if any test fails. This allows you not to wait for all testcafe chrome my-tests --sf ``` +### --disable-test-syntax-validation + +Disables checks for `test` and `fixture` directives in test files. Use this flag to run dynamically loaded tests. + +TestCafe requires test files to have the [fixture](../test-api/test-code-structure.md#fixtures) and [test](../test-api/test-code-structure.md#tests) directives. Otherwise, an error is thrown. + +However, when you import tests from external libraries or generate them dynamically, the `.js` file provided to TestCafe may not contain any tests. + +**external-lib.js** + +```js +export default function runTests () { + fixture `External tests` + .page `http:///example.com`; + + test('My Test', async t => { + // ... + }); +} +``` + +**test.js** + +```js +import runTests from './external-lib'; + +runTests(); +``` + +In this instance, specify the `--disable-test-syntax-validation` flag to bypass checks for test syntax. + +```sh +testcafe safari test.js --disable-test-syntax-validation +``` + ### --color Enables colors in the command line. diff --git a/docs/articles/documentation/using-testcafe/programming-interface/runner.md b/docs/articles/documentation/using-testcafe/programming-interface/runner.md index 9bba77e3..f30722b5 100644 --- a/docs/articles/documentation/using-testcafe/programming-interface/runner.md +++ b/docs/articles/documentation/using-testcafe/programming-interface/runner.md @@ -87,9 +87,9 @@ Allows you to select which tests should be run. filter(callback) → this ``` -Parameter | Type | Description ----------- | ---------------------------------------------- | ---------------------------------------------------------------- -`callback` | `function(testName, fixtureName, fixturePath)` | The callback that determines if a particular test should be run. +Parameter | Type | Description +---------- | --------------------------------------------------------------------- | ---------------------------------------------------------------- +`callback` | `function(testName, fixtureName, fixturePath, testMeta, fixtureMeta)` | The callback that determines if a particular test should be run. The callback function is called for each test in the files specified using the [src](#src) method. @@ -97,19 +97,23 @@ Return `true` from the callback to include the current test or `false` to exclud The callback function accepts the following arguments: -Parameter | Type | Description -------------- | ------ | ---------------------------------- -`testName` | String | The name of the test. -`fixtureName` | String | The name of the test fixture. -`fixturePath` | String | The path to the test fixture file. +Parameter | Type | Description +------------- | ------------------------ | ---------------------------------- +`testName` | String | The name of the test. +`fixtureName` | String | The name of the test fixture. +`fixturePath` | String | The path to the test fixture file. +`testMeta` | Object\ | The test metadata. +`fixtureMeta` | Object\ | The fixture metadata. **Example** ```js -runner.filter((testName, fixtureName, fixturePath) => { +runner.filter((testName, fixtureName, fixturePath, testMeta, fixtureMeta) => { return fixturePath.startsWith('D') && testName.match(someRe) && - fixtureName.match(anotherRe); + fixtureName.match(anotherRe) && + testMeta.mobile === 'true' && + fixtureMeta.env === 'staging'; }); ``` @@ -418,6 +422,7 @@ Parameter | Type | Description `pageLoadTimeout` | Number | Specifies the time (in milliseconds) passed after the `DOMContentLoaded` event, within which TestCafe waits for the `window.load` event to fire. After the timeout passes or the `window.load` event is raised (whichever happens first), TestCafe starts the test. You can set this timeout to `0` to skip waiting for `window.load`. | `3000` `speed` | Number | Specifies the test execution speed. Should be a number between `1` (the fastest) and `0.01` (the slowest). If speed is also specified for an [individual action](../../test-api/actions/action-options.md#basic-action-options), the action speed setting overrides test speed. | `1` `stopOnFirstFail` | Boolean | Defines whether to stop an entire test run if any test fails. This allows you not to wait for all the tests included in the test task to finish and allows focusing on the first error. | `false` +`disableTestSyntaxValidation` | Boolean | Defines whether to disable checks for [test](../../test-api/test-code-structure.md#tests) and [fixture](../../test-api/test-code-structure.md#fixtures) directives in test files. Use this option to run dynamically loaded tests. See details in the [--disable-test-syntax-validation](../command-line-interface.md#--disable-test-syntax-validation) command line option description. | `false` After all tests are finished, call the [testcafe.close](testcafe.md#close) function to stop the TestCafe server. From ce7fa9233a8d980068fee883052491122a8b668f Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Wed, 7 Nov 2018 19:03:23 +0300 Subject: [PATCH 176/184] Bump version (v0.23.1) (#3085) --- .publishrc | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.publishrc b/.publishrc index 2414a453..5727c783 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "alpha", + "publishTag": "latest", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index ddd22fb0..cfcf097f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.23.1-alpha.4", + "version": "0.23.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From f105949a8cf5de6ddc27fa51fb2e94eccc298824 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Fri, 9 Nov 2018 16:36:56 +0300 Subject: [PATCH 177/184] Improve startup time (#2984) * Improve startup time (closes #2912) * Export upload utils * Fix lazy loading for empty project * Load compilers when accessing parser functions * Fix remarks --- package.json | 1 + src/.eslintrc | 4 +- src/api/exportable-lib/index.js | 39 ++++++--- src/browser/provider/built-in/chrome/index.js | 11 +-- .../provider/built-in/firefox/index.js | 11 +-- src/browser/provider/index.js | 49 ++++++----- src/browser/provider/plugin-host.js | 5 +- src/cli/cli.js | 4 +- src/client/.eslintrc | 3 +- src/embedding-utils.js | 83 ++++++++++++++----- src/index.js | 9 +- src/load-assets.js | 28 +++++++ src/runner/bootstrapper.js | 59 ++++++++++++- src/test-run/commands/actions.js | 2 +- src/test-run/commands/assertion.js | 2 +- .../commands/validations/initializers.js | 2 +- src/test-run/execute-js-expression.js | 2 +- src/test-run/index.js | 48 +++++------ src/testcafe.js | 48 +++++------ test/server/create-testcafe-test.js | 2 +- test/server/runner-test.js | 4 +- 21 files changed, 276 insertions(+), 140 deletions(-) create mode 100644 src/load-assets.js diff --git a/package.json b/package.json index cfcf097f..a6faab1c 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "globby": "^3.0.1", "graceful-fs": "^4.1.11", "gulp-data": "^1.3.1", + "import-lazy": "^3.1.0", "indent-string": "^1.2.2", "is-ci": "^1.0.10", "is-glob": "^2.0.1", diff --git a/src/.eslintrc b/src/.eslintrc index bc3f5083..446f2ca2 100644 --- a/src/.eslintrc +++ b/src/.eslintrc @@ -6,6 +6,8 @@ }, "globals": { "Map": true, - "Set": true + "Set": true, + "Proxy": true, + "Reflect": true } } diff --git a/src/api/exportable-lib/index.js b/src/api/exportable-lib/index.js index f69e433f..dfc672bb 100644 --- a/src/api/exportable-lib/index.js +++ b/src/api/exportable-lib/index.js @@ -1,13 +1,18 @@ -import ClientFunctionBuilder from '../../client-functions/client-function-builder'; -import SelectorBuilder from '../../client-functions/selectors/selector-builder'; -import { createRole, createAnonymousRole } from '../../role'; -import testControllerProxy from '../test-controller/proxy'; -import createRequestLogger from '../request-hooks/request-logger'; -import createRequestMock from '../request-hooks/request-mock'; -import RequestHook from '../request-hooks/hook'; +const lazyRequire = require('import-lazy')(require); +const ClientFunctionBuilder = lazyRequire('../../client-functions/client-function-builder'); +const SelectorBuilder = lazyRequire('../../client-functions/selectors/selector-builder'); +const role = lazyRequire('../../role'); +const createRequestLogger = lazyRequire('../request-hooks/request-logger'); +const createRequestMock = lazyRequire('../request-hooks/request-mock'); + +// NOTE: We can't use lazy require for RequestHook, because it will break base class detection for inherited classes +let RequestHook = null; + +// NOTE: We can't use lazy require for testControllerProxy, because it will break test controller detection +let testControllerProxy = null; function Role (loginPage, initFn, options) { - return createRole(loginPage, initFn, options); + return role.createRole(loginPage, initFn, options); } function RequestMock () { @@ -30,7 +35,9 @@ function Selector (fn, options) { return builder.getFunction(); } -Role.anonymous = createAnonymousRole; +Object.defineProperty(Role, 'anonymous', { + get: () => role.createAnonymousRole +}); export default { Role, @@ -43,7 +50,17 @@ export default { RequestMock, - RequestHook, + get RequestHook () { + if (!RequestHook) + RequestHook = require('../request-hooks/hook'); + + return RequestHook; + }, + + get t () { + if (!testControllerProxy) + testControllerProxy = require('../test-controller/proxy'); - t: testControllerProxy + return testControllerProxy; + } }; diff --git a/src/browser/provider/built-in/chrome/index.js b/src/browser/provider/built-in/chrome/index.js index 2c7c8ffd..dc7cada8 100644 --- a/src/browser/provider/built-in/chrome/index.js +++ b/src/browser/provider/built-in/chrome/index.js @@ -1,7 +1,6 @@ import OS from 'os-family'; import { parse as parseUrl } from 'url'; import getRuntimeInfo from './runtime-info'; -import getConfig from './config'; import { start as startLocalChrome, stop as stopLocalChrome } from './local-chrome'; import * as cdp from './cdp'; import getMaximizedHeadlessWindowSize from '../../utils/get-maximized-headless-window-size'; @@ -52,16 +51,12 @@ export default { delete this.openedBrowsers[browserId]; }, - async isLocalBrowser (browserId, configString) { - const config = this.openedBrowsers[browserId] ? this.openedBrowsers[browserId].config : getConfig(configString); - - return !config.headless; + async isLocalBrowser () { + return true; }, isHeadlessBrowser (browserId) { - const config = this.openedBrowsers[browserId].config; - - return config && config.headless; + return this.openedBrowsers[browserId].config.headless; }, async takeScreenshot (browserId, path) { diff --git a/src/browser/provider/built-in/firefox/index.js b/src/browser/provider/built-in/firefox/index.js index 98417699..2cf7c33c 100644 --- a/src/browser/provider/built-in/firefox/index.js +++ b/src/browser/provider/built-in/firefox/index.js @@ -2,7 +2,6 @@ import OS from 'os-family'; import getRuntimeInfo from './runtime-info'; import { start as startLocalFirefox, stop as stopLocalFirefox } from './local-firefox'; import MarionetteClient from './marionette-client'; -import getConfig from './config'; import getMaximizedHeadlessWindowSize from '../../utils/get-maximized-headless-window-size'; @@ -59,16 +58,12 @@ export default { delete this.openedBrowsers[browserId]; }, - async isLocalBrowser (browserId, configString) { - const config = this.openedBrowsers[browserId] ? this.openedBrowsers[browserId].config : getConfig(configString); - - return !config.headless; + async isLocalBrowser () { + return true; }, isHeadlessBrowser (browserId) { - const config = this.openedBrowsers[browserId].config; - - return config && config.headless; + return this.openedBrowsers[browserId].config.headless; }, async takeScreenshot (browserId, path) { diff --git a/src/browser/provider/index.js b/src/browser/provider/index.js index 03a8ed5f..bd9a4caf 100644 --- a/src/browser/provider/index.js +++ b/src/browser/provider/index.js @@ -168,6 +168,13 @@ export default class BrowserProvider { await browserTools.maximize(this._getWindowDescriptor(browserId)); } + async _canUseDefaultWindowActions (browserId) { + const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); + const isHeadlessBrowser = await this.plugin.isHeadlessBrowser(browserId); + + return isLocalBrowser && !isHeadlessBrowser; + } + async init () { const initialized = await this.initPromise; @@ -219,24 +226,22 @@ export default class BrowserProvider { async openBrowser (browserId, pageUrl, browserName) { await this.plugin.openBrowser(browserId, pageUrl, browserName); - const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - - if (isLocalBrowser) + if (await this._canUseDefaultWindowActions(browserId)) await this._ensureBrowserWindowParameters(browserId); } async closeBrowser (browserId) { - const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - const customActionsInfo = await this.hasCustomActionForBrowser(browserId); - const hasCustomCloseBrowser = customActionsInfo.hasCloseBrowser; - const usePluginsCloseBrowser = hasCustomCloseBrowser || !isLocalBrowser; + const canUseDefaultWindowActions = await this._canUseDefaultWindowActions(browserId); + const customActionsInfo = await this.hasCustomActionForBrowser(browserId); + const hasCustomCloseBrowser = customActionsInfo.hasCloseBrowser; + const usePluginsCloseBrowser = hasCustomCloseBrowser || !canUseDefaultWindowActions; if (usePluginsCloseBrowser) await this.plugin.closeBrowser(browserId); else await this._closeLocalBrowser(browserId); - if (isLocalBrowser) + if (canUseDefaultWindowActions) delete this.localBrowsersInfo[browserId]; } @@ -249,12 +254,12 @@ export default class BrowserProvider { } async resizeWindow (browserId, width, height, currentWidth, currentHeight) { - const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - const customActionsInfo = await this.hasCustomActionForBrowser(browserId); - const hasCustomResizeWindow = customActionsInfo.hasResizeWindow; + const canUseDefaultWindowActions = await this._canUseDefaultWindowActions(browserId); + const customActionsInfo = await this.hasCustomActionForBrowser(browserId); + const hasCustomResizeWindow = customActionsInfo.hasResizeWindow; - if (isLocalBrowser && !hasCustomResizeWindow) { + if (canUseDefaultWindowActions && !hasCustomResizeWindow) { await this._resizeLocalBrowserWindow(browserId, width, height, currentWidth, currentHeight); return; } @@ -263,34 +268,34 @@ export default class BrowserProvider { } async canResizeWindowToDimensions (browserId, width, height) { - const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); + const canUseDefaultWindowActions = await this._canUseDefaultWindowActions(browserId); const customActionsInfo = await this.hasCustomActionForBrowser(browserId); const hasCustomCanResizeToDimensions = customActionsInfo.hasCanResizeWindowToDimensions; - if (isLocalBrowser && !hasCustomCanResizeToDimensions) + if (canUseDefaultWindowActions && !hasCustomCanResizeToDimensions) return await this._canResizeLocalBrowserWindowToDimensions(browserId, width, height); return await this.plugin.canResizeWindowToDimensions(browserId, width, height); } async maximizeWindow (browserId) { - const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - const customActionsInfo = await this.hasCustomActionForBrowser(browserId); - const hasCustomMaximizeWindow = customActionsInfo.hasMaximizeWindow; + const canUseDefaultWindowActions = await this._canUseDefaultWindowActions(browserId); + const customActionsInfo = await this.hasCustomActionForBrowser(browserId); + const hasCustomMaximizeWindow = customActionsInfo.hasMaximizeWindow; - if (isLocalBrowser && !hasCustomMaximizeWindow) + if (canUseDefaultWindowActions && !hasCustomMaximizeWindow) return await this._maximizeLocalBrowserWindow(browserId); return await this.plugin.maximizeWindow(browserId); } async takeScreenshot (browserId, screenshotPath, pageWidth, pageHeight) { - const isLocalBrowser = await this.plugin.isLocalBrowser(browserId); - const customActionsInfo = await this.hasCustomActionForBrowser(browserId); - const hasCustomTakeScreenshot = customActionsInfo.hasTakeScreenshot; + const canUseDefaultWindowActions = await this._canUseDefaultWindowActions(browserId); + const customActionsInfo = await this.hasCustomActionForBrowser(browserId); + const hasCustomTakeScreenshot = customActionsInfo.hasTakeScreenshot; - if (isLocalBrowser && !hasCustomTakeScreenshot) { + if (canUseDefaultWindowActions && !hasCustomTakeScreenshot) { await this._takeLocalBrowserScreenshot(browserId, screenshotPath, pageWidth, pageHeight); return; } diff --git a/src/browser/provider/plugin-host.js b/src/browser/provider/plugin-host.js index a388330b..6608d7d6 100644 --- a/src/browser/provider/plugin-host.js +++ b/src/browser/provider/plugin-host.js @@ -95,11 +95,12 @@ export default class BrowserProviderPluginHost { } // Extra functions - async isLocalBrowser (/* browserId, browserName */) { + // NOTE: The browserName argument is optional, and must be supplied if the browserId argument is not valid (browser is not opened) + async isLocalBrowser (/* browserId[, browserName] */) { return false; } - isHeadlessBrowser () { + isHeadlessBrowser (/* browserId */) { return false; } diff --git a/src/cli/cli.js b/src/cli/cli.js index ed7f59f7..e36e5fd7 100644 --- a/src/cli/cli.js +++ b/src/cli/cli.js @@ -1,6 +1,5 @@ import fs from 'fs'; import chalk from 'chalk'; -import browserProviderPool from '../browser/provider/pool'; import { GeneralError, APIError } from '../errors/runtime'; import MESSAGE from '../errors/runtime/message'; import CliArgumentParser from './argument-parser'; @@ -111,6 +110,9 @@ async function runTests (argParser) { } async function listBrowsers (providerName = 'locally-installed') { + // NOTE: Load the provider pool lazily to reduce startup time + const browserProviderPool = require('../browser/provider/pool'); + const provider = await browserProviderPool.getProvider(providerName); if (!provider) diff --git a/src/client/.eslintrc b/src/client/.eslintrc index f49a9e28..62c8c447 100644 --- a/src/client/.eslintrc +++ b/src/client/.eslintrc @@ -6,7 +6,8 @@ }, "env": { "browser": true, - "node": false + "node": false, + "es6": false }, "plugins": [ "hammerhead" diff --git a/src/embedding-utils.js b/src/embedding-utils.js index 445c57ef..6000c1f6 100644 --- a/src/embedding-utils.js +++ b/src/embedding-utils.js @@ -1,27 +1,72 @@ -import ReporterPluginHost from './reporter/plugin-host'; -import TestRunErrorFormattableAdapter from './errors/test-run/formattable-adapter'; -import * as testRunErrors from './errors/test-run'; -import TestRun from './test-run'; -import COMMAND_TYPE from './test-run/commands/type'; -import Assignable from './utils/assignable'; -import { getTestList, getTestListFromCode } from './compiler/test-file/formats/es-next/get-test-list'; -import { getTypeScriptTestList, getTypeScriptTestListFromCode } from './compiler/test-file/formats/typescript/get-test-list'; -import { getCoffeeScriptTestList, getCoffeeScriptTestListFromCode } from './compiler/test-file/formats/coffeescript/get-test-list'; -import { initSelector } from './test-run/commands/validations/initializers'; +const lazyRequire = require('import-lazy')(require); +const hammerhead = lazyRequire('testcafe-hammerhead'); +const ReporterPluginHost = lazyRequire('./reporter/plugin-host'); +const TestRunErrorFormattableAdapter = lazyRequire('./errors/test-run/formattable-adapter'); +const testRunErrors = lazyRequire('./errors/test-run'); +const COMMAND_TYPE = lazyRequire('./test-run/commands/type'); +const getTestListModule = lazyRequire('./compiler/test-file/formats/es-next/get-test-list'); +const getTypeScriptTestListModule = lazyRequire('./compiler/test-file/formats/typescript/get-test-list'); +const getCoffeeScriptTestListModule = lazyRequire('./compiler/test-file/formats/coffeescript/get-test-list'); +const initializers = lazyRequire('./test-run/commands/validations/initializers'); + +// NOTE: we can't use lazy require for TestRun and Assignable, because it breaks prototype chain for inherited classes +let TestRun = null; +let Assignable = null; export default { - getTestList, - getTypeScriptTestList, - getCoffeeScriptTestList, - getTestListFromCode, - getTypeScriptTestListFromCode, - getCoffeeScriptTestListFromCode, TestRunErrorFormattableAdapter, - TestRun, testRunErrors, COMMAND_TYPE, - Assignable, - initSelector, + + get Assignable () { + if (!Assignable) + Assignable = require('./utils/assignable'); + + return Assignable; + }, + + get TestRun () { + if (!TestRun) + TestRun = require('./test-run'); + + return TestRun; + }, + + get getTestList () { + return getTestListModule.getTestList; + }, + + get getTypeScriptTestList () { + return getTypeScriptTestListModule.getTypeScriptTestList; + }, + + get getCoffeeScriptTestList () { + return getCoffeeScriptTestListModule.getCoffeeScriptTestList; + }, + + get getTestListFromCode () { + return getTestListModule.getTestListFromCode; + }, + + get getTypeScriptTestListFromCode () { + return getTypeScriptTestListModule.getTypeScriptTestListFromCode; + }, + + get getCoffeeScriptTestListFromCode () { + return getCoffeeScriptTestListModule.getCoffeeScriptTestListFromCode; + }, + + get initSelector () { + return initializers.initSelector; + }, + + ensureUploadDirectory (...args) { + return hammerhead.UploadStorage.ensureUploadsRoot(...args); + }, + + copyFilesToUploadFolder (...args) { + return hammerhead.UploadStorage.copy(...args); + }, buildReporterPlugin (pluginFactory, outStream) { const plugin = pluginFactory(); diff --git a/src/index.js b/src/index.js index d36fb3d7..bc75f6ca 100644 --- a/src/index.js +++ b/src/index.js @@ -1,12 +1,13 @@ import Promise from 'pinkie'; -import TestCafe from './testcafe'; -import * as endpointUtils from 'endpoint-utils'; -import setupExitHook from 'async-exit-hook'; import { GeneralError } from './errors/runtime'; import MESSAGE from './errors/runtime/message'; import embeddingUtils from './embedding-utils'; import exportableLib from './api/exportable-lib'; +const lazyRequire = require('import-lazy')(require); +const TestCafe = lazyRequire('./testcafe'); +const endpointUtils = lazyRequire('endpoint-utils'); +const setupExitHook = lazyRequire('async-exit-hook'); // Validations async function getValidHostname (hostname) { @@ -59,7 +60,7 @@ createTestCafe.embeddingUtils = embeddingUtils; // Common API Object.keys(exportableLib).forEach(key => { - createTestCafe[key] = exportableLib[key]; + Object.defineProperty(createTestCafe, key, { get: () => exportableLib[key] }); }); export default createTestCafe; diff --git a/src/load-assets.js b/src/load-assets.js new file mode 100644 index 00000000..65a80b9c --- /dev/null +++ b/src/load-assets.js @@ -0,0 +1,28 @@ +import { readSync as read } from 'read-file-relative'; + + +const ASSETS_CACHE = {}; + +function loadAsset (filename, asBuffer) { + if (!ASSETS_CACHE[filename]) + ASSETS_CACHE[filename] = read(filename, asBuffer); + + return ASSETS_CACHE[filename]; +} + +export default function (developmentMode) { + const scriptNameSuffix = developmentMode ? 'js' : 'min.js'; + + return { + favIcon: loadAsset('./client/ui/favicon.ico', true), + coreScript: loadAsset(`./client/core/index.${scriptNameSuffix}`), + driverScript: loadAsset(`./client/driver/index.${scriptNameSuffix}`), + uiScript: loadAsset(`./client/ui/index.${scriptNameSuffix}`), + uiStyle: loadAsset('./client/ui/styles.css'), + uiSprite: loadAsset('./client/ui/sprite.png', true), + automationScript: loadAsset(`./client/automation/index.${scriptNameSuffix}`), + + // NOTE: Load the legacy client script lazily to reduce startup time + legacyRunnerScript: require('testcafe-legacy-api').CLIENT_RUNNER_SCRIPT + }; +} diff --git a/src/runner/bootstrapper.js b/src/runner/bootstrapper.js index 5f6511fd..1ad17f2a 100644 --- a/src/runner/bootstrapper.js +++ b/src/runner/bootstrapper.js @@ -135,6 +135,57 @@ export default class Bootstrapper { return null; } + _canUseParallelBootstrapping (browserInfo) { + return browserInfo.every(browser => browser.provider.isLocalBrowser(null, browserInfo.browserName)); + } + + async _bootstrapSequence (browserInfo) { + const tests = await this._getTests(); + const testedApp = await this._startTestedApp(); + const browserSet = await this._getBrowserConnections(browserInfo); + + return { tests, testedApp, browserSet }; + } + + _wrapBootstrappingPromise (promise) { + return promise + .then(result => ({ error: null, result })) + .catch(error => ({ result: null, error })); + } + + async _handleBootstrappingError ([browserSetStatus, testsStatus, testedAppStatus]) { + if (!browserSetStatus.error) + await browserSetStatus.result.dispose(); + + if (!testedAppStatus.error && testedAppStatus.result) + await testedAppStatus.result.kill(); + + if (testsStatus.error) + throw testsStatus.error; + else if (testedAppStatus.error) + throw testedAppStatus.error; + else + throw browserSetStatus.error; + } + + async _bootstrapParallel (browserInfo) { + let bootstrappingPromises = [ + this._getBrowserConnections(browserInfo), + this._getTests(), + this._startTestedApp() + ]; + + bootstrappingPromises = bootstrappingPromises.map(promise => this._wrapBootstrappingPromise(promise)); + + const bootstrappingStatuses = await Promise.all(bootstrappingPromises); + + if (bootstrappingStatuses.some(status => status.error)) + await this._handleBootstrappingError(bootstrappingStatuses); + + const [browserSet, tests, testedApp] = bootstrappingStatuses.map(status => status.result); + + return { browserSet, tests, testedApp }; + } // API async createRunnableConfiguration () { @@ -145,10 +196,10 @@ export default class Bootstrapper { // It's very ambiguous for the user, who might be confused by compilation errors from an unexpected test. // So, we need to retrieve the browser aliases and paths before tests compilation. const browserInfo = await this._getBrowserInfo(); - const tests = await this._getTests(); - const testedApp = await this._startTestedApp(); - const browserSet = await this._getBrowserConnections(browserInfo); - return { reporterPlugins, browserSet, tests, testedApp }; + if (this._canUseParallelBootstrapping(browserInfo)) + return { reporterPlugins, ...await this._bootstrapParallel(browserInfo) }; + + return { reporterPlugins, ...await this._bootstrapSequence(browserInfo) }; } } diff --git a/src/test-run/commands/actions.js b/src/test-run/commands/actions.js index bfc67834..6bf170ce 100644 --- a/src/test-run/commands/actions.js +++ b/src/test-run/commands/actions.js @@ -5,7 +5,7 @@ import functionBuilderSymbol from '../../client-functions/builder-symbol'; import CommandBase from './base'; import { ActionOptions, ClickOptions, MouseOptions, TypeOptions, DragToElementOptions } from './options'; import { initSelector, initUploadSelector } from './validations/initializers'; -import { executeJsExpression } from '../execute-js-expression'; +import executeJsExpression from '../execute-js-expression'; import { isJSExpression } from './utils'; import { diff --git a/src/test-run/commands/assertion.js b/src/test-run/commands/assertion.js index 47b16e71..7e8ae8b9 100644 --- a/src/test-run/commands/assertion.js +++ b/src/test-run/commands/assertion.js @@ -3,7 +3,7 @@ import CommandBase from './base'; import { AssertionOptions } from './options'; import { APIError } from '../../errors/runtime'; import { AssertionExecutableArgumentError } from '../../errors/test-run'; -import { executeJsExpression } from '../execute-js-expression'; +import executeJsExpression from '../execute-js-expression'; import { isJSExpression } from './utils'; import { stringArgument, actionOptions, nonEmptyStringArgument } from './validations/argument'; diff --git a/src/test-run/commands/validations/initializers.js b/src/test-run/commands/validations/initializers.js index 367fb0fa..73e7cd3b 100644 --- a/src/test-run/commands/validations/initializers.js +++ b/src/test-run/commands/validations/initializers.js @@ -2,7 +2,7 @@ import SelectorBuilder from '../../../client-functions/selectors/selector-builde import { ActionSelectorError } from '../../../errors/test-run'; import { APIError } from '../../../errors/runtime'; import { ExecuteSelectorCommand } from '../observation'; -import { executeJsExpression } from '../../execute-js-expression'; +import executeJsExpression from '../../execute-js-expression'; import { isJSExpression } from '../utils'; export function initUploadSelector (name, val, initOptions) { diff --git a/src/test-run/execute-js-expression.js b/src/test-run/execute-js-expression.js index e69d57ac..16e9cbd5 100644 --- a/src/test-run/execute-js-expression.js +++ b/src/test-run/execute-js-expression.js @@ -56,7 +56,7 @@ function createExecutionContext (testRun) { return createContext(sandbox); } -export function executeJsExpression (expression, testRun, options) { +export default function (expression, testRun, options) { const context = getContext(testRun, options); return runInContext(expression, context, { displayErrors: false }); diff --git a/src/test-run/index.js b/src/test-run/index.js index 1bfa09eb..dac6cd35 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -5,40 +5,22 @@ import promisifyEvent from 'promisify-event'; import Promise from 'pinkie'; import Mustache from 'mustache'; import debugLogger from '../notifications/debug-logger'; -import SessionController from './session-controller'; import TestRunDebugLog from './debug-log'; import TestRunErrorFormattableAdapter from '../errors/test-run/formattable-adapter'; import TestCafeErrorList from '../errors/error-list'; -import { executeJsExpression } from './execute-js-expression'; import { PageLoadError, RoleSwitchInRoleInitializerError } from '../errors/test-run/'; -import BrowserManipulationQueue from './browser-manipulation-queue'; import PHASE from './phase'; import CLIENT_MESSAGES from './client-messages'; import COMMAND_TYPE from './commands/type'; -import AssertionExecutor from '../assertions/executor'; import delay from '../utils/delay'; import testRunMarker from './marker-symbol'; import testRunTracker from '../api/test-run-tracker'; import ROLE_PHASE from '../role/phase'; -import TestRunBookmark from './bookmark'; -import ClientFunctionBuilder from '../client-functions/client-function-builder'; import ReporterPluginHost from '../reporter/plugin-host'; import BrowserConsoleMessages from './browser-console-messages'; import { UNSTABLE_NETWORK_MODE_HEADER } from '../browser/connection/unstable-network-mode'; import WARNING_MESSAGE from '../notifications/warning-message'; -import { TakeScreenshotOnFailCommand } from './commands/browser-manipulation'; -import { SetNativeDialogHandlerCommand, SetTestSpeedCommand, SetPageLoadTimeoutCommand } from './commands/actions'; - - -import { - TestDoneCommand, - ShowAssertionRetriesStatusCommand, - HideAssertionRetriesStatusCommand, - SetBreakpointCommand, - BackupStoragesCommand -} from './commands/service'; - import { isCommandRejectableByPageError, isBrowserManipulationCommand, @@ -48,6 +30,18 @@ import { isExecutableOnClientCommand } from './commands/utils'; +const lazyRequire = require('import-lazy')(require); +const SessionController = lazyRequire('./session-controller'); +const ClientFunctionBuilder = lazyRequire('../client-functions/client-function-builder'); +const executeJsExpression = lazyRequire('./execute-js-expression'); +const BrowserManipulationQueue = lazyRequire('./browser-manipulation-queue'); +const TestRunBookmark = lazyRequire('./bookmark'); +const AssertionExecutor = lazyRequire('../assertions/executor'); +const actionCommands = lazyRequire('./commands/actions'); +const browserManipulationCommands = lazyRequire('./commands/browser-manipulation'); +const serviceCommands = lazyRequire('./commands/service'); + + const TEST_RUN_TEMPLATE = read('../client/test-run/index.js.mustache'); const IFRAME_TEST_RUN_TEMPLATE = read('../client/test-run/iframe.js.mustache'); const TEST_DONE_CONFIRMATION_RESPONSE = 'test-done-confirmation'; @@ -248,7 +242,7 @@ export default class TestRun extends EventEmitter { let screenshotPath = null; if (this.opts.takeScreenshotsOnFails) - screenshotPath = await this.executeCommand(new TakeScreenshotOnFailCommand()); + screenshotPath = await this.executeCommand(new browserManipulationCommands.TakeScreenshotOnFailCommand()); this.addError(err, screenshotPath); return false; @@ -299,7 +293,7 @@ export default class TestRun extends EventEmitter { if (this.errs.length && this.debugOnFail) await this._enqueueSetBreakpointCommand(null, this.debugReporterPluginHost.formatError(this.errs[0])); - await this.executeCommand(new TestDoneCommand()); + await this.executeCommand(new serviceCommands.TestDoneCommand()); this._addPendingPageErrorIfAny(); @@ -374,7 +368,7 @@ export default class TestRun extends EventEmitter { debugLogger.showBreakpoint(this.session.id, this.browserConnection.userAgent, callsite, error); - this.debugging = await this.executeCommand(new SetBreakpointCommand(!!error), callsite); + this.debugging = await this.executeCommand(new serviceCommands.SetBreakpointCommand(!!error), callsite); } _removeAllNonServiceTasks () { @@ -498,8 +492,8 @@ export default class TestRun extends EventEmitter { const assertionTimeout = command.options.timeout === void 0 ? this.opts.assertionTimeout : command.options.timeout; const executor = new AssertionExecutor(command, assertionTimeout, callsite); - executor.once('start-assertion-retries', timeout => this.executeCommand(new ShowAssertionRetriesStatusCommand(timeout))); - executor.once('end-assertion-retries', success => this.executeCommand(new HideAssertionRetriesStatusCommand(success))); + executor.once('start-assertion-retries', timeout => this.executeCommand(new serviceCommands.ShowAssertionRetriesStatusCommand(timeout))); + executor.once('end-assertion-retries', success => this.executeCommand(new serviceCommands.HideAssertionRetriesStatusCommand(success))); return executor.run(); } @@ -598,7 +592,7 @@ export default class TestRun extends EventEmitter { async getStateSnapshot () { const state = this.session.getStateSnapshot(); - state.storages = await this.executeCommand(new BackupStoragesCommand()); + state.storages = await this.executeCommand(new serviceCommands.BackupStoragesCommand()); return state; } @@ -611,19 +605,19 @@ export default class TestRun extends EventEmitter { this.session.useStateSnapshot(null); if (this.activeDialogHandler) { - const removeDialogHandlerCommand = new SetNativeDialogHandlerCommand({ dialogHandler: { fn: null } }); + const removeDialogHandlerCommand = new actionCommands.SetNativeDialogHandlerCommand({ dialogHandler: { fn: null } }); await this.executeCommand(removeDialogHandlerCommand); } if (this.speed !== this.opts.speed) { - const setSpeedCommand = new SetTestSpeedCommand({ speed: this.opts.speed }); + const setSpeedCommand = new actionCommands.SetTestSpeedCommand({ speed: this.opts.speed }); await this.executeCommand(setSpeedCommand); } if (this.pageLoadTimeout !== this.opts.pageLoadTimeout) { - const setPageLoadTimeoutCommand = new SetPageLoadTimeoutCommand({ duration: this.opts.pageLoadTimeout }); + const setPageLoadTimeoutCommand = new actionCommands.SetPageLoadTimeoutCommand({ duration: this.opts.pageLoadTimeout }); await this.executeCommand(setPageLoadTimeoutCommand); } diff --git a/src/testcafe.js b/src/testcafe.js index 6a156517..23a6cc02 100644 --- a/src/testcafe.js +++ b/src/testcafe.js @@ -1,30 +1,29 @@ import Promise from 'pinkie'; -import sourceMapSupport from 'source-map-support'; -import { readSync as read } from 'read-file-relative'; -import { Proxy } from 'testcafe-hammerhead'; -import { CLIENT_RUNNER_SCRIPT as LEGACY_RUNNER_SCRIPT } from 'testcafe-legacy-api'; -import BrowserConnectionGateway from './browser/connection/gateway'; -import BrowserConnection from './browser/connection'; -import browserProviderPool from './browser/provider/pool'; -import Runner from './runner'; -import { registerErrorHandlers } from './utils/handle-errors'; - -// Const -const UI_STYLE = read('./client/ui/styles.css'); -const UI_SPRITE = read('./client/ui/sprite.png', true); -const FAVICON = read('./client/ui/favicon.ico', true); + +const lazyRequire = require('import-lazy')(require); +const sourceMapSupport = lazyRequire('source-map-support'); +const hammerhead = lazyRequire('testcafe-hammerhead'); +const loadAssets = lazyRequire('./load-assets'); +const errorHandlers = lazyRequire('./utils/handle-errors'); +const BrowserConnectionGateway = lazyRequire('./browser/connection/gateway'); +const BrowserConnection = lazyRequire('./browser/connection'); +const browserProviderPool = lazyRequire('./browser/provider/pool'); +const Runner = lazyRequire('./runner'); + +// NOTE: CoffeeScript can't be loaded lazily, because it will break stack traces +require('coffeescript'); export default class TestCafe { constructor (hostname, port1, port2, options = {}) { this._setupSourceMapsSupport(); - registerErrorHandlers(); + errorHandlers.registerErrorHandlers(); if (options.retryTestPages) options.staticContentCaching = { maxAge: 3600, mustRevalidate: false }; this.closed = false; - this.proxy = new Proxy(hostname, port1, port2, options); + this.proxy = new hammerhead.Proxy(hostname, port1, port2, options); this.browserConnectionGateway = new BrowserConnectionGateway(this.proxy, { retryTestPages: options.retryTestPages }); this.runners = []; this.retryTestPages = options.retryTestPages; @@ -33,25 +32,24 @@ export default class TestCafe { } _registerAssets (developmentMode) { - const scriptNameSuffix = developmentMode ? 'js' : 'min.js'; - const coreScript = read(`./client/core/index.${scriptNameSuffix}`); - const driverScript = read(`./client/driver/index.${scriptNameSuffix}`); - const uiScript = read(`./client/ui/index.${scriptNameSuffix}`); - const automationScript = read(`./client/automation/index.${scriptNameSuffix}`); + const { favIcon, coreScript, driverScript, uiScript, + uiStyle, uiSprite, automationScript, legacyRunnerScript } = loadAssets(developmentMode); this.proxy.GET('/testcafe-core.js', { content: coreScript, contentType: 'application/x-javascript' }); this.proxy.GET('/testcafe-driver.js', { content: driverScript, contentType: 'application/x-javascript' }); + this.proxy.GET('/testcafe-legacy-runner.js', { - content: LEGACY_RUNNER_SCRIPT, + content: legacyRunnerScript, contentType: 'application/x-javascript' }); + this.proxy.GET('/testcafe-automation.js', { content: automationScript, contentType: 'application/x-javascript' }); this.proxy.GET('/testcafe-ui.js', { content: uiScript, contentType: 'application/x-javascript' }); - this.proxy.GET('/testcafe-ui-sprite.png', { content: UI_SPRITE, contentType: 'image/png' }); - this.proxy.GET('/favicon.ico', { content: FAVICON, contentType: 'image/x-icon' }); + this.proxy.GET('/testcafe-ui-sprite.png', { content: uiSprite, contentType: 'image/png' }); + this.proxy.GET('/favicon.ico', { content: favIcon, contentType: 'image/x-icon' }); this.proxy.GET('/testcafe-ui-styles.css', { - content: UI_STYLE, + content: uiStyle, contentType: 'text/css', isShadowUIStylesheet: true }); diff --git a/test/server/create-testcafe-test.js b/test/server/create-testcafe-test.js index e773051a..73fffd30 100644 --- a/test/server/create-testcafe-test.js +++ b/test/server/create-testcafe-test.js @@ -88,7 +88,7 @@ describe('TestCafe factory function', function () { }); it('Should contain embedding utils and common runtime functions', function () { - expect(createTestCafe.embeddingUtils).to.be.an('object'); + expect(createTestCafe.embeddingUtils).to.be.ok; expect(createTestCafe.Role).eql(exportableLib.Role); expect(createTestCafe.ClientFunction).eql(exportableLib.ClientFunction); }); diff --git a/test/server/runner-test.js b/test/server/runner-test.js index 1bc3245c..f36c0e3a 100644 --- a/test/server/runner-test.js +++ b/test/server/runner-test.js @@ -404,7 +404,7 @@ describe('Runner', () => { }); describe('.run()', () => { - it('Should not create a new local browser connection if sources are empty', () => { + it('Should not create a new remote browser connection if sources are empty', () => { const origGenerateId = BrowserConnection._generateId; let connectionsCount = 0; @@ -415,7 +415,7 @@ describe('Runner', () => { }; return runner - .browsers(browserMock) + .browsers(connection) .reporter('list') .src([]) .run() From 6f8db5ec9be84aaca23ccb340fe352b2a7c993e6 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Fri, 9 Nov 2018 16:49:49 +0300 Subject: [PATCH 178/184] Wait until outStream is finished (closes #2502) (#2828) --- package.json | 1 + src/reporter/index.js | 21 +++++++++++ src/runner/index.js | 44 ++++++++++++++++------- test/functional/fixtures/reporter/test.js | 40 ++++++++++++++++++++- test/functional/utils/stream.js | 31 +++++++++++++--- 5 files changed, 118 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index a6faab1c..63dfa13d 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "indent-string": "^1.2.2", "is-ci": "^1.0.10", "is-glob": "^2.0.1", + "is-stream": "^1.1.0", "lodash": "^4.17.10", "log-update-async-hook": "^2.0.2", "make-dir": "^1.3.0", diff --git a/src/reporter/index.js b/src/reporter/index.js index efa4bba5..45a98550 100644 --- a/src/reporter/index.js +++ b/src/reporter/index.js @@ -1,15 +1,19 @@ +import Promise from 'pinkie'; import { find, sortBy } from 'lodash'; +import { writable as isWritableStream } from 'is-stream'; import ReporterPluginHost from './plugin-host'; export default class Reporter { constructor (plugin, task, outStream) { this.plugin = new ReporterPluginHost(plugin, outStream); + this.disposed = false; this.passed = 0; this.skipped = task.tests.filter(test => test.skip).length; this.testCount = task.tests.length - this.skipped; this.reportQueue = Reporter._createReportQueue(task); this.stopOnFirstFail = task.opts.stopOnFirstFail; + this.outStream = outStream; this._assignTaskEventHandlers(task); } @@ -130,4 +134,21 @@ export default class Reporter { this.plugin.reportTaskDone(endTime, this.passed, task.warningLog.messages); }); } + + async dispose () { + if (this.disposed) + return; + + this.disposed = true; + + if (!isWritableStream(this.outStream)) + return; + + this.outStream.end(); + + await new Promise(resolve => { + this.outStream.once('finish', resolve); + this.outStream.once('error', resolve); + }); + } } diff --git a/src/runner/index.js b/src/runner/index.js index c6348152..5a278f54 100644 --- a/src/runner/index.js +++ b/src/runner/index.js @@ -1,4 +1,5 @@ import { resolve as resolvePath } from 'path'; +import debug from 'debug'; import Promise from 'pinkie'; import promisifyEvent from 'promisify-event'; import mapReverse from 'map-reverse'; @@ -14,10 +15,13 @@ import renderForbiddenCharsList from '../errors/render-forbidden-chars-list'; import checkFilePath from '../utils/check-file-path'; import { addRunningTest, removeRunningTest, startHandlingTestErrors, stopHandlingTestErrors } from '../utils/handle-errors'; + const DEFAULT_SELECTOR_TIMEOUT = 10000; const DEFAULT_ASSERTION_TIMEOUT = 3000; const DEFAULT_PAGE_LOAD_TIMEOUT = 3000; +const DEBUG_LOGGER = debug('testcafe:runner'); + export default class Runner extends EventEmitter { constructor (proxy, browserConnectionGateway, options = {}) { super(); @@ -41,18 +45,32 @@ export default class Runner extends EventEmitter { }; } - static async _disposeTaskAndRelatedAssets (task, browserSet, testedApp) { + + static _disposeBrowserSet (browserSet) { + return browserSet.dispose().catch(e => DEBUG_LOGGER(e)); + } + + static _disposeReporters (reporters) { + return Promise.all(reporters.map(reporter => reporter.dispose().catch(e => DEBUG_LOGGER(e)))); + } + + static _disposeTestedApp (testedApp) { + return testedApp ? testedApp.kill().catch(e => DEBUG_LOGGER(e)) : Promise.resolve(); + } + + static async _disposeTaskAndRelatedAssets (task, browserSet, reporters, testedApp) { task.abort(); task.removeAllListeners(); - await Runner._disposeBrowserSetAndTestedApp(browserSet, testedApp); + await Runner._disposeAssets(browserSet, reporters, testedApp); } - static async _disposeBrowserSetAndTestedApp (browserSet, testedApp) { - await browserSet.dispose(); - - if (testedApp) - await testedApp.kill(); + static _disposeAssets (browserSet, reporters, testedApp) { + return Promise.all([ + Runner._disposeBrowserSet(browserSet), + Runner._disposeReporters(reporters), + Runner._disposeTestedApp(testedApp) + ]); } _createCancelablePromise (taskPromise) { @@ -81,7 +99,7 @@ export default class Runner extends EventEmitter { return failedTestCount; } - async _getTaskResult (task, browserSet, reporter, testedApp) { + async _getTaskResult (task, browserSet, reporters, testedApp) { task.on('browser-job-done', job => browserSet.releaseConnection(job.browserConnection)); const promises = [ @@ -96,21 +114,21 @@ export default class Runner extends EventEmitter { await Promise.race(promises); } catch (err) { - await Runner._disposeTaskAndRelatedAssets(task, browserSet, testedApp); + await Runner._disposeTaskAndRelatedAssets(task, browserSet, reporters, testedApp); throw err; } - await Runner._disposeBrowserSetAndTestedApp(browserSet, testedApp); + await Runner._disposeAssets(browserSet, reporters, testedApp); - return this._getFailedTestCount(task, reporter); + return this._getFailedTestCount(task, reporters[0]); } _runTask (reporterPlugins, browserSet, tests, testedApp) { let completed = false; const task = new Task(tests, browserSet.browserConnectionGroups, this.proxy, this.opts); const reporters = reporterPlugins.map(reporter => new Reporter(reporter.plugin, task, reporter.outStream)); - const completionPromise = this._getTaskResult(task, browserSet, reporters[0], testedApp); + const completionPromise = this._getTaskResult(task, browserSet, reporters, testedApp); task.once('start', startHandlingTestErrors); @@ -131,7 +149,7 @@ export default class Runner extends EventEmitter { const cancelTask = async () => { if (!completed) - await Runner._disposeTaskAndRelatedAssets(task, browserSet, testedApp); + await Runner._disposeTaskAndRelatedAssets(task, browserSet, reporters, testedApp); }; return { completionPromise, cancelTask }; diff --git a/test/functional/fixtures/reporter/test.js b/test/functional/fixtures/reporter/test.js index 1f8276b4..69fce053 100644 --- a/test/functional/fixtures/reporter/test.js +++ b/test/functional/fixtures/reporter/test.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const { createTestStream } = require('../../utils/stream'); +const { createTestStream, createAsyncTestStream } = require('../../utils/stream'); describe('Reporter', () => { it('Should support several different reporters for a test run', function () { @@ -28,4 +28,42 @@ describe('Reporter', () => { expect(stream2.data).to.contains('Simple test'); }); }); + + it('Should wait until reporter stream is finished (GH-2502)', function () { + const stream = createAsyncTestStream(); + + const runOpts = { + only: ['chrome'], + reporters: [ + { + reporter: 'json', + outStream: stream + } + ] + }; + + return runTests('testcafe-fixtures/index-test.js', 'Simple test', runOpts) + .then(() => { + expect(stream.finalCalled).to.be.ok; + }); + }); + + it('Should wait until reporter stream failed to finish (GH-2502)', function () { + const stream = createAsyncTestStream({ shouldFail: true }); + + const runOpts = { + only: ['chrome'], + reporters: [ + { + reporter: 'json', + outStream: stream + } + ] + }; + + return runTests('testcafe-fixtures/index-test.js', 'Simple test', runOpts) + .then(() => { + expect(stream.finalCalled).to.be.ok; + }); + }); }); diff --git a/test/functional/utils/stream.js b/test/functional/utils/stream.js index 8416bf0d..61e41e2c 100644 --- a/test/functional/utils/stream.js +++ b/test/functional/utils/stream.js @@ -1,15 +1,36 @@ +const { Writable: WritableStream } = require('stream'); + + +const ASYNC_REPORTER_FINALIZING_TIMEOUT = 2000; + module.exports.createTestStream = () => { - const stream = { - data: '', - write: function (val) { + return { + data: '', + + write (val) { this.data += val; }, - end: function (val) { + end (val) { this.data += val; } }; +}; - return stream; + +module.exports.createAsyncTestStream = ({ shouldFail } = {}) => { + return new WritableStream({ + write (chunk, enc, cb) { + cb(); + }, + + final (cb) { + setTimeout(() => { + this.finalCalled = true; + + cb(shouldFail ? new Error('Stream failed') : null); + }, ASYNC_REPORTER_FINALIZING_TIMEOUT); + } + }); }; module.exports.createNullStream = () => { From 8054e2e67719bd224004d0e793edfe874bac7543 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Fri, 9 Nov 2018 18:57:27 +0300 Subject: [PATCH 179/184] Refresh node_modules when publishing; Bump version (v0.23.2-alpha.1) (#3101) --- .publishrc | 2 +- package.json | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.publishrc b/.publishrc index 5727c783..2414a453 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "latest", + "publishTag": "alpha", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index 63dfa13d..23e86642 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.23.1", + "version": "0.23.2-alpha.1", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" @@ -50,7 +50,7 @@ ], "scripts": { "test": "gulp travis", - "publish-please": "publish-please", + "publish-please": "del-cli package-lock.json node_modules && npm i && publish-please", "prepublish": "publish-please guard" }, "dependencies": { @@ -136,6 +136,7 @@ "chai-string": "^1.5.0", "connect": "^3.4.0", "cross-spawn": "^4.0.0", + "del-cli": "^1.1.0", "dom-walk": "^0.1.1", "eslint-plugin-hammerhead": "0.1.10", "express": "^4.13.3", From e9b00fb3ef390218efe6e1f7573601e547bd816f Mon Sep 17 00:00:00 2001 From: Vasily Strelyaev Date: Mon, 12 Nov 2018 15:17:25 +0300 Subject: [PATCH 180/184] Fix button names in the Handling Native Dialogs topic --- docs/articles/documentation/test-api/handling-native-dialogs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/documentation/test-api/handling-native-dialogs.md b/docs/articles/documentation/test-api/handling-native-dialogs.md index 74886d09..78d57b1c 100644 --- a/docs/articles/documentation/test-api/handling-native-dialogs.md +++ b/docs/articles/documentation/test-api/handling-native-dialogs.md @@ -62,7 +62,7 @@ Dialog Type | Return Value | Defaul ------------ | -------------------------------------------------------- | -------------- alert | Ignored | 'OK' button. beforeunload | Ignored | 'Leave' button. There is no way to emulate 'Stay' programmatically. -confirm | `true` to answer 'Yes'; `false` to answer 'No'. | 'No' button. +confirm | `true` to answer 'OK'; `false` to answer 'Cancel'. | 'Cancel' button. prompt | A string that contains text to be typed into the prompt. | 'Cancel' button. The following example demonstrates how to handle an alert dialog. From c75685e5c22270c5a87880694edcd31fe9a0ebe5 Mon Sep 17 00:00:00 2001 From: AlexKamaev Date: Mon, 12 Nov 2018 17:07:10 +0300 Subject: [PATCH 181/184] add docker-test task (closes #3026) (#3081) --- .dockerignore | 8 ++++---- Gulpfile.js | 27 ++++++++++++++++++++++++--- docker/Dockerfile | 16 ++++++++++------ docker/testcafe-docker.sh | 2 +- test/docker/Dockerfile | 8 ++++++++ 5 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 test/docker/Dockerfile diff --git a/.dockerignore b/.dockerignore index aed076dc..93288afc 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,6 @@ * -!bin !docker -!lib -!ts-defs -!package.json +!test +!Gulpfile.js +!.publishrc +!*.tgz \ No newline at end of file diff --git a/Gulpfile.js b/Gulpfile.js index 83dffe00..366ff006 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -35,6 +35,7 @@ const listBrowsers = require('testcafe-browser-tools').getInstallations; const npmAuditor = require('npm-auditor'); const checkLicenses = require('./test/dependency-licenses-checker'); const sourcemaps = require('gulp-sourcemaps'); +const packageInfo = require('./package'); gulpStep.install(); @@ -739,6 +740,8 @@ function startDocker () { } gulp.task('docker-build', done => { + childProcess.execSync('npm pack', { env: process.env }).toString(); + if (!process.env['DOCKER_HOST']) { try { startDocker(); @@ -749,8 +752,9 @@ gulp.task('docker-build', done => { } } - const imageId = childProcess - .execSync('docker build -q -t testcafe -f docker/Dockerfile .', { env: process.env }) + const packageId = `${packageInfo.name}-${packageInfo.version}.tgz`; + const command = `docker build --no-cache --build-arg packageId=${packageId} -q -t testcafe -f docker/Dockerfile .`; + const imageId = childProcess.execSync(command, { env: process.env }) .toString() .replace(/\n/g, ''); @@ -762,12 +766,29 @@ gulp.task('docker-build', done => { done(); }); +gulp.task('docker-test', done => { + if (!process.env['DOCKER_HOST']) { + try { + startDocker(); + } + catch (e) { + throw new Error('Unable to initialize Docker environment. Use Docker terminal to run this task.\n' + + e.stack); + } + } + + childProcess.spawnSync(`docker build --build-arg tag=${PUBLISH_TAG} -q -t docker-server-tests -f test/docker/Dockerfile .`, + { stdio: 'inherit', env: process.env, shell: true }); + + done(); +}); + gulp.step('docker-publish-run', done => { childProcess.execSync('docker push testcafe/testcafe:' + PUBLISH_TAG, { stdio: 'inherit', env: process.env }); done(); }); -gulp.task('docker-publish', gulp.series('docker-build', 'docker-publish-run')); +gulp.task('docker-publish', gulp.series('docker-build', 'docker-test', 'docker-publish-run')); gulp.task('travis', process.env.GULP_TASK ? gulp.series(process.env.GULP_TASK) : () => {}); diff --git a/docker/Dockerfile b/docker/Dockerfile index 92b9632c..b7fba364 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,16 +1,20 @@ FROM alpine:edge +ARG packageId -RUN apk --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ add \ - nodejs nodejs-npm chromium firefox xwininfo xvfb dbus eudev ttf-freefont fluxbox +COPY ${packageId} /opt/testcafe/${packageId} +COPY docker/testcafe-docker.sh /opt/testcafe/docker/testcafe-docker.sh -COPY . /opt/testcafe +RUN apk --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ upgrade +RUN apk --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ add \ + nodejs nodejs-npm chromium firefox xwininfo xvfb dbus eudev ttf-freefont fluxbox procps -RUN cd /opt/testcafe; \ - npm install --production && \ +RUN npm install -g /opt/testcafe/${packageId} && \ npm cache clean --force && \ rm -rf /tmp/* && \ chmod +x /opt/testcafe/docker/testcafe-docker.sh && \ - adduser -D user + adduser -D user && \ + rm /opt/testcafe/${packageId} + USER user EXPOSE 1337 1338 diff --git a/docker/testcafe-docker.sh b/docker/testcafe-docker.sh index 646b2460..d2141f7a 100644 --- a/docker/testcafe-docker.sh +++ b/docker/testcafe-docker.sh @@ -6,4 +6,4 @@ dbus-daemon --session --fork Xvfb :1 -screen 0 "${XVFB_SCREEN_WIDTH}x${XVFB_SCREEN_HEIGHT}x24" >/dev/null 2>&1 & export DISPLAY=:1.0 fluxbox >/dev/null 2>&1 & -node /opt/testcafe/bin/testcafe.js --ports 1337,1338 "$@" +node /usr/lib/node_modules/testcafe/bin/testcafe.js --ports 1337,1338 "$@" diff --git a/test/docker/Dockerfile b/test/docker/Dockerfile new file mode 100644 index 00000000..d3fc0950 --- /dev/null +++ b/test/docker/Dockerfile @@ -0,0 +1,8 @@ +ARG tag +FROM testcafe/testcafe:$tag + +USER root +COPY . /usr/lib/node_modules/testcafe +RUN cd /usr/lib/node_modules/testcafe && npm install --only=dev && \ + node node_modules/gulp/bin/gulp.js --steps-as-tasks --gulpfile Gulpfile.js test-server-run +USER user From 08290c6185b3cecb2af7bdaedd8b8d0eef1c3795 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Mon, 12 Nov 2018 19:33:30 +0300 Subject: [PATCH 182/184] Update changelog (v0.23.2) (#3107) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34a82ea9..a028da92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## v0.23.2 (2018-11-12) + +### Bug Fixes + +* TestCafe no longer posts internal messages to the browser console ([#3099](https://github.com/DevExpress/testcafe/issues/3099)) +* The TestCafe process no longer terminates before the report is written to a file ([#2502](https://github.com/DevExpress/testcafe/issues/2502)) + ## v0.23.1 (2018-11-7) ### Enhancements From 591ed4c52a3df19b23aba843f77d252bae4017c3 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Mon, 12 Nov 2018 19:33:44 +0300 Subject: [PATCH 183/184] Bump version (v0.23.2) (#3106) --- .publishrc | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.publishrc b/.publishrc index 2414a453..5727c783 100644 --- a/.publishrc +++ b/.publishrc @@ -8,7 +8,7 @@ "gitTag": true }, "confirm": true, - "publishTag": "alpha", + "publishTag": "latest", "prePublishScript": "gulp test-server", "postPublishScript": "gulp docker-publish" } diff --git a/package.json b/package.json index 23e86642..15ada01f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "testcafe", "description": "Automated browser testing for the modern web development stack.", "license": "MIT", - "version": "0.23.2-alpha.1", + "version": "0.23.2", "author": { "name": "Developer Express Inc.", "url": "https://www.devexpress.com/" From 03bc936d82c53520828ae20b4725cf68008a5e04 Mon Sep 17 00:00:00 2001 From: Will O'Brien Date: Fri, 7 Dec 2018 10:20:50 -0500 Subject: [PATCH 184/184] with build --- .gitignore | 1 - lib/api/exportable-lib/index.js | 69 + lib/api/request-hooks/assert-type.js | 12 + lib/api/request-hooks/hook.js | 51 + lib/api/request-hooks/request-logger.js | 162 + lib/api/request-hooks/request-mock.js | 74 + lib/api/structure/fixture.js | 103 + lib/api/structure/test-file.js | 27 + lib/api/structure/test.js | 83 + lib/api/structure/testing-unit.js | 117 + lib/api/test-controller/assertion.js | 110 + lib/api/test-controller/index.js | 326 + lib/api/test-controller/proxy.js | 47 + lib/api/test-page-url.js | 59 + lib/api/test-run-tracker.js | 114 + lib/api/wrap-test-function.js | 61 + lib/assertions/executor.js | 105 + lib/assertions/get-fn.js | 63 + lib/browser/connection/command.js | 14 + lib/browser/connection/gateway.js | 189 + lib/browser/connection/index.js | 367 + lib/browser/connection/remotes-queue.js | 76 + lib/browser/connection/status.js | 9 + .../connection/unstable-network-mode.js | 5 + lib/browser/provider/built-in/chrome/cdp.js | 205 + .../provider/built-in/chrome/config.js | 141 + .../built-in/chrome/create-temp-profile.js | 75 + lib/browser/provider/built-in/chrome/index.js | 150 + .../provider/built-in/chrome/local-chrome.js | 57 + .../provider/built-in/chrome/runtime-info.js | 36 + .../provider/built-in/firefox/config.js | 55 + .../built-in/firefox/create-temp-profile.js | 58 + .../provider/built-in/firefox/index.js | 150 + .../built-in/firefox/local-firefox.js | 72 + .../firefox/marionette-client/commands.js | 13 + .../firefox/marionette-client/index.js | 268 + .../provider/built-in/firefox/runtime-info.js | 38 + lib/browser/provider/built-in/index.js | 41 + .../provider/built-in/locally-installed.js | 67 + lib/browser/provider/built-in/path.js | 82 + lib/browser/provider/built-in/remote.js | 90 + lib/browser/provider/index.js | 406 + lib/browser/provider/parse-provider-name.js | 26 + lib/browser/provider/plugin-host.js | 203 + lib/browser/provider/pool.js | 195 + .../provider/utils/argument-parsing.js | 99 + lib/browser/provider/utils/browser-starter.js | 64 + .../provider/utils/client-functions.js | 23 + .../get-maximized-headless-window-size.js | 20 + lib/cli/argument-parser.js | 315 + lib/cli/cli.js | 187 + lib/cli/index.js | 29 + lib/cli/log.js | 63 + lib/cli/parse-ssl-options.js | 59 + lib/cli/remotes-wizard.js | 82 + lib/cli/termination-handler.js | 55 + lib/client-functions/builder-symbol.js | 14 + .../client-function-builder.js | 192 + lib/client-functions/replicator.js | 83 + lib/client-functions/selectors/add-api.js | 745 ++ .../selectors/create-snapshot-methods.js | 17 + .../selectors/selector-attribute-filter.js | 30 + .../selectors/selector-builder.js | 223 + .../selectors/selector-text-filter.js | 61 + .../selectors/snapshot-properties.js | 14 + lib/client/automation/index.js | 8366 +++++++++++++++++ lib/client/automation/index.min.js | 1 + .../browser/idle-page/index.html.mustache | 33 + lib/client/browser/idle-page/index.js | 970 ++ lib/client/browser/idle-page/logo.svg | 86 + lib/client/browser/idle-page/styles.css | 73 + lib/client/core/index.js | 4277 +++++++++ lib/client/core/index.min.js | 1 + lib/client/driver/index.js | 5799 ++++++++++++ lib/client/driver/index.min.js | 1 + lib/client/test-run/iframe.js.mustache | 17 + lib/client/test-run/index.js.mustache | 46 + lib/client/ui/favicon.ico | Bin 0 -> 15086 bytes lib/client/ui/index.js | 2379 +++++ lib/client/ui/index.min.js | 1 + lib/client/ui/sprite.png | Bin 0 -> 20689 bytes lib/client/ui/styles.css | 577 ++ lib/compiler/compile-client-function.js | 149 + lib/compiler/index.js | 119 + lib/compiler/load-babel-libs.js | 34 + lib/compiler/test-file/api-based.js | 198 + lib/compiler/test-file/base.js | 44 + .../formats/coffeescript/compiler.js | 60 + .../formats/coffeescript/get-test-list.js | 45 + .../test-file/formats/es-next/compiler.js | 89 + .../formats/es-next/get-test-list.js | 204 + lib/compiler/test-file/formats/raw.js | 131 + .../test-file/formats/typescript/compiler.js | 124 + .../formats/typescript/get-test-list.js | 241 + .../test-file/test-file-parser-base.js | 289 + lib/embedding-utils.js | 79 + lib/errors/create-stack-filter.js | 43 + lib/errors/error-list.js | 32 + lib/errors/get-callsite.js | 46 + lib/errors/process-test-fn-error.js | 47 + lib/errors/render-forbidden-chars-list.js | 10 + lib/errors/runtime/index.js | 87 + lib/errors/runtime/message.js | 47 + lib/errors/runtime/type-assertions.js | 132 + lib/errors/stack-cleaning-hook.js | 67 + lib/errors/test-run/formattable-adapter.js | 90 + lib/errors/test-run/index.js | 583 ++ lib/errors/test-run/templates.js | 341 + lib/errors/test-run/type.js | 71 + lib/index.js | 115 + lib/load-assets.js | 33 + lib/notifications/debug-logger.js | 118 + lib/notifications/deprecation-message.js | 38 + lib/notifications/warning-log.js | 25 + lib/notifications/warning-message.js | 19 + lib/reporter/index.js | 173 + lib/reporter/plugin-host.js | 172 + lib/role/index.js | 134 + lib/role/marker-symbol.js | 18 + lib/role/phase.js | 10 + lib/runner/bootstrapper.js | 270 + lib/runner/browser-job-result.js | 10 + lib/runner/browser-job.js | 162 + lib/runner/browser-set.js | 188 + lib/runner/fixture-hook-controller.js | 137 + lib/runner/index.js | 353 + lib/runner/task.js | 86 + lib/runner/test-run-controller.js | 202 + lib/runner/tested-app.js | 110 + lib/screenshots/capturer.js | 181 + lib/screenshots/constants.js | 12 + lib/screenshots/crop.js | 155 + lib/screenshots/generate-mark.js | 41 + lib/screenshots/index.js | 88 + lib/screenshots/path-pattern.js | 128 + lib/test-run/bookmark.js | 153 + lib/test-run/browser-console-messages.js | 70 + lib/test-run/browser-manipulation-queue.js | 155 + lib/test-run/client-messages.js | 10 + lib/test-run/commands/actions.js | 326 + lib/test-run/commands/assertion.js | 59 + lib/test-run/commands/base.js | 22 + lib/test-run/commands/browser-manipulation.js | 113 + lib/test-run/commands/from-object.js | 120 + lib/test-run/commands/observation.js | 64 + lib/test-run/commands/options.js | 224 + lib/test-run/commands/service.js | 50 + lib/test-run/commands/type.js | 52 + lib/test-run/commands/utils.js | 70 + lib/test-run/commands/validations/argument.js | 97 + .../commands/validations/factories.js | 52 + .../commands/validations/initializers.js | 64 + lib/test-run/debug-log.js | 41 + lib/test-run/execute-js-expression.js | 77 + lib/test-run/index.js | 840 ++ lib/test-run/marker-symbol.js | 18 + lib/test-run/phase.js | 17 + lib/test-run/session-controller.js | 131 + lib/testcafe.js | 126 + lib/utils/assignable.js | 55 + lib/utils/async-queue.js | 26 + lib/utils/check-file-path.js | 49 + lib/utils/check-url.js | 70 + lib/utils/correct-file-path.js | 30 + lib/utils/define-lazy-property.js | 25 + lib/utils/delay.js | 16 + lib/utils/delegated-api.js | 51 + lib/utils/escape-user-agent.js | 16 + lib/utils/get-common-path.js | 47 + lib/utils/get-viewport-width.js | 24 + lib/utils/handle-errors.js | 87 + lib/utils/handle-tag-args.js | 19 + lib/utils/http.js | 43 + lib/utils/limit-number.js | 13 + lib/utils/make-reg-exp.js | 12 + lib/utils/moment-loader.js | 30 + lib/utils/parse-file-list.js | 108 + lib/utils/process.js | 193 + lib/utils/promisified-functions.js | 29 + lib/utils/promisify.js | 20 + lib/utils/re-executable-promise.js | 57 + lib/utils/render-template.js | 13 + lib/utils/string.js | 82 + .../cleanup-process/commands.js | 10 + .../temp-directory/cleanup-process/index.js | 219 + .../temp-directory/cleanup-process/worker.js | 112 + lib/utils/temp-directory/index.js | 195 + lib/utils/temp-directory/lockfile.js | 78 + lib/utils/thennable.js | 8 + 189 files changed, 40741 insertions(+), 1 deletion(-) create mode 100644 lib/api/exportable-lib/index.js create mode 100644 lib/api/request-hooks/assert-type.js create mode 100644 lib/api/request-hooks/hook.js create mode 100644 lib/api/request-hooks/request-logger.js create mode 100644 lib/api/request-hooks/request-mock.js create mode 100644 lib/api/structure/fixture.js create mode 100644 lib/api/structure/test-file.js create mode 100644 lib/api/structure/test.js create mode 100644 lib/api/structure/testing-unit.js create mode 100644 lib/api/test-controller/assertion.js create mode 100644 lib/api/test-controller/index.js create mode 100644 lib/api/test-controller/proxy.js create mode 100644 lib/api/test-page-url.js create mode 100644 lib/api/test-run-tracker.js create mode 100644 lib/api/wrap-test-function.js create mode 100644 lib/assertions/executor.js create mode 100644 lib/assertions/get-fn.js create mode 100644 lib/browser/connection/command.js create mode 100644 lib/browser/connection/gateway.js create mode 100644 lib/browser/connection/index.js create mode 100644 lib/browser/connection/remotes-queue.js create mode 100644 lib/browser/connection/status.js create mode 100644 lib/browser/connection/unstable-network-mode.js create mode 100644 lib/browser/provider/built-in/chrome/cdp.js create mode 100644 lib/browser/provider/built-in/chrome/config.js create mode 100644 lib/browser/provider/built-in/chrome/create-temp-profile.js create mode 100644 lib/browser/provider/built-in/chrome/index.js create mode 100644 lib/browser/provider/built-in/chrome/local-chrome.js create mode 100644 lib/browser/provider/built-in/chrome/runtime-info.js create mode 100644 lib/browser/provider/built-in/firefox/config.js create mode 100644 lib/browser/provider/built-in/firefox/create-temp-profile.js create mode 100644 lib/browser/provider/built-in/firefox/index.js create mode 100644 lib/browser/provider/built-in/firefox/local-firefox.js create mode 100644 lib/browser/provider/built-in/firefox/marionette-client/commands.js create mode 100644 lib/browser/provider/built-in/firefox/marionette-client/index.js create mode 100644 lib/browser/provider/built-in/firefox/runtime-info.js create mode 100644 lib/browser/provider/built-in/index.js create mode 100644 lib/browser/provider/built-in/locally-installed.js create mode 100644 lib/browser/provider/built-in/path.js create mode 100644 lib/browser/provider/built-in/remote.js create mode 100644 lib/browser/provider/index.js create mode 100644 lib/browser/provider/parse-provider-name.js create mode 100644 lib/browser/provider/plugin-host.js create mode 100644 lib/browser/provider/pool.js create mode 100644 lib/browser/provider/utils/argument-parsing.js create mode 100644 lib/browser/provider/utils/browser-starter.js create mode 100644 lib/browser/provider/utils/client-functions.js create mode 100644 lib/browser/provider/utils/get-maximized-headless-window-size.js create mode 100644 lib/cli/argument-parser.js create mode 100644 lib/cli/cli.js create mode 100644 lib/cli/index.js create mode 100644 lib/cli/log.js create mode 100644 lib/cli/parse-ssl-options.js create mode 100644 lib/cli/remotes-wizard.js create mode 100644 lib/cli/termination-handler.js create mode 100644 lib/client-functions/builder-symbol.js create mode 100644 lib/client-functions/client-function-builder.js create mode 100644 lib/client-functions/replicator.js create mode 100644 lib/client-functions/selectors/add-api.js create mode 100644 lib/client-functions/selectors/create-snapshot-methods.js create mode 100644 lib/client-functions/selectors/selector-attribute-filter.js create mode 100644 lib/client-functions/selectors/selector-builder.js create mode 100644 lib/client-functions/selectors/selector-text-filter.js create mode 100644 lib/client-functions/selectors/snapshot-properties.js create mode 100644 lib/client/automation/index.js create mode 100644 lib/client/automation/index.min.js create mode 100644 lib/client/browser/idle-page/index.html.mustache create mode 100644 lib/client/browser/idle-page/index.js create mode 100644 lib/client/browser/idle-page/logo.svg create mode 100644 lib/client/browser/idle-page/styles.css create mode 100644 lib/client/core/index.js create mode 100644 lib/client/core/index.min.js create mode 100644 lib/client/driver/index.js create mode 100644 lib/client/driver/index.min.js create mode 100644 lib/client/test-run/iframe.js.mustache create mode 100644 lib/client/test-run/index.js.mustache create mode 100644 lib/client/ui/favicon.ico create mode 100644 lib/client/ui/index.js create mode 100644 lib/client/ui/index.min.js create mode 100644 lib/client/ui/sprite.png create mode 100644 lib/client/ui/styles.css create mode 100644 lib/compiler/compile-client-function.js create mode 100644 lib/compiler/index.js create mode 100644 lib/compiler/load-babel-libs.js create mode 100644 lib/compiler/test-file/api-based.js create mode 100644 lib/compiler/test-file/base.js create mode 100644 lib/compiler/test-file/formats/coffeescript/compiler.js create mode 100644 lib/compiler/test-file/formats/coffeescript/get-test-list.js create mode 100644 lib/compiler/test-file/formats/es-next/compiler.js create mode 100644 lib/compiler/test-file/formats/es-next/get-test-list.js create mode 100644 lib/compiler/test-file/formats/raw.js create mode 100644 lib/compiler/test-file/formats/typescript/compiler.js create mode 100644 lib/compiler/test-file/formats/typescript/get-test-list.js create mode 100644 lib/compiler/test-file/test-file-parser-base.js create mode 100644 lib/embedding-utils.js create mode 100644 lib/errors/create-stack-filter.js create mode 100644 lib/errors/error-list.js create mode 100644 lib/errors/get-callsite.js create mode 100644 lib/errors/process-test-fn-error.js create mode 100644 lib/errors/render-forbidden-chars-list.js create mode 100644 lib/errors/runtime/index.js create mode 100644 lib/errors/runtime/message.js create mode 100644 lib/errors/runtime/type-assertions.js create mode 100644 lib/errors/stack-cleaning-hook.js create mode 100644 lib/errors/test-run/formattable-adapter.js create mode 100644 lib/errors/test-run/index.js create mode 100644 lib/errors/test-run/templates.js create mode 100644 lib/errors/test-run/type.js create mode 100644 lib/index.js create mode 100644 lib/load-assets.js create mode 100644 lib/notifications/debug-logger.js create mode 100644 lib/notifications/deprecation-message.js create mode 100644 lib/notifications/warning-log.js create mode 100644 lib/notifications/warning-message.js create mode 100644 lib/reporter/index.js create mode 100644 lib/reporter/plugin-host.js create mode 100644 lib/role/index.js create mode 100644 lib/role/marker-symbol.js create mode 100644 lib/role/phase.js create mode 100644 lib/runner/bootstrapper.js create mode 100644 lib/runner/browser-job-result.js create mode 100644 lib/runner/browser-job.js create mode 100644 lib/runner/browser-set.js create mode 100644 lib/runner/fixture-hook-controller.js create mode 100644 lib/runner/index.js create mode 100644 lib/runner/task.js create mode 100644 lib/runner/test-run-controller.js create mode 100644 lib/runner/tested-app.js create mode 100644 lib/screenshots/capturer.js create mode 100644 lib/screenshots/constants.js create mode 100644 lib/screenshots/crop.js create mode 100644 lib/screenshots/generate-mark.js create mode 100644 lib/screenshots/index.js create mode 100644 lib/screenshots/path-pattern.js create mode 100644 lib/test-run/bookmark.js create mode 100644 lib/test-run/browser-console-messages.js create mode 100644 lib/test-run/browser-manipulation-queue.js create mode 100644 lib/test-run/client-messages.js create mode 100644 lib/test-run/commands/actions.js create mode 100644 lib/test-run/commands/assertion.js create mode 100644 lib/test-run/commands/base.js create mode 100644 lib/test-run/commands/browser-manipulation.js create mode 100644 lib/test-run/commands/from-object.js create mode 100644 lib/test-run/commands/observation.js create mode 100644 lib/test-run/commands/options.js create mode 100644 lib/test-run/commands/service.js create mode 100644 lib/test-run/commands/type.js create mode 100644 lib/test-run/commands/utils.js create mode 100644 lib/test-run/commands/validations/argument.js create mode 100644 lib/test-run/commands/validations/factories.js create mode 100644 lib/test-run/commands/validations/initializers.js create mode 100644 lib/test-run/debug-log.js create mode 100644 lib/test-run/execute-js-expression.js create mode 100644 lib/test-run/index.js create mode 100644 lib/test-run/marker-symbol.js create mode 100644 lib/test-run/phase.js create mode 100644 lib/test-run/session-controller.js create mode 100644 lib/testcafe.js create mode 100644 lib/utils/assignable.js create mode 100644 lib/utils/async-queue.js create mode 100644 lib/utils/check-file-path.js create mode 100644 lib/utils/check-url.js create mode 100644 lib/utils/correct-file-path.js create mode 100644 lib/utils/define-lazy-property.js create mode 100644 lib/utils/delay.js create mode 100644 lib/utils/delegated-api.js create mode 100644 lib/utils/escape-user-agent.js create mode 100644 lib/utils/get-common-path.js create mode 100644 lib/utils/get-viewport-width.js create mode 100644 lib/utils/handle-errors.js create mode 100644 lib/utils/handle-tag-args.js create mode 100644 lib/utils/http.js create mode 100644 lib/utils/limit-number.js create mode 100644 lib/utils/make-reg-exp.js create mode 100644 lib/utils/moment-loader.js create mode 100644 lib/utils/parse-file-list.js create mode 100644 lib/utils/process.js create mode 100644 lib/utils/promisified-functions.js create mode 100644 lib/utils/promisify.js create mode 100644 lib/utils/re-executable-promise.js create mode 100644 lib/utils/render-template.js create mode 100644 lib/utils/string.js create mode 100644 lib/utils/temp-directory/cleanup-process/commands.js create mode 100644 lib/utils/temp-directory/cleanup-process/index.js create mode 100644 lib/utils/temp-directory/cleanup-process/worker.js create mode 100644 lib/utils/temp-directory/index.js create mode 100644 lib/utils/temp-directory/lockfile.js create mode 100644 lib/utils/thennable.js diff --git a/.gitignore b/.gitignore index bedcb6f0..21703f57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ /node_modules .idea .vscode -/lib /site .sass-cache .publish diff --git a/lib/api/exportable-lib/index.js b/lib/api/exportable-lib/index.js new file mode 100644 index 00000000..3dcf42c3 --- /dev/null +++ b/lib/api/exportable-lib/index.js @@ -0,0 +1,69 @@ +'use strict'; + +exports.__esModule = true; +const lazyRequire = require('import-lazy')(require); +const ClientFunctionBuilder = lazyRequire('../../client-functions/client-function-builder'); +const SelectorBuilder = lazyRequire('../../client-functions/selectors/selector-builder'); +const role = lazyRequire('../../role'); +const createRequestLogger = lazyRequire('../request-hooks/request-logger'); +const createRequestMock = lazyRequire('../request-hooks/request-mock'); + +// NOTE: We can't use lazy require for RequestHook, because it will break base class detection for inherited classes +let RequestHook = null; + +// NOTE: We can't use lazy require for testControllerProxy, because it will break test controller detection +let testControllerProxy = null; + +function Role(loginPage, initFn, options) { + return role.createRole(loginPage, initFn, options); +} + +function RequestMock() { + return createRequestMock(); +} + +function RequestLogger(requestFilterRuleInit, logOptions) { + return createRequestLogger(requestFilterRuleInit, logOptions); +} + +function ClientFunction(fn, options) { + const builder = new ClientFunctionBuilder(fn, options, { instantiation: 'ClientFunction' }); + + return builder.getFunction(); +} + +function Selector(fn, options) { + const builder = new SelectorBuilder(fn, options, { instantiation: 'Selector' }); + + return builder.getFunction(); +} + +Object.defineProperty(Role, 'anonymous', { + get: () => role.createAnonymousRole +}); + +exports.default = { + Role, + + ClientFunction, + + Selector, + + RequestLogger, + + RequestMock, + + get RequestHook() { + if (!RequestHook) RequestHook = require('../request-hooks/hook'); + + return RequestHook; + }, + + get t() { + if (!testControllerProxy) testControllerProxy = require('../test-controller/proxy'); + + return testControllerProxy; + } +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvZXhwb3J0YWJsZS1saWIvaW5kZXguanMiXSwibmFtZXMiOlsibGF6eVJlcXVpcmUiLCJyZXF1aXJlIiwiQ2xpZW50RnVuY3Rpb25CdWlsZGVyIiwiU2VsZWN0b3JCdWlsZGVyIiwicm9sZSIsImNyZWF0ZVJlcXVlc3RMb2dnZXIiLCJjcmVhdGVSZXF1ZXN0TW9jayIsIlJlcXVlc3RIb29rIiwidGVzdENvbnRyb2xsZXJQcm94eSIsIlJvbGUiLCJsb2dpblBhZ2UiLCJpbml0Rm4iLCJvcHRpb25zIiwiY3JlYXRlUm9sZSIsIlJlcXVlc3RNb2NrIiwiUmVxdWVzdExvZ2dlciIsInJlcXVlc3RGaWx0ZXJSdWxlSW5pdCIsImxvZ09wdGlvbnMiLCJDbGllbnRGdW5jdGlvbiIsImZuIiwiYnVpbGRlciIsImluc3RhbnRpYXRpb24iLCJnZXRGdW5jdGlvbiIsIlNlbGVjdG9yIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJjcmVhdGVBbm9ueW1vdXNSb2xlIiwidCJdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsTUFBTUEsY0FBd0JDLFFBQVEsYUFBUixFQUF1QkEsT0FBdkIsQ0FBOUI7QUFDQSxNQUFNQyx3QkFBd0JGLFlBQVksZ0RBQVosQ0FBOUI7QUFDQSxNQUFNRyxrQkFBd0JILFlBQVksbURBQVosQ0FBOUI7QUFDQSxNQUFNSSxPQUF3QkosWUFBWSxZQUFaLENBQTlCO0FBQ0EsTUFBTUssc0JBQXdCTCxZQUFZLGlDQUFaLENBQTlCO0FBQ0EsTUFBTU0sb0JBQXdCTixZQUFZLCtCQUFaLENBQTlCOztBQUVBO0FBQ0EsSUFBSU8sY0FBYyxJQUFsQjs7QUFFQTtBQUNBLElBQUlDLHNCQUFzQixJQUExQjs7QUFFQSxTQUFTQyxJQUFULENBQWVDLFNBQWYsRUFBMEJDLE1BQTFCLEVBQWtDQyxPQUFsQyxFQUEyQztBQUN2QyxXQUFPUixLQUFLUyxVQUFMLENBQWdCSCxTQUFoQixFQUEyQkMsTUFBM0IsRUFBbUNDLE9BQW5DLENBQVA7QUFDSDs7QUFFRCxTQUFTRSxXQUFULEdBQXdCO0FBQ3BCLFdBQU9SLG1CQUFQO0FBQ0g7O0FBRUQsU0FBU1MsYUFBVCxDQUF3QkMscUJBQXhCLEVBQStDQyxVQUEvQyxFQUEyRDtBQUN2RCxXQUFPWixvQkFBb0JXLHFCQUFwQixFQUEyQ0MsVUFBM0MsQ0FBUDtBQUNIOztBQUVELFNBQVNDLGNBQVQsQ0FBeUJDLEVBQXpCLEVBQTZCUCxPQUE3QixFQUFzQztBQUNsQyxVQUFNUSxVQUFVLElBQUlsQixxQkFBSixDQUEwQmlCLEVBQTFCLEVBQThCUCxPQUE5QixFQUF1QyxFQUFFUyxlQUFlLGdCQUFqQixFQUF2QyxDQUFoQjs7QUFFQSxXQUFPRCxRQUFRRSxXQUFSLEVBQVA7QUFDSDs7QUFFRCxTQUFTQyxRQUFULENBQW1CSixFQUFuQixFQUF1QlAsT0FBdkIsRUFBZ0M7QUFDNUIsVUFBTVEsVUFBVSxJQUFJakIsZUFBSixDQUFvQmdCLEVBQXBCLEVBQXdCUCxPQUF4QixFQUFpQyxFQUFFUyxlQUFlLFVBQWpCLEVBQWpDLENBQWhCOztBQUVBLFdBQU9ELFFBQVFFLFdBQVIsRUFBUDtBQUNIOztBQUVERSxPQUFPQyxjQUFQLENBQXNCaEIsSUFBdEIsRUFBNEIsV0FBNUIsRUFBeUM7QUFDckNpQixTQUFLLE1BQU10QixLQUFLdUI7QUFEcUIsQ0FBekM7O2tCQUllO0FBQ1hsQixRQURXOztBQUdYUyxrQkFIVzs7QUFLWEssWUFMVzs7QUFPWFIsaUJBUFc7O0FBU1hELGVBVFc7O0FBV1gsUUFBSVAsV0FBSixHQUFtQjtBQUNmLFlBQUksQ0FBQ0EsV0FBTCxFQUNJQSxjQUFjTixRQUFRLHVCQUFSLENBQWQ7O0FBRUosZUFBT00sV0FBUDtBQUNILEtBaEJVOztBQWtCWCxRQUFJcUIsQ0FBSixHQUFTO0FBQ0wsWUFBSSxDQUFDcEIsbUJBQUwsRUFDSUEsc0JBQXNCUCxRQUFRLDBCQUFSLENBQXRCOztBQUVKLGVBQU9PLG1CQUFQO0FBQ0g7QUF2QlUsQyIsImZpbGUiOiJhcGkvZXhwb3J0YWJsZS1saWIvaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBsYXp5UmVxdWlyZSAgICAgICAgICAgPSByZXF1aXJlKCdpbXBvcnQtbGF6eScpKHJlcXVpcmUpO1xuY29uc3QgQ2xpZW50RnVuY3Rpb25CdWlsZGVyID0gbGF6eVJlcXVpcmUoJy4uLy4uL2NsaWVudC1mdW5jdGlvbnMvY2xpZW50LWZ1bmN0aW9uLWJ1aWxkZXInKTtcbmNvbnN0IFNlbGVjdG9yQnVpbGRlciAgICAgICA9IGxhenlSZXF1aXJlKCcuLi8uLi9jbGllbnQtZnVuY3Rpb25zL3NlbGVjdG9ycy9zZWxlY3Rvci1idWlsZGVyJyk7XG5jb25zdCByb2xlICAgICAgICAgICAgICAgICAgPSBsYXp5UmVxdWlyZSgnLi4vLi4vcm9sZScpO1xuY29uc3QgY3JlYXRlUmVxdWVzdExvZ2dlciAgID0gbGF6eVJlcXVpcmUoJy4uL3JlcXVlc3QtaG9va3MvcmVxdWVzdC1sb2dnZXInKTtcbmNvbnN0IGNyZWF0ZVJlcXVlc3RNb2NrICAgICA9IGxhenlSZXF1aXJlKCcuLi9yZXF1ZXN0LWhvb2tzL3JlcXVlc3QtbW9jaycpO1xuXG4vLyBOT1RFOiBXZSBjYW4ndCB1c2UgbGF6eSByZXF1aXJlIGZvciBSZXF1ZXN0SG9vaywgYmVjYXVzZSBpdCB3aWxsIGJyZWFrIGJhc2UgY2xhc3MgZGV0ZWN0aW9uIGZvciBpbmhlcml0ZWQgY2xhc3Nlc1xubGV0IFJlcXVlc3RIb29rID0gbnVsbDtcblxuLy8gTk9URTogV2UgY2FuJ3QgdXNlIGxhenkgcmVxdWlyZSBmb3IgdGVzdENvbnRyb2xsZXJQcm94eSwgYmVjYXVzZSBpdCB3aWxsIGJyZWFrIHRlc3QgY29udHJvbGxlciBkZXRlY3Rpb25cbmxldCB0ZXN0Q29udHJvbGxlclByb3h5ID0gbnVsbDtcblxuZnVuY3Rpb24gUm9sZSAobG9naW5QYWdlLCBpbml0Rm4sIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gcm9sZS5jcmVhdGVSb2xlKGxvZ2luUGFnZSwgaW5pdEZuLCBvcHRpb25zKTtcbn1cblxuZnVuY3Rpb24gUmVxdWVzdE1vY2sgKCkge1xuICAgIHJldHVybiBjcmVhdGVSZXF1ZXN0TW9jaygpO1xufVxuXG5mdW5jdGlvbiBSZXF1ZXN0TG9nZ2VyIChyZXF1ZXN0RmlsdGVyUnVsZUluaXQsIGxvZ09wdGlvbnMpIHtcbiAgICByZXR1cm4gY3JlYXRlUmVxdWVzdExvZ2dlcihyZXF1ZXN0RmlsdGVyUnVsZUluaXQsIGxvZ09wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBDbGllbnRGdW5jdGlvbiAoZm4sIG9wdGlvbnMpIHtcbiAgICBjb25zdCBidWlsZGVyID0gbmV3IENsaWVudEZ1bmN0aW9uQnVpbGRlcihmbiwgb3B0aW9ucywgeyBpbnN0YW50aWF0aW9uOiAnQ2xpZW50RnVuY3Rpb24nIH0pO1xuXG4gICAgcmV0dXJuIGJ1aWxkZXIuZ2V0RnVuY3Rpb24oKTtcbn1cblxuZnVuY3Rpb24gU2VsZWN0b3IgKGZuLCBvcHRpb25zKSB7XG4gICAgY29uc3QgYnVpbGRlciA9IG5ldyBTZWxlY3RvckJ1aWxkZXIoZm4sIG9wdGlvbnMsIHsgaW5zdGFudGlhdGlvbjogJ1NlbGVjdG9yJyB9KTtcblxuICAgIHJldHVybiBidWlsZGVyLmdldEZ1bmN0aW9uKCk7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSb2xlLCAnYW5vbnltb3VzJywge1xuICAgIGdldDogKCkgPT4gcm9sZS5jcmVhdGVBbm9ueW1vdXNSb2xlXG59KTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIFJvbGUsXG5cbiAgICBDbGllbnRGdW5jdGlvbixcblxuICAgIFNlbGVjdG9yLFxuXG4gICAgUmVxdWVzdExvZ2dlcixcblxuICAgIFJlcXVlc3RNb2NrLFxuXG4gICAgZ2V0IFJlcXVlc3RIb29rICgpIHtcbiAgICAgICAgaWYgKCFSZXF1ZXN0SG9vaylcbiAgICAgICAgICAgIFJlcXVlc3RIb29rID0gcmVxdWlyZSgnLi4vcmVxdWVzdC1ob29rcy9ob29rJyk7XG5cbiAgICAgICAgcmV0dXJuIFJlcXVlc3RIb29rO1xuICAgIH0sXG5cbiAgICBnZXQgdCAoKSB7XG4gICAgICAgIGlmICghdGVzdENvbnRyb2xsZXJQcm94eSlcbiAgICAgICAgICAgIHRlc3RDb250cm9sbGVyUHJveHkgPSByZXF1aXJlKCcuLi90ZXN0LWNvbnRyb2xsZXIvcHJveHknKTtcblxuICAgICAgICByZXR1cm4gdGVzdENvbnRyb2xsZXJQcm94eTtcbiAgICB9XG59O1xuIl19 diff --git a/lib/api/request-hooks/assert-type.js b/lib/api/request-hooks/assert-type.js new file mode 100644 index 00000000..740b166e --- /dev/null +++ b/lib/api/request-hooks/assert-type.js @@ -0,0 +1,12 @@ +'use strict'; + +exports.__esModule = true; +exports.default = assertRequestHookType; + +var _typeAssertions = require('../../errors/runtime/type-assertions'); + +function assertRequestHookType(hooks) { + hooks.forEach(hook => (0, _typeAssertions.assertType)(_typeAssertions.is.requestHookSubclass, 'requestHooks', `Hook`, hook)); +} +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvcmVxdWVzdC1ob29rcy9hc3NlcnQtdHlwZS5qcyJdLCJuYW1lcyI6WyJhc3NlcnRSZXF1ZXN0SG9va1R5cGUiLCJob29rcyIsImZvckVhY2giLCJob29rIiwiaXMiLCJyZXF1ZXN0SG9va1N1YmNsYXNzIl0sIm1hcHBpbmdzIjoiOzs7a0JBRXdCQSxxQjs7QUFGeEI7O0FBRWUsU0FBU0EscUJBQVQsQ0FBZ0NDLEtBQWhDLEVBQXVDO0FBQ2xEQSxVQUFNQyxPQUFOLENBQWNDLFFBQVEsZ0NBQVdDLG1CQUFHQyxtQkFBZCxFQUFtQyxjQUFuQyxFQUFvRCxNQUFwRCxFQUEyREYsSUFBM0QsQ0FBdEI7QUFDSCIsImZpbGUiOiJhcGkvcmVxdWVzdC1ob29rcy9hc3NlcnQtdHlwZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGFzc2VydFR5cGUsIGlzIH0gZnJvbSAnLi4vLi4vZXJyb3JzL3J1bnRpbWUvdHlwZS1hc3NlcnRpb25zJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gYXNzZXJ0UmVxdWVzdEhvb2tUeXBlIChob29rcykge1xuICAgIGhvb2tzLmZvckVhY2goaG9vayA9PiBhc3NlcnRUeXBlKGlzLnJlcXVlc3RIb29rU3ViY2xhc3MsICdyZXF1ZXN0SG9va3MnLCBgSG9va2AsIGhvb2spKTtcbn1cbiJdfQ== diff --git a/lib/api/request-hooks/hook.js b/lib/api/request-hooks/hook.js new file mode 100644 index 00000000..f2689ae8 --- /dev/null +++ b/lib/api/request-hooks/hook.js @@ -0,0 +1,51 @@ +'use strict'; + +exports.__esModule = true; + +var _testcafeHammerhead = require('testcafe-hammerhead'); + +var _lodash = require('lodash'); + +class RequestHook { + constructor(requestFilterRules, responseEventConfigureOpts) { + this.requestFilterRules = this._prepareRequestFilterRules(requestFilterRules); + this._instantiatedRequestFilterRules = []; + this.responseEventConfigureOpts = responseEventConfigureOpts; + + this.warningLog = null; + } + + _prepareRequestFilterRules(rules) { + if (rules) return (0, _lodash.castArray)(rules); + + return [_testcafeHammerhead.RequestFilterRule.ANY]; + } + + _instantiateRequestFilterRules() { + this._instantiatedRequestFilterRules = []; + + this.requestFilterRules.forEach(rule => { + const instantiatedRule = rule instanceof _testcafeHammerhead.RequestFilterRule ? rule : new _testcafeHammerhead.RequestFilterRule(rule); + + this._instantiatedRequestFilterRules.push(instantiatedRule); + }); + } + + onRequest() /*RequestEvent event*/{ + throw new Error('Not implemented'); + } + + _onConfigureResponse(event) { + if (!this.responseEventConfigureOpts) return; + + event.opts.includeHeaders = this.responseEventConfigureOpts.includeHeaders; + event.opts.includeBody = this.responseEventConfigureOpts.includeBody; + } + + onResponse() /*ResponseEvent event*/{ + throw new Error('Not implemented'); + } +} +exports.default = RequestHook; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvcmVxdWVzdC1ob29rcy9ob29rLmpzIl0sIm5hbWVzIjpbIlJlcXVlc3RIb29rIiwiY29uc3RydWN0b3IiLCJyZXF1ZXN0RmlsdGVyUnVsZXMiLCJyZXNwb25zZUV2ZW50Q29uZmlndXJlT3B0cyIsIl9wcmVwYXJlUmVxdWVzdEZpbHRlclJ1bGVzIiwiX2luc3RhbnRpYXRlZFJlcXVlc3RGaWx0ZXJSdWxlcyIsIndhcm5pbmdMb2ciLCJydWxlcyIsIlJlcXVlc3RGaWx0ZXJSdWxlIiwiQU5ZIiwiX2luc3RhbnRpYXRlUmVxdWVzdEZpbHRlclJ1bGVzIiwiZm9yRWFjaCIsInJ1bGUiLCJpbnN0YW50aWF0ZWRSdWxlIiwicHVzaCIsIm9uUmVxdWVzdCIsIkVycm9yIiwiX29uQ29uZmlndXJlUmVzcG9uc2UiLCJldmVudCIsIm9wdHMiLCJpbmNsdWRlSGVhZGVycyIsImluY2x1ZGVCb2R5Iiwib25SZXNwb25zZSJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBOztBQUNBOztBQUVlLE1BQU1BLFdBQU4sQ0FBa0I7QUFDN0JDLGdCQUFhQyxrQkFBYixFQUFpQ0MsMEJBQWpDLEVBQTZEO0FBQ3pELGFBQUtELGtCQUFMLEdBQXVDLEtBQUtFLDBCQUFMLENBQWdDRixrQkFBaEMsQ0FBdkM7QUFDQSxhQUFLRywrQkFBTCxHQUF1QyxFQUF2QztBQUNBLGFBQUtGLDBCQUFMLEdBQXVDQSwwQkFBdkM7O0FBRUEsYUFBS0csVUFBTCxHQUFrQixJQUFsQjtBQUNIOztBQUVERiwrQkFBNEJHLEtBQTVCLEVBQW1DO0FBQy9CLFlBQUlBLEtBQUosRUFDSSxPQUFPLHVCQUFVQSxLQUFWLENBQVA7O0FBRUosZUFBTyxDQUFDQyxzQ0FBa0JDLEdBQW5CLENBQVA7QUFDSDs7QUFFREMscUNBQWtDO0FBQzlCLGFBQUtMLCtCQUFMLEdBQXVDLEVBQXZDOztBQUVBLGFBQUtILGtCQUFMLENBQXdCUyxPQUF4QixDQUFnQ0MsUUFBUTtBQUNwQyxrQkFBTUMsbUJBQW1CRCxnQkFBZ0JKLHFDQUFoQixHQUFvQ0ksSUFBcEMsR0FBMkMsSUFBSUoscUNBQUosQ0FBc0JJLElBQXRCLENBQXBFOztBQUVBLGlCQUFLUCwrQkFBTCxDQUFxQ1MsSUFBckMsQ0FBMENELGdCQUExQztBQUNILFNBSkQ7QUFLSDs7QUFFREUsZ0JBQVcsc0JBQXdCO0FBQy9CLGNBQU0sSUFBSUMsS0FBSixDQUFVLGlCQUFWLENBQU47QUFDSDs7QUFFREMseUJBQXNCQyxLQUF0QixFQUE2QjtBQUN6QixZQUFJLENBQUMsS0FBS2YsMEJBQVYsRUFDSTs7QUFFSmUsY0FBTUMsSUFBTixDQUFXQyxjQUFYLEdBQTRCLEtBQUtqQiwwQkFBTCxDQUFnQ2lCLGNBQTVEO0FBQ0FGLGNBQU1DLElBQU4sQ0FBV0UsV0FBWCxHQUE0QixLQUFLbEIsMEJBQUwsQ0FBZ0NrQixXQUE1RDtBQUNIOztBQUVEQyxpQkFBWSx1QkFBeUI7QUFDakMsY0FBTSxJQUFJTixLQUFKLENBQVUsaUJBQVYsQ0FBTjtBQUNIO0FBeEM0QjtrQkFBWmhCLFciLCJmaWxlIjoiYXBpL3JlcXVlc3QtaG9va3MvaG9vay5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlcXVlc3RGaWx0ZXJSdWxlIH0gZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5pbXBvcnQgeyBjYXN0QXJyYXkgfSBmcm9tICdsb2Rhc2gnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZXF1ZXN0SG9vayB7XG4gICAgY29uc3RydWN0b3IgKHJlcXVlc3RGaWx0ZXJSdWxlcywgcmVzcG9uc2VFdmVudENvbmZpZ3VyZU9wdHMpIHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0RmlsdGVyUnVsZXMgICAgICAgICAgICAgID0gdGhpcy5fcHJlcGFyZVJlcXVlc3RGaWx0ZXJSdWxlcyhyZXF1ZXN0RmlsdGVyUnVsZXMpO1xuICAgICAgICB0aGlzLl9pbnN0YW50aWF0ZWRSZXF1ZXN0RmlsdGVyUnVsZXMgPSBbXTtcbiAgICAgICAgdGhpcy5yZXNwb25zZUV2ZW50Q29uZmlndXJlT3B0cyAgICAgID0gcmVzcG9uc2VFdmVudENvbmZpZ3VyZU9wdHM7XG5cbiAgICAgICAgdGhpcy53YXJuaW5nTG9nID0gbnVsbDtcbiAgICB9XG5cbiAgICBfcHJlcGFyZVJlcXVlc3RGaWx0ZXJSdWxlcyAocnVsZXMpIHtcbiAgICAgICAgaWYgKHJ1bGVzKVxuICAgICAgICAgICAgcmV0dXJuIGNhc3RBcnJheShydWxlcyk7XG5cbiAgICAgICAgcmV0dXJuIFtSZXF1ZXN0RmlsdGVyUnVsZS5BTlldO1xuICAgIH1cblxuICAgIF9pbnN0YW50aWF0ZVJlcXVlc3RGaWx0ZXJSdWxlcyAoKSB7XG4gICAgICAgIHRoaXMuX2luc3RhbnRpYXRlZFJlcXVlc3RGaWx0ZXJSdWxlcyA9IFtdO1xuXG4gICAgICAgIHRoaXMucmVxdWVzdEZpbHRlclJ1bGVzLmZvckVhY2gocnVsZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbnN0YW50aWF0ZWRSdWxlID0gcnVsZSBpbnN0YW5jZW9mIFJlcXVlc3RGaWx0ZXJSdWxlID8gcnVsZSA6IG5ldyBSZXF1ZXN0RmlsdGVyUnVsZShydWxlKTtcblxuICAgICAgICAgICAgdGhpcy5faW5zdGFudGlhdGVkUmVxdWVzdEZpbHRlclJ1bGVzLnB1c2goaW5zdGFudGlhdGVkUnVsZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uUmVxdWVzdCAoLypSZXF1ZXN0RXZlbnQgZXZlbnQqLykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIF9vbkNvbmZpZ3VyZVJlc3BvbnNlIChldmVudCkge1xuICAgICAgICBpZiAoIXRoaXMucmVzcG9uc2VFdmVudENvbmZpZ3VyZU9wdHMpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgZXZlbnQub3B0cy5pbmNsdWRlSGVhZGVycyA9IHRoaXMucmVzcG9uc2VFdmVudENvbmZpZ3VyZU9wdHMuaW5jbHVkZUhlYWRlcnM7XG4gICAgICAgIGV2ZW50Lm9wdHMuaW5jbHVkZUJvZHkgICAgPSB0aGlzLnJlc3BvbnNlRXZlbnRDb25maWd1cmVPcHRzLmluY2x1ZGVCb2R5O1xuICAgIH1cblxuICAgIG9uUmVzcG9uc2UgKC8qUmVzcG9uc2VFdmVudCBldmVudCovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxufVxuIl19 diff --git a/lib/api/request-hooks/request-logger.js b/lib/api/request-hooks/request-logger.js new file mode 100644 index 00000000..102b257a --- /dev/null +++ b/lib/api/request-hooks/request-logger.js @@ -0,0 +1,162 @@ +'use strict'; + +exports.__esModule = true; + +var _keys = require('babel-runtime/core-js/object/keys'); + +var _keys2 = _interopRequireDefault(_keys); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _values = require('babel-runtime/core-js/object/values'); + +var _values2 = _interopRequireDefault(_values); + +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + +exports.default = createRequestLogger; + +var _testcafeHammerhead = require('testcafe-hammerhead'); + +var _hook = require('./hook'); + +var _hook2 = _interopRequireDefault(_hook); + +var _useragent = require('useragent'); + +var _testRunTracker = require('../test-run-tracker'); + +var _testRunTracker2 = _interopRequireDefault(_testRunTracker); + +var _reExecutablePromise = require('../../utils/re-executable-promise'); + +var _reExecutablePromise2 = _interopRequireDefault(_reExecutablePromise); + +var _runtime = require('../../errors/runtime'); + +var _message = require('../../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DEFAULT_OPTIONS = { + logRequestHeaders: false, + logRequestBody: false, + stringifyRequestBody: false, + logResponseHeaders: false, + logResponseBody: false, + stringifyResponseBody: false +}; + +class RequestLoggerImplementation extends _hook2.default { + constructor(requestFilterRuleInit, options) { + options = (0, _assign2.default)({}, DEFAULT_OPTIONS, options); + RequestLoggerImplementation._assertLogOptions(options); + + const configureResponseEventOptions = new _testcafeHammerhead.ConfigureResponseEventOptions(options.logResponseHeaders, options.logResponseBody); + + super(requestFilterRuleInit, configureResponseEventOptions); + + this.options = options; + + this._internalRequests = {}; + } + + static _assertLogOptions(logOptions) { + if (!logOptions.logRequestBody && logOptions.stringifyRequestBody) throw new _runtime.APIError('RequestLogger', _message2.default.requestHookConfigureAPIError, 'RequestLogger', 'Cannot stringify the request body because it is not logged. Specify { logRequestBody: true } in log options.'); + + if (!logOptions.logResponseBody && logOptions.stringifyResponseBody) throw new _runtime.APIError('RequestLogger', _message2.default.requestHookConfigureAPIError, 'RequestLogger', 'Cannot stringify the response body because it is not logged. Specify { logResponseBody: true } in log options.'); + } + + onRequest(event) { + const userAgent = (0, _useragent.parse)(event._requestInfo.userAgent).toString(); + + const loggedReq = { + id: event._requestInfo.requestId, + testRunId: event._requestInfo.sessionId, + userAgent, + request: { + url: event._requestInfo.url, + method: event._requestInfo.method + } + }; + + if (this.options.logRequestHeaders) loggedReq.request.headers = (0, _assign2.default)({}, event._requestInfo.headers); + + if (this.options.logRequestBody) loggedReq.request.body = this.options.stringifyRequestBody ? event._requestInfo.body.toString() : event._requestInfo.body; + + this._internalRequests[loggedReq.id] = loggedReq; + } + + onResponse(event) { + const loggerReq = this._internalRequests[event.requestId]; + + // NOTE: If the 'clear' method is called during a long running request, + // we should not save a response part - request part has been already removed. + if (!loggerReq) return; + + loggerReq.response = {}; + loggerReq.response.statusCode = event.statusCode; + + if (this.options.logResponseHeaders) loggerReq.response.headers = (0, _assign2.default)({}, event.headers); + + if (this.options.logResponseBody) { + loggerReq.response.body = this.options.stringifyResponseBody && event.body ? event.body.toString() : event.body; + } + } + + _prepareInternalRequestInfo() { + const testRun = _testRunTracker2.default.resolveContextTestRun(); + let preparedRequests = (0, _values2.default)(this._internalRequests); + + if (testRun) preparedRequests = preparedRequests.filter(r => r.testRunId === testRun.id); + + return preparedRequests; + } + + _getCompletedRequests() { + return this._prepareInternalRequestInfo().filter(r => r.response); + } + + // API + contains(predicate) { + var _this = this; + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + return !!_this._getCompletedRequests().find(predicate); + })); + } + + count(predicate) { + var _this2 = this; + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + return _this2._getCompletedRequests().filter(predicate).length; + })); + } + + clear() { + const testRun = _testRunTracker2.default.resolveContextTestRun(); + + if (testRun) { + (0, _keys2.default)(this._internalRequests).forEach(id => { + if (this._internalRequests[id].testRunId === testRun.id) delete this._internalRequests[id]; + }); + } else this._internalRequests = {}; + } + + get requests() { + return this._prepareInternalRequestInfo(); + } +} + +function createRequestLogger(requestFilterRuleInit, logOptions) { + return new RequestLoggerImplementation(requestFilterRuleInit, logOptions); +} +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvcmVxdWVzdC1ob29rcy9yZXF1ZXN0LWxvZ2dlci5qcyJdLCJuYW1lcyI6WyJjcmVhdGVSZXF1ZXN0TG9nZ2VyIiwiREVGQVVMVF9PUFRJT05TIiwibG9nUmVxdWVzdEhlYWRlcnMiLCJsb2dSZXF1ZXN0Qm9keSIsInN0cmluZ2lmeVJlcXVlc3RCb2R5IiwibG9nUmVzcG9uc2VIZWFkZXJzIiwibG9nUmVzcG9uc2VCb2R5Iiwic3RyaW5naWZ5UmVzcG9uc2VCb2R5IiwiUmVxdWVzdExvZ2dlckltcGxlbWVudGF0aW9uIiwiUmVxdWVzdEhvb2siLCJjb25zdHJ1Y3RvciIsInJlcXVlc3RGaWx0ZXJSdWxlSW5pdCIsIm9wdGlvbnMiLCJfYXNzZXJ0TG9nT3B0aW9ucyIsImNvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zIiwiQ29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnMiLCJfaW50ZXJuYWxSZXF1ZXN0cyIsImxvZ09wdGlvbnMiLCJBUElFcnJvciIsIk1FU1NBR0UiLCJyZXF1ZXN0SG9va0NvbmZpZ3VyZUFQSUVycm9yIiwib25SZXF1ZXN0IiwiZXZlbnQiLCJ1c2VyQWdlbnQiLCJfcmVxdWVzdEluZm8iLCJ0b1N0cmluZyIsImxvZ2dlZFJlcSIsImlkIiwicmVxdWVzdElkIiwidGVzdFJ1bklkIiwic2Vzc2lvbklkIiwicmVxdWVzdCIsInVybCIsIm1ldGhvZCIsImhlYWRlcnMiLCJib2R5Iiwib25SZXNwb25zZSIsImxvZ2dlclJlcSIsInJlc3BvbnNlIiwic3RhdHVzQ29kZSIsIl9wcmVwYXJlSW50ZXJuYWxSZXF1ZXN0SW5mbyIsInRlc3RSdW4iLCJ0ZXN0UnVuVHJhY2tlciIsInJlc29sdmVDb250ZXh0VGVzdFJ1biIsInByZXBhcmVkUmVxdWVzdHMiLCJmaWx0ZXIiLCJyIiwiX2dldENvbXBsZXRlZFJlcXVlc3RzIiwiY29udGFpbnMiLCJwcmVkaWNhdGUiLCJSZUV4ZWN1dGFibGVQcm9taXNlIiwiZnJvbUZuIiwiZmluZCIsImNvdW50IiwibGVuZ3RoIiwiY2xlYXIiLCJmb3JFYWNoIiwicmVxdWVzdHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O2tCQStId0JBLG1COztBQS9IeEI7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLE1BQU1DLGtCQUFrQjtBQUNwQkMsdUJBQXVCLEtBREg7QUFFcEJDLG9CQUF1QixLQUZIO0FBR3BCQywwQkFBdUIsS0FISDtBQUlwQkMsd0JBQXVCLEtBSkg7QUFLcEJDLHFCQUF1QixLQUxIO0FBTXBCQywyQkFBdUI7QUFOSCxDQUF4Qjs7QUFTQSxNQUFNQywyQkFBTixTQUEwQ0MsY0FBMUMsQ0FBc0Q7QUFDbERDLGdCQUFhQyxxQkFBYixFQUFvQ0MsT0FBcEMsRUFBNkM7QUFDekNBLGtCQUFVLHNCQUFjLEVBQWQsRUFBa0JYLGVBQWxCLEVBQW1DVyxPQUFuQyxDQUFWO0FBQ0FKLG9DQUE0QkssaUJBQTVCLENBQThDRCxPQUE5Qzs7QUFFQSxjQUFNRSxnQ0FBZ0MsSUFBSUMsaURBQUosQ0FBa0NILFFBQVFQLGtCQUExQyxFQUE4RE8sUUFBUU4sZUFBdEUsQ0FBdEM7O0FBRUEsY0FBTUsscUJBQU4sRUFBNkJHLDZCQUE3Qjs7QUFFQSxhQUFLRixPQUFMLEdBQWVBLE9BQWY7O0FBRUEsYUFBS0ksaUJBQUwsR0FBeUIsRUFBekI7QUFDSDs7QUFFRCxXQUFPSCxpQkFBUCxDQUEwQkksVUFBMUIsRUFBc0M7QUFDbEMsWUFBSSxDQUFDQSxXQUFXZCxjQUFaLElBQThCYyxXQUFXYixvQkFBN0MsRUFDSSxNQUFNLElBQUljLGlCQUFKLENBQWEsZUFBYixFQUE4QkMsa0JBQVFDLDRCQUF0QyxFQUFvRSxlQUFwRSxFQUFxRiw4R0FBckYsQ0FBTjs7QUFFSixZQUFJLENBQUNILFdBQVdYLGVBQVosSUFBK0JXLFdBQVdWLHFCQUE5QyxFQUNJLE1BQU0sSUFBSVcsaUJBQUosQ0FBYSxlQUFiLEVBQThCQyxrQkFBUUMsNEJBQXRDLEVBQW9FLGVBQXBFLEVBQXFGLGdIQUFyRixDQUFOO0FBQ1A7O0FBRURDLGNBQVdDLEtBQVgsRUFBa0I7QUFDZCxjQUFNQyxZQUFZLHNCQUFlRCxNQUFNRSxZQUFOLENBQW1CRCxTQUFsQyxFQUE2Q0UsUUFBN0MsRUFBbEI7O0FBRUEsY0FBTUMsWUFBWTtBQUNkQyxnQkFBV0wsTUFBTUUsWUFBTixDQUFtQkksU0FEaEI7QUFFZEMsdUJBQVdQLE1BQU1FLFlBQU4sQ0FBbUJNLFNBRmhCO0FBR2RQLHFCQUhjO0FBSWRRLHFCQUFXO0FBQ1BDLHFCQUFRVixNQUFNRSxZQUFOLENBQW1CUSxHQURwQjtBQUVQQyx3QkFBUVgsTUFBTUUsWUFBTixDQUFtQlM7QUFGcEI7QUFKRyxTQUFsQjs7QUFVQSxZQUFJLEtBQUtyQixPQUFMLENBQWFWLGlCQUFqQixFQUNJd0IsVUFBVUssT0FBVixDQUFrQkcsT0FBbEIsR0FBNEIsc0JBQWMsRUFBZCxFQUFrQlosTUFBTUUsWUFBTixDQUFtQlUsT0FBckMsQ0FBNUI7O0FBRUosWUFBSSxLQUFLdEIsT0FBTCxDQUFhVCxjQUFqQixFQUNJdUIsVUFBVUssT0FBVixDQUFrQkksSUFBbEIsR0FBeUIsS0FBS3ZCLE9BQUwsQ0FBYVIsb0JBQWIsR0FBb0NrQixNQUFNRSxZQUFOLENBQW1CVyxJQUFuQixDQUF3QlYsUUFBeEIsRUFBcEMsR0FBeUVILE1BQU1FLFlBQU4sQ0FBbUJXLElBQXJIOztBQUVKLGFBQUtuQixpQkFBTCxDQUF1QlUsVUFBVUMsRUFBakMsSUFBdUNELFNBQXZDO0FBQ0g7O0FBRURVLGVBQVlkLEtBQVosRUFBbUI7QUFDZixjQUFNZSxZQUFZLEtBQUtyQixpQkFBTCxDQUF1Qk0sTUFBTU0sU0FBN0IsQ0FBbEI7O0FBRUE7QUFDQTtBQUNBLFlBQUksQ0FBQ1MsU0FBTCxFQUNJOztBQUVKQSxrQkFBVUMsUUFBVixHQUFnQyxFQUFoQztBQUNBRCxrQkFBVUMsUUFBVixDQUFtQkMsVUFBbkIsR0FBZ0NqQixNQUFNaUIsVUFBdEM7O0FBRUEsWUFBSSxLQUFLM0IsT0FBTCxDQUFhUCxrQkFBakIsRUFDSWdDLFVBQVVDLFFBQVYsQ0FBbUJKLE9BQW5CLEdBQTZCLHNCQUFjLEVBQWQsRUFBa0JaLE1BQU1ZLE9BQXhCLENBQTdCOztBQUVKLFlBQUksS0FBS3RCLE9BQUwsQ0FBYU4sZUFBakIsRUFBa0M7QUFDOUIrQixzQkFBVUMsUUFBVixDQUFtQkgsSUFBbkIsR0FBMEIsS0FBS3ZCLE9BQUwsQ0FBYUwscUJBQWIsSUFBc0NlLE1BQU1hLElBQTVDLEdBQ3BCYixNQUFNYSxJQUFOLENBQVdWLFFBQVgsRUFEb0IsR0FFcEJILE1BQU1hLElBRlo7QUFHSDtBQUNKOztBQUVESyxrQ0FBK0I7QUFDM0IsY0FBTUMsVUFBaUJDLHlCQUFlQyxxQkFBZixFQUF2QjtBQUNBLFlBQUlDLG1CQUFtQixzQkFBYyxLQUFLNUIsaUJBQW5CLENBQXZCOztBQUVBLFlBQUl5QixPQUFKLEVBQ0lHLG1CQUFtQkEsaUJBQWlCQyxNQUFqQixDQUF3QkMsS0FBS0EsRUFBRWpCLFNBQUYsS0FBZ0JZLFFBQVFkLEVBQXJELENBQW5COztBQUVKLGVBQU9pQixnQkFBUDtBQUNIOztBQUVERyw0QkFBeUI7QUFDckIsZUFBTyxLQUFLUCwyQkFBTCxHQUFtQ0ssTUFBbkMsQ0FBMENDLEtBQUtBLEVBQUVSLFFBQWpELENBQVA7QUFDSDs7QUFFRDtBQUNBVSxhQUFVQyxTQUFWLEVBQXFCO0FBQUE7O0FBQ2pCLGVBQU9DLDhCQUFvQkMsTUFBcEIsaUNBQTJCLGFBQVk7QUFDMUMsbUJBQU8sQ0FBQyxDQUFDLE1BQUtKLHFCQUFMLEdBQTZCSyxJQUE3QixDQUFrQ0gsU0FBbEMsQ0FBVDtBQUNILFNBRk0sRUFBUDtBQUdIOztBQUVESSxVQUFPSixTQUFQLEVBQWtCO0FBQUE7O0FBQ2QsZUFBT0MsOEJBQW9CQyxNQUFwQixpQ0FBMkIsYUFBWTtBQUMxQyxtQkFBTyxPQUFLSixxQkFBTCxHQUE2QkYsTUFBN0IsQ0FBb0NJLFNBQXBDLEVBQStDSyxNQUF0RDtBQUNILFNBRk0sRUFBUDtBQUdIOztBQUVEQyxZQUFTO0FBQ0wsY0FBTWQsVUFBVUMseUJBQWVDLHFCQUFmLEVBQWhCOztBQUVBLFlBQUlGLE9BQUosRUFBYTtBQUNULGdDQUFZLEtBQUt6QixpQkFBakIsRUFBb0N3QyxPQUFwQyxDQUE0QzdCLE1BQU07QUFDOUMsb0JBQUksS0FBS1gsaUJBQUwsQ0FBdUJXLEVBQXZCLEVBQTJCRSxTQUEzQixLQUF5Q1ksUUFBUWQsRUFBckQsRUFDSSxPQUFPLEtBQUtYLGlCQUFMLENBQXVCVyxFQUF2QixDQUFQO0FBQ1AsYUFIRDtBQUlILFNBTEQsTUFPSSxLQUFLWCxpQkFBTCxHQUF5QixFQUF6QjtBQUNQOztBQUVELFFBQUl5QyxRQUFKLEdBQWdCO0FBQ1osZUFBTyxLQUFLakIsMkJBQUwsRUFBUDtBQUNIO0FBM0dpRDs7QUE4R3ZDLFNBQVN4QyxtQkFBVCxDQUE4QlcscUJBQTlCLEVBQXFETSxVQUFyRCxFQUFpRTtBQUM1RSxXQUFPLElBQUlULDJCQUFKLENBQWdDRyxxQkFBaEMsRUFBdURNLFVBQXZELENBQVA7QUFDSCIsImZpbGUiOiJhcGkvcmVxdWVzdC1ob29rcy9yZXF1ZXN0LWxvZ2dlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zIH0gZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5pbXBvcnQgUmVxdWVzdEhvb2sgZnJvbSAnLi9ob29rJztcbmltcG9ydCB7IHBhcnNlIGFzIHBhcnNlVXNlckFnZW50IH0gZnJvbSAndXNlcmFnZW50JztcbmltcG9ydCB0ZXN0UnVuVHJhY2tlciBmcm9tICcuLi90ZXN0LXJ1bi10cmFja2VyJztcbmltcG9ydCBSZUV4ZWN1dGFibGVQcm9taXNlIGZyb20gJy4uLy4uL3V0aWxzL3JlLWV4ZWN1dGFibGUtcHJvbWlzZSc7XG5pbXBvcnQgeyBBUElFcnJvciB9IGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lJztcbmltcG9ydCBNRVNTQUdFIGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lL21lc3NhZ2UnO1xuXG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgbG9nUmVxdWVzdEhlYWRlcnM6ICAgICBmYWxzZSxcbiAgICBsb2dSZXF1ZXN0Qm9keTogICAgICAgIGZhbHNlLFxuICAgIHN0cmluZ2lmeVJlcXVlc3RCb2R5OiAgZmFsc2UsXG4gICAgbG9nUmVzcG9uc2VIZWFkZXJzOiAgICBmYWxzZSxcbiAgICBsb2dSZXNwb25zZUJvZHk6ICAgICAgIGZhbHNlLFxuICAgIHN0cmluZ2lmeVJlc3BvbnNlQm9keTogZmFsc2Vcbn07XG5cbmNsYXNzIFJlcXVlc3RMb2dnZXJJbXBsZW1lbnRhdGlvbiBleHRlbmRzIFJlcXVlc3RIb29rIHtcbiAgICBjb25zdHJ1Y3RvciAocmVxdWVzdEZpbHRlclJ1bGVJbml0LCBvcHRpb25zKSB7XG4gICAgICAgIG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX09QVElPTlMsIG9wdGlvbnMpO1xuICAgICAgICBSZXF1ZXN0TG9nZ2VySW1wbGVtZW50YXRpb24uX2Fzc2VydExvZ09wdGlvbnMob3B0aW9ucyk7XG5cbiAgICAgICAgY29uc3QgY29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnMgPSBuZXcgQ29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnMob3B0aW9ucy5sb2dSZXNwb25zZUhlYWRlcnMsIG9wdGlvbnMubG9nUmVzcG9uc2VCb2R5KTtcblxuICAgICAgICBzdXBlcihyZXF1ZXN0RmlsdGVyUnVsZUluaXQsIGNvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zKTtcblxuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgICAgIHRoaXMuX2ludGVybmFsUmVxdWVzdHMgPSB7fTtcbiAgICB9XG5cbiAgICBzdGF0aWMgX2Fzc2VydExvZ09wdGlvbnMgKGxvZ09wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFsb2dPcHRpb25zLmxvZ1JlcXVlc3RCb2R5ICYmIGxvZ09wdGlvbnMuc3RyaW5naWZ5UmVxdWVzdEJvZHkpXG4gICAgICAgICAgICB0aHJvdyBuZXcgQVBJRXJyb3IoJ1JlcXVlc3RMb2dnZXInLCBNRVNTQUdFLnJlcXVlc3RIb29rQ29uZmlndXJlQVBJRXJyb3IsICdSZXF1ZXN0TG9nZ2VyJywgJ0Nhbm5vdCBzdHJpbmdpZnkgdGhlIHJlcXVlc3QgYm9keSBiZWNhdXNlIGl0IGlzIG5vdCBsb2dnZWQuIFNwZWNpZnkgeyBsb2dSZXF1ZXN0Qm9keTogdHJ1ZSB9IGluIGxvZyBvcHRpb25zLicpO1xuXG4gICAgICAgIGlmICghbG9nT3B0aW9ucy5sb2dSZXNwb25zZUJvZHkgJiYgbG9nT3B0aW9ucy5zdHJpbmdpZnlSZXNwb25zZUJvZHkpXG4gICAgICAgICAgICB0aHJvdyBuZXcgQVBJRXJyb3IoJ1JlcXVlc3RMb2dnZXInLCBNRVNTQUdFLnJlcXVlc3RIb29rQ29uZmlndXJlQVBJRXJyb3IsICdSZXF1ZXN0TG9nZ2VyJywgJ0Nhbm5vdCBzdHJpbmdpZnkgdGhlIHJlc3BvbnNlIGJvZHkgYmVjYXVzZSBpdCBpcyBub3QgbG9nZ2VkLiBTcGVjaWZ5IHsgbG9nUmVzcG9uc2VCb2R5OiB0cnVlIH0gaW4gbG9nIG9wdGlvbnMuJyk7XG4gICAgfVxuXG4gICAgb25SZXF1ZXN0IChldmVudCkge1xuICAgICAgICBjb25zdCB1c2VyQWdlbnQgPSBwYXJzZVVzZXJBZ2VudChldmVudC5fcmVxdWVzdEluZm8udXNlckFnZW50KS50b1N0cmluZygpO1xuXG4gICAgICAgIGNvbnN0IGxvZ2dlZFJlcSA9IHtcbiAgICAgICAgICAgIGlkOiAgICAgICAgZXZlbnQuX3JlcXVlc3RJbmZvLnJlcXVlc3RJZCxcbiAgICAgICAgICAgIHRlc3RSdW5JZDogZXZlbnQuX3JlcXVlc3RJbmZvLnNlc3Npb25JZCxcbiAgICAgICAgICAgIHVzZXJBZ2VudCxcbiAgICAgICAgICAgIHJlcXVlc3Q6ICAge1xuICAgICAgICAgICAgICAgIHVybDogICAgZXZlbnQuX3JlcXVlc3RJbmZvLnVybCxcbiAgICAgICAgICAgICAgICBtZXRob2Q6IGV2ZW50Ll9yZXF1ZXN0SW5mby5tZXRob2QsXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5sb2dSZXF1ZXN0SGVhZGVycylcbiAgICAgICAgICAgIGxvZ2dlZFJlcS5yZXF1ZXN0LmhlYWRlcnMgPSBPYmplY3QuYXNzaWduKHt9LCBldmVudC5fcmVxdWVzdEluZm8uaGVhZGVycyk7XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5sb2dSZXF1ZXN0Qm9keSlcbiAgICAgICAgICAgIGxvZ2dlZFJlcS5yZXF1ZXN0LmJvZHkgPSB0aGlzLm9wdGlvbnMuc3RyaW5naWZ5UmVxdWVzdEJvZHkgPyBldmVudC5fcmVxdWVzdEluZm8uYm9keS50b1N0cmluZygpIDogZXZlbnQuX3JlcXVlc3RJbmZvLmJvZHk7XG5cbiAgICAgICAgdGhpcy5faW50ZXJuYWxSZXF1ZXN0c1tsb2dnZWRSZXEuaWRdID0gbG9nZ2VkUmVxO1xuICAgIH1cblxuICAgIG9uUmVzcG9uc2UgKGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGxvZ2dlclJlcSA9IHRoaXMuX2ludGVybmFsUmVxdWVzdHNbZXZlbnQucmVxdWVzdElkXTtcblxuICAgICAgICAvLyBOT1RFOiBJZiB0aGUgJ2NsZWFyJyBtZXRob2QgaXMgY2FsbGVkIGR1cmluZyBhIGxvbmcgcnVubmluZyByZXF1ZXN0LFxuICAgICAgICAvLyB3ZSBzaG91bGQgbm90IHNhdmUgYSByZXNwb25zZSBwYXJ0IC0gcmVxdWVzdCBwYXJ0IGhhcyBiZWVuIGFscmVhZHkgcmVtb3ZlZC5cbiAgICAgICAgaWYgKCFsb2dnZXJSZXEpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgbG9nZ2VyUmVxLnJlc3BvbnNlICAgICAgICAgICAgPSB7fTtcbiAgICAgICAgbG9nZ2VyUmVxLnJlc3BvbnNlLnN0YXR1c0NvZGUgPSBldmVudC5zdGF0dXNDb2RlO1xuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMubG9nUmVzcG9uc2VIZWFkZXJzKVxuICAgICAgICAgICAgbG9nZ2VyUmVxLnJlc3BvbnNlLmhlYWRlcnMgPSBPYmplY3QuYXNzaWduKHt9LCBldmVudC5oZWFkZXJzKTtcblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmxvZ1Jlc3BvbnNlQm9keSkge1xuICAgICAgICAgICAgbG9nZ2VyUmVxLnJlc3BvbnNlLmJvZHkgPSB0aGlzLm9wdGlvbnMuc3RyaW5naWZ5UmVzcG9uc2VCb2R5ICYmIGV2ZW50LmJvZHlcbiAgICAgICAgICAgICAgICA/IGV2ZW50LmJvZHkudG9TdHJpbmcoKVxuICAgICAgICAgICAgICAgIDogZXZlbnQuYm9keTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9wcmVwYXJlSW50ZXJuYWxSZXF1ZXN0SW5mbyAoKSB7XG4gICAgICAgIGNvbnN0IHRlc3RSdW4gICAgICAgID0gdGVzdFJ1blRyYWNrZXIucmVzb2x2ZUNvbnRleHRUZXN0UnVuKCk7XG4gICAgICAgIGxldCBwcmVwYXJlZFJlcXVlc3RzID0gT2JqZWN0LnZhbHVlcyh0aGlzLl9pbnRlcm5hbFJlcXVlc3RzKTtcblxuICAgICAgICBpZiAodGVzdFJ1bilcbiAgICAgICAgICAgIHByZXBhcmVkUmVxdWVzdHMgPSBwcmVwYXJlZFJlcXVlc3RzLmZpbHRlcihyID0+IHIudGVzdFJ1bklkID09PSB0ZXN0UnVuLmlkKTtcblxuICAgICAgICByZXR1cm4gcHJlcGFyZWRSZXF1ZXN0cztcbiAgICB9XG5cbiAgICBfZ2V0Q29tcGxldGVkUmVxdWVzdHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJlcGFyZUludGVybmFsUmVxdWVzdEluZm8oKS5maWx0ZXIociA9PiByLnJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICAvLyBBUElcbiAgICBjb250YWlucyAocHJlZGljYXRlKSB7XG4gICAgICAgIHJldHVybiBSZUV4ZWN1dGFibGVQcm9taXNlLmZyb21Gbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gISF0aGlzLl9nZXRDb21wbGV0ZWRSZXF1ZXN0cygpLmZpbmQocHJlZGljYXRlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY291bnQgKHByZWRpY2F0ZSkge1xuICAgICAgICByZXR1cm4gUmVFeGVjdXRhYmxlUHJvbWlzZS5mcm9tRm4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldENvbXBsZXRlZFJlcXVlc3RzKCkuZmlsdGVyKHByZWRpY2F0ZSkubGVuZ3RoO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBjbGVhciAoKSB7XG4gICAgICAgIGNvbnN0IHRlc3RSdW4gPSB0ZXN0UnVuVHJhY2tlci5yZXNvbHZlQ29udGV4dFRlc3RSdW4oKTtcblxuICAgICAgICBpZiAodGVzdFJ1bikge1xuICAgICAgICAgICAgT2JqZWN0LmtleXModGhpcy5faW50ZXJuYWxSZXF1ZXN0cykuZm9yRWFjaChpZCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2ludGVybmFsUmVxdWVzdHNbaWRdLnRlc3RSdW5JZCA9PT0gdGVzdFJ1bi5pZClcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2ludGVybmFsUmVxdWVzdHNbaWRdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5faW50ZXJuYWxSZXF1ZXN0cyA9IHt9O1xuICAgIH1cblxuICAgIGdldCByZXF1ZXN0cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcmVwYXJlSW50ZXJuYWxSZXF1ZXN0SW5mbygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY3JlYXRlUmVxdWVzdExvZ2dlciAocmVxdWVzdEZpbHRlclJ1bGVJbml0LCBsb2dPcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBSZXF1ZXN0TG9nZ2VySW1wbGVtZW50YXRpb24ocmVxdWVzdEZpbHRlclJ1bGVJbml0LCBsb2dPcHRpb25zKTtcbn1cblxuIl19 diff --git a/lib/api/request-hooks/request-mock.js b/lib/api/request-hooks/request-mock.js new file mode 100644 index 00000000..41d114d3 --- /dev/null +++ b/lib/api/request-hooks/request-mock.js @@ -0,0 +1,74 @@ +'use strict'; + +exports.__esModule = true; + +var _map = require('babel-runtime/core-js/map'); + +var _map2 = _interopRequireDefault(_map); + +exports.default = createRequestMock; + +var _hook = require('./hook'); + +var _hook2 = _interopRequireDefault(_hook); + +var _testcafeHammerhead = require('testcafe-hammerhead'); + +var _runtime = require('../../errors/runtime'); + +var _message = require('../../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +var _warningMessage = require('../../notifications/warning-message'); + +var _warningMessage2 = _interopRequireDefault(_warningMessage); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class RequestMock extends _hook2.default { + constructor() { + super([]); + + this.pendingRequestFilterRuleInit = null; + this.mocks = new _map2.default(); + } + + onRequest(event) { + const mock = this.mocks.get(event._requestFilterRule); + + event.setMock(mock); + } + + onResponse(event) { + if (event.statusCode === _testcafeHammerhead.SAME_ORIGIN_CHECK_FAILED_STATUS_CODE) this.warningLog.addWarning(_warningMessage2.default.requestMockCORSValidationFailed, RequestMock.name, event._requestFilterRule); + } + + // API + onRequestTo(requestFilterRuleInit) { + if (this.pendingRequestFilterRuleInit) throw new _runtime.APIError('onRequestTo', _message2.default.requestHookConfigureAPIError, RequestMock.name, "The 'respond' method was not called after 'onRequestTo'. You must call the 'respond' method to provide the mocked response."); + + this.pendingRequestFilterRuleInit = requestFilterRuleInit; + + return this; + } + + respond(body, statusCode, headers) { + if (!this.pendingRequestFilterRuleInit) throw new _runtime.APIError('respond', _message2.default.requestHookConfigureAPIError, RequestMock.name, "The 'onRequestTo' method was not called before 'respond'. You must call the 'onRequestTo' method to provide the URL requests to which are mocked."); + + const mock = new _testcafeHammerhead.ResponseMock(body, statusCode, headers); + const rule = new _testcafeHammerhead.RequestFilterRule(this.pendingRequestFilterRuleInit); + + this.requestFilterRules.push(rule); + this.mocks.set(rule, mock); + this.pendingRequestFilterRuleInit = null; + + return this; + } +} + +function createRequestMock() { + return new RequestMock(); +} +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvcmVxdWVzdC1ob29rcy9yZXF1ZXN0LW1vY2suanMiXSwibmFtZXMiOlsiY3JlYXRlUmVxdWVzdE1vY2siLCJSZXF1ZXN0TW9jayIsIlJlcXVlc3RIb29rIiwiY29uc3RydWN0b3IiLCJwZW5kaW5nUmVxdWVzdEZpbHRlclJ1bGVJbml0IiwibW9ja3MiLCJvblJlcXVlc3QiLCJldmVudCIsIm1vY2siLCJnZXQiLCJfcmVxdWVzdEZpbHRlclJ1bGUiLCJzZXRNb2NrIiwib25SZXNwb25zZSIsInN0YXR1c0NvZGUiLCJTQU1FX09SSUdJTl9DSEVDS19GQUlMRURfU1RBVFVTX0NPREUiLCJ3YXJuaW5nTG9nIiwiYWRkV2FybmluZyIsIldBUk5JTkdfTUVTU0FHRSIsInJlcXVlc3RNb2NrQ09SU1ZhbGlkYXRpb25GYWlsZWQiLCJuYW1lIiwib25SZXF1ZXN0VG8iLCJyZXF1ZXN0RmlsdGVyUnVsZUluaXQiLCJBUElFcnJvciIsIk1FU1NBR0UiLCJyZXF1ZXN0SG9va0NvbmZpZ3VyZUFQSUVycm9yIiwicmVzcG9uZCIsImJvZHkiLCJoZWFkZXJzIiwiUmVzcG9uc2VNb2NrIiwicnVsZSIsIlJlcXVlc3RGaWx0ZXJSdWxlIiwicmVxdWVzdEZpbHRlclJ1bGVzIiwicHVzaCIsInNldCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7a0JBa0R3QkEsaUI7O0FBbER4Qjs7OztBQUNBOztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7OztBQUVBLE1BQU1DLFdBQU4sU0FBMEJDLGNBQTFCLENBQXNDO0FBQ2xDQyxrQkFBZTtBQUNYLGNBQU0sRUFBTjs7QUFFQSxhQUFLQyw0QkFBTCxHQUFvQyxJQUFwQztBQUNBLGFBQUtDLEtBQUwsR0FBb0MsbUJBQXBDO0FBQ0g7O0FBRURDLGNBQVdDLEtBQVgsRUFBa0I7QUFDZCxjQUFNQyxPQUFPLEtBQUtILEtBQUwsQ0FBV0ksR0FBWCxDQUFlRixNQUFNRyxrQkFBckIsQ0FBYjs7QUFFQUgsY0FBTUksT0FBTixDQUFjSCxJQUFkO0FBQ0g7O0FBRURJLGVBQVlMLEtBQVosRUFBbUI7QUFDZixZQUFJQSxNQUFNTSxVQUFOLEtBQXFCQyx3REFBekIsRUFDSSxLQUFLQyxVQUFMLENBQWdCQyxVQUFoQixDQUEyQkMseUJBQWdCQywrQkFBM0MsRUFBNEVqQixZQUFZa0IsSUFBeEYsRUFBOEZaLE1BQU1HLGtCQUFwRztBQUNQOztBQUVEO0FBQ0FVLGdCQUFhQyxxQkFBYixFQUFvQztBQUNoQyxZQUFJLEtBQUtqQiw0QkFBVCxFQUNJLE1BQU0sSUFBSWtCLGlCQUFKLENBQWEsYUFBYixFQUE0QkMsa0JBQVFDLDRCQUFwQyxFQUFrRXZCLFlBQVlrQixJQUE5RSxFQUFvRiw2SEFBcEYsQ0FBTjs7QUFFSixhQUFLZiw0QkFBTCxHQUFvQ2lCLHFCQUFwQzs7QUFFQSxlQUFPLElBQVA7QUFDSDs7QUFFREksWUFBU0MsSUFBVCxFQUFlYixVQUFmLEVBQTJCYyxPQUEzQixFQUFvQztBQUNoQyxZQUFJLENBQUMsS0FBS3ZCLDRCQUFWLEVBQ0ksTUFBTSxJQUFJa0IsaUJBQUosQ0FBYSxTQUFiLEVBQXdCQyxrQkFBUUMsNEJBQWhDLEVBQThEdkIsWUFBWWtCLElBQTFFLEVBQWdGLG1KQUFoRixDQUFOOztBQUVKLGNBQU1YLE9BQU8sSUFBSW9CLGdDQUFKLENBQWlCRixJQUFqQixFQUF1QmIsVUFBdkIsRUFBbUNjLE9BQW5DLENBQWI7QUFDQSxjQUFNRSxPQUFPLElBQUlDLHFDQUFKLENBQXNCLEtBQUsxQiw0QkFBM0IsQ0FBYjs7QUFFQSxhQUFLMkIsa0JBQUwsQ0FBd0JDLElBQXhCLENBQTZCSCxJQUE3QjtBQUNBLGFBQUt4QixLQUFMLENBQVc0QixHQUFYLENBQWVKLElBQWYsRUFBcUJyQixJQUFyQjtBQUNBLGFBQUtKLDRCQUFMLEdBQW9DLElBQXBDOztBQUVBLGVBQU8sSUFBUDtBQUNIO0FBekNpQzs7QUE0Q3ZCLFNBQVNKLGlCQUFULEdBQThCO0FBQ3pDLFdBQU8sSUFBSUMsV0FBSixFQUFQO0FBQ0giLCJmaWxlIjoiYXBpL3JlcXVlc3QtaG9va3MvcmVxdWVzdC1tb2NrLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlcXVlc3RIb29rIGZyb20gJy4vaG9vayc7XG5pbXBvcnQgeyBSZXNwb25zZU1vY2ssIFJlcXVlc3RGaWx0ZXJSdWxlLCBTQU1FX09SSUdJTl9DSEVDS19GQUlMRURfU1RBVFVTX0NPREUgfSBmcm9tICd0ZXN0Y2FmZS1oYW1tZXJoZWFkJztcbmltcG9ydCB7IEFQSUVycm9yIH0gZnJvbSAnLi4vLi4vZXJyb3JzL3J1bnRpbWUnO1xuaW1wb3J0IE1FU1NBR0UgZnJvbSAnLi4vLi4vZXJyb3JzL3J1bnRpbWUvbWVzc2FnZSc7XG5pbXBvcnQgV0FSTklOR19NRVNTQUdFIGZyb20gJy4uLy4uL25vdGlmaWNhdGlvbnMvd2FybmluZy1tZXNzYWdlJztcblxuY2xhc3MgUmVxdWVzdE1vY2sgZXh0ZW5kcyBSZXF1ZXN0SG9vayB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcihbXSk7XG5cbiAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdEZpbHRlclJ1bGVJbml0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5tb2NrcyAgICAgICAgICAgICAgICAgICAgICAgID0gbmV3IE1hcCgpO1xuICAgIH1cblxuICAgIG9uUmVxdWVzdCAoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgbW9jayA9IHRoaXMubW9ja3MuZ2V0KGV2ZW50Ll9yZXF1ZXN0RmlsdGVyUnVsZSk7XG5cbiAgICAgICAgZXZlbnQuc2V0TW9jayhtb2NrKTtcbiAgICB9XG5cbiAgICBvblJlc3BvbnNlIChldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQuc3RhdHVzQ29kZSA9PT0gU0FNRV9PUklHSU5fQ0hFQ0tfRkFJTEVEX1NUQVRVU19DT0RFKVxuICAgICAgICAgICAgdGhpcy53YXJuaW5nTG9nLmFkZFdhcm5pbmcoV0FSTklOR19NRVNTQUdFLnJlcXVlc3RNb2NrQ09SU1ZhbGlkYXRpb25GYWlsZWQsIFJlcXVlc3RNb2NrLm5hbWUsIGV2ZW50Ll9yZXF1ZXN0RmlsdGVyUnVsZSk7XG4gICAgfVxuXG4gICAgLy8gQVBJXG4gICAgb25SZXF1ZXN0VG8gKHJlcXVlc3RGaWx0ZXJSdWxlSW5pdCkge1xuICAgICAgICBpZiAodGhpcy5wZW5kaW5nUmVxdWVzdEZpbHRlclJ1bGVJbml0KVxuICAgICAgICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKCdvblJlcXVlc3RUbycsIE1FU1NBR0UucmVxdWVzdEhvb2tDb25maWd1cmVBUElFcnJvciwgUmVxdWVzdE1vY2submFtZSwgXCJUaGUgJ3Jlc3BvbmQnIG1ldGhvZCB3YXMgbm90IGNhbGxlZCBhZnRlciAnb25SZXF1ZXN0VG8nLiBZb3UgbXVzdCBjYWxsIHRoZSAncmVzcG9uZCcgbWV0aG9kIHRvIHByb3ZpZGUgdGhlIG1vY2tlZCByZXNwb25zZS5cIik7XG5cbiAgICAgICAgdGhpcy5wZW5kaW5nUmVxdWVzdEZpbHRlclJ1bGVJbml0ID0gcmVxdWVzdEZpbHRlclJ1bGVJbml0O1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHJlc3BvbmQgKGJvZHksIHN0YXR1c0NvZGUsIGhlYWRlcnMpIHtcbiAgICAgICAgaWYgKCF0aGlzLnBlbmRpbmdSZXF1ZXN0RmlsdGVyUnVsZUluaXQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgQVBJRXJyb3IoJ3Jlc3BvbmQnLCBNRVNTQUdFLnJlcXVlc3RIb29rQ29uZmlndXJlQVBJRXJyb3IsIFJlcXVlc3RNb2NrLm5hbWUsIFwiVGhlICdvblJlcXVlc3RUbycgbWV0aG9kIHdhcyBub3QgY2FsbGVkIGJlZm9yZSAncmVzcG9uZCcuIFlvdSBtdXN0IGNhbGwgdGhlICdvblJlcXVlc3RUbycgbWV0aG9kIHRvIHByb3ZpZGUgdGhlIFVSTCByZXF1ZXN0cyB0byB3aGljaCBhcmUgbW9ja2VkLlwiKTtcblxuICAgICAgICBjb25zdCBtb2NrID0gbmV3IFJlc3BvbnNlTW9jayhib2R5LCBzdGF0dXNDb2RlLCBoZWFkZXJzKTtcbiAgICAgICAgY29uc3QgcnVsZSA9IG5ldyBSZXF1ZXN0RmlsdGVyUnVsZSh0aGlzLnBlbmRpbmdSZXF1ZXN0RmlsdGVyUnVsZUluaXQpO1xuXG4gICAgICAgIHRoaXMucmVxdWVzdEZpbHRlclJ1bGVzLnB1c2gocnVsZSk7XG4gICAgICAgIHRoaXMubW9ja3Muc2V0KHJ1bGUsIG1vY2spO1xuICAgICAgICB0aGlzLnBlbmRpbmdSZXF1ZXN0RmlsdGVyUnVsZUluaXQgPSBudWxsO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY3JlYXRlUmVxdWVzdE1vY2sgKCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdE1vY2soKTtcbn1cbiJdfQ== diff --git a/lib/api/structure/fixture.js b/lib/api/structure/fixture.js new file mode 100644 index 00000000..17114ebd --- /dev/null +++ b/lib/api/structure/fixture.js @@ -0,0 +1,103 @@ +'use strict'; + +exports.__esModule = true; + +var _typeAssertions = require('../../errors/runtime/type-assertions'); + +var _handleTagArgs = require('../../utils/handle-tag-args'); + +var _handleTagArgs2 = _interopRequireDefault(_handleTagArgs); + +var _testingUnit = require('./testing-unit'); + +var _testingUnit2 = _interopRequireDefault(_testingUnit); + +var _wrapTestFunction = require('../wrap-test-function'); + +var _wrapTestFunction2 = _interopRequireDefault(_wrapTestFunction); + +var _assertType = require('../request-hooks/assert-type'); + +var _assertType2 = _interopRequireDefault(_assertType); + +var _lodash = require('lodash'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Fixture extends _testingUnit2.default { + constructor(testFile) { + super(testFile, 'fixture'); + + this.path = testFile.filename; + + this.pageUrl = 'about:blank'; + + this.beforeEachFn = null; + this.afterEachFn = null; + + this.beforeFn = null; + this.afterFn = null; + + this.requestHooks = []; + + return this.apiOrigin; + } + + _add(name, ...rest) { + name = (0, _handleTagArgs2.default)(name, rest); + + (0, _typeAssertions.assertType)(_typeAssertions.is.string, 'apiOrigin', 'The fixture name', name); + + this.name = name; + this.testFile.currentFixture = this; + + return this.apiOrigin; + } + + _before$(fn) { + (0, _typeAssertions.assertType)(_typeAssertions.is.function, 'before', 'fixture.before hook', fn); + + this.beforeFn = fn; + + return this.apiOrigin; + } + + _after$(fn) { + (0, _typeAssertions.assertType)(_typeAssertions.is.function, 'after', 'fixture.after hook', fn); + + this.afterFn = fn; + + return this.apiOrigin; + } + + _beforeEach$(fn) { + (0, _typeAssertions.assertType)(_typeAssertions.is.function, 'beforeEach', 'fixture.beforeEach hook', fn); + + this.beforeEachFn = (0, _wrapTestFunction2.default)(fn); + + return this.apiOrigin; + } + + _afterEach$(fn) { + (0, _typeAssertions.assertType)(_typeAssertions.is.function, 'afterEach', 'fixture.afterEach hook', fn); + + this.afterEachFn = (0, _wrapTestFunction2.default)(fn); + + return this.apiOrigin; + } + + _requestHooks$(...hooks) { + hooks = (0, _lodash.flattenDeep)(hooks); + + (0, _assertType2.default)(hooks); + + this.requestHooks = hooks; + + return this.apiOrigin; + } +} + +exports.default = Fixture; +_testingUnit2.default._makeAPIListForChildClass(Fixture); +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvc3RydWN0dXJlL2ZpeHR1cmUuanMiXSwibmFtZXMiOlsiRml4dHVyZSIsIlRlc3RpbmdVbml0IiwiY29uc3RydWN0b3IiLCJ0ZXN0RmlsZSIsInBhdGgiLCJmaWxlbmFtZSIsInBhZ2VVcmwiLCJiZWZvcmVFYWNoRm4iLCJhZnRlckVhY2hGbiIsImJlZm9yZUZuIiwiYWZ0ZXJGbiIsInJlcXVlc3RIb29rcyIsImFwaU9yaWdpbiIsIl9hZGQiLCJuYW1lIiwicmVzdCIsImlzIiwic3RyaW5nIiwiY3VycmVudEZpeHR1cmUiLCJfYmVmb3JlJCIsImZuIiwiZnVuY3Rpb24iLCJfYWZ0ZXIkIiwiX2JlZm9yZUVhY2gkIiwiX2FmdGVyRWFjaCQiLCJfcmVxdWVzdEhvb2tzJCIsImhvb2tzIiwiX21ha2VBUElMaXN0Rm9yQ2hpbGRDbGFzcyJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFFZSxNQUFNQSxPQUFOLFNBQXNCQyxxQkFBdEIsQ0FBa0M7QUFDN0NDLGdCQUFhQyxRQUFiLEVBQXVCO0FBQ25CLGNBQU1BLFFBQU4sRUFBZ0IsU0FBaEI7O0FBRUEsYUFBS0MsSUFBTCxHQUFZRCxTQUFTRSxRQUFyQjs7QUFFQSxhQUFLQyxPQUFMLEdBQWUsYUFBZjs7QUFFQSxhQUFLQyxZQUFMLEdBQW9CLElBQXBCO0FBQ0EsYUFBS0MsV0FBTCxHQUFvQixJQUFwQjs7QUFFQSxhQUFLQyxRQUFMLEdBQWdCLElBQWhCO0FBQ0EsYUFBS0MsT0FBTCxHQUFnQixJQUFoQjs7QUFFQSxhQUFLQyxZQUFMLEdBQW9CLEVBQXBCOztBQUVBLGVBQU8sS0FBS0MsU0FBWjtBQUNIOztBQUVEQyxTQUFNQyxJQUFOLEVBQVksR0FBR0MsSUFBZixFQUFxQjtBQUNqQkQsZUFBTyw2QkFBY0EsSUFBZCxFQUFvQkMsSUFBcEIsQ0FBUDs7QUFFQSx3Q0FBV0MsbUJBQUdDLE1BQWQsRUFBc0IsV0FBdEIsRUFBbUMsa0JBQW5DLEVBQXVESCxJQUF2RDs7QUFFQSxhQUFLQSxJQUFMLEdBQStCQSxJQUEvQjtBQUNBLGFBQUtYLFFBQUwsQ0FBY2UsY0FBZCxHQUErQixJQUEvQjs7QUFFQSxlQUFPLEtBQUtOLFNBQVo7QUFDSDs7QUFFRE8sYUFBVUMsRUFBVixFQUFjO0FBQ1Ysd0NBQVdKLG1CQUFHSyxRQUFkLEVBQXdCLFFBQXhCLEVBQWtDLHFCQUFsQyxFQUF5REQsRUFBekQ7O0FBRUEsYUFBS1gsUUFBTCxHQUFnQlcsRUFBaEI7O0FBRUEsZUFBTyxLQUFLUixTQUFaO0FBQ0g7O0FBRURVLFlBQVNGLEVBQVQsRUFBYTtBQUNULHdDQUFXSixtQkFBR0ssUUFBZCxFQUF3QixPQUF4QixFQUFpQyxvQkFBakMsRUFBdURELEVBQXZEOztBQUVBLGFBQUtWLE9BQUwsR0FBZVUsRUFBZjs7QUFFQSxlQUFPLEtBQUtSLFNBQVo7QUFDSDs7QUFFRFcsaUJBQWNILEVBQWQsRUFBa0I7QUFDZCx3Q0FBV0osbUJBQUdLLFFBQWQsRUFBd0IsWUFBeEIsRUFBc0MseUJBQXRDLEVBQWlFRCxFQUFqRTs7QUFFQSxhQUFLYixZQUFMLEdBQW9CLGdDQUFpQmEsRUFBakIsQ0FBcEI7O0FBRUEsZUFBTyxLQUFLUixTQUFaO0FBQ0g7O0FBRURZLGdCQUFhSixFQUFiLEVBQWlCO0FBQ2Isd0NBQVdKLG1CQUFHSyxRQUFkLEVBQXdCLFdBQXhCLEVBQXFDLHdCQUFyQyxFQUErREQsRUFBL0Q7O0FBRUEsYUFBS1osV0FBTCxHQUFtQixnQ0FBaUJZLEVBQWpCLENBQW5COztBQUVBLGVBQU8sS0FBS1IsU0FBWjtBQUNIOztBQUVEYSxtQkFBZ0IsR0FBR0MsS0FBbkIsRUFBMEI7QUFDdEJBLGdCQUFRLHlCQUFRQSxLQUFSLENBQVI7O0FBRUEsa0NBQXNCQSxLQUF0Qjs7QUFFQSxhQUFLZixZQUFMLEdBQW9CZSxLQUFwQjs7QUFFQSxlQUFPLEtBQUtkLFNBQVo7QUFDSDtBQXRFNEM7O2tCQUE1QlosTztBQXlFckJDLHNCQUFZMEIseUJBQVosQ0FBc0MzQixPQUF0QyIsImZpbGUiOiJhcGkvc3RydWN0dXJlL2ZpeHR1cmUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhc3NlcnRUeXBlLCBpcyB9IGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lL3R5cGUtYXNzZXJ0aW9ucyc7XG5pbXBvcnQgaGFuZGxlVGFnQXJncyBmcm9tICcuLi8uLi91dGlscy9oYW5kbGUtdGFnLWFyZ3MnO1xuaW1wb3J0IFRlc3RpbmdVbml0IGZyb20gJy4vdGVzdGluZy11bml0JztcbmltcG9ydCB3cmFwVGVzdEZ1bmN0aW9uIGZyb20gJy4uL3dyYXAtdGVzdC1mdW5jdGlvbic7XG5pbXBvcnQgYXNzZXJ0UmVxdWVzdEhvb2tUeXBlIGZyb20gJy4uL3JlcXVlc3QtaG9va3MvYXNzZXJ0LXR5cGUnO1xuaW1wb3J0IHsgZmxhdHRlbkRlZXAgYXMgZmxhdHRlbiB9IGZyb20gJ2xvZGFzaCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZpeHR1cmUgZXh0ZW5kcyBUZXN0aW5nVW5pdCB7XG4gICAgY29uc3RydWN0b3IgKHRlc3RGaWxlKSB7XG4gICAgICAgIHN1cGVyKHRlc3RGaWxlLCAnZml4dHVyZScpO1xuXG4gICAgICAgIHRoaXMucGF0aCA9IHRlc3RGaWxlLmZpbGVuYW1lO1xuXG4gICAgICAgIHRoaXMucGFnZVVybCA9ICdhYm91dDpibGFuayc7XG5cbiAgICAgICAgdGhpcy5iZWZvcmVFYWNoRm4gPSBudWxsO1xuICAgICAgICB0aGlzLmFmdGVyRWFjaEZuICA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5iZWZvcmVGbiA9IG51bGw7XG4gICAgICAgIHRoaXMuYWZ0ZXJGbiAgPSBudWxsO1xuXG4gICAgICAgIHRoaXMucmVxdWVzdEhvb2tzID0gW107XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXBpT3JpZ2luO1xuICAgIH1cblxuICAgIF9hZGQgKG5hbWUsIC4uLnJlc3QpIHtcbiAgICAgICAgbmFtZSA9IGhhbmRsZVRhZ0FyZ3MobmFtZSwgcmVzdCk7XG5cbiAgICAgICAgYXNzZXJ0VHlwZShpcy5zdHJpbmcsICdhcGlPcmlnaW4nLCAnVGhlIGZpeHR1cmUgbmFtZScsIG5hbWUpO1xuXG4gICAgICAgIHRoaXMubmFtZSAgICAgICAgICAgICAgICAgICAgPSBuYW1lO1xuICAgICAgICB0aGlzLnRlc3RGaWxlLmN1cnJlbnRGaXh0dXJlID0gdGhpcztcblxuICAgICAgICByZXR1cm4gdGhpcy5hcGlPcmlnaW47XG4gICAgfVxuXG4gICAgX2JlZm9yZSQgKGZuKSB7XG4gICAgICAgIGFzc2VydFR5cGUoaXMuZnVuY3Rpb24sICdiZWZvcmUnLCAnZml4dHVyZS5iZWZvcmUgaG9vaycsIGZuKTtcblxuICAgICAgICB0aGlzLmJlZm9yZUZuID0gZm47XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXBpT3JpZ2luO1xuICAgIH1cblxuICAgIF9hZnRlciQgKGZuKSB7XG4gICAgICAgIGFzc2VydFR5cGUoaXMuZnVuY3Rpb24sICdhZnRlcicsICdmaXh0dXJlLmFmdGVyIGhvb2snLCBmbik7XG5cbiAgICAgICAgdGhpcy5hZnRlckZuID0gZm47XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXBpT3JpZ2luO1xuICAgIH1cblxuICAgIF9iZWZvcmVFYWNoJCAoZm4pIHtcbiAgICAgICAgYXNzZXJ0VHlwZShpcy5mdW5jdGlvbiwgJ2JlZm9yZUVhY2gnLCAnZml4dHVyZS5iZWZvcmVFYWNoIGhvb2snLCBmbik7XG5cbiAgICAgICAgdGhpcy5iZWZvcmVFYWNoRm4gPSB3cmFwVGVzdEZ1bmN0aW9uKGZuKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5hcGlPcmlnaW47XG4gICAgfVxuXG4gICAgX2FmdGVyRWFjaCQgKGZuKSB7XG4gICAgICAgIGFzc2VydFR5cGUoaXMuZnVuY3Rpb24sICdhZnRlckVhY2gnLCAnZml4dHVyZS5hZnRlckVhY2ggaG9vaycsIGZuKTtcblxuICAgICAgICB0aGlzLmFmdGVyRWFjaEZuID0gd3JhcFRlc3RGdW5jdGlvbihmbik7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXBpT3JpZ2luO1xuICAgIH1cblxuICAgIF9yZXF1ZXN0SG9va3MkICguLi5ob29rcykge1xuICAgICAgICBob29rcyA9IGZsYXR0ZW4oaG9va3MpO1xuXG4gICAgICAgIGFzc2VydFJlcXVlc3RIb29rVHlwZShob29rcyk7XG5cbiAgICAgICAgdGhpcy5yZXF1ZXN0SG9va3MgPSBob29rcztcblxuICAgICAgICByZXR1cm4gdGhpcy5hcGlPcmlnaW47XG4gICAgfVxufVxuXG5UZXN0aW5nVW5pdC5fbWFrZUFQSUxpc3RGb3JDaGlsZENsYXNzKEZpeHR1cmUpO1xuIl19 diff --git a/lib/api/structure/test-file.js b/lib/api/structure/test-file.js new file mode 100644 index 00000000..ec8b7d5e --- /dev/null +++ b/lib/api/structure/test-file.js @@ -0,0 +1,27 @@ +'use strict'; + +exports.__esModule = true; +const BORROWED_TEST_PROPERTIES = ['skip', 'only', 'pageUrl', 'authCredentials']; + +class TestFile { + constructor(filename) { + this.filename = filename; + this.currentFixture = null; + this.collectedTests = []; + } + + getTests() { + this.collectedTests.forEach(test => { + BORROWED_TEST_PROPERTIES.forEach(prop => { + test[prop] = test[prop] || test.fixture[prop]; + }); + + if (test.disablePageReloads === void 0) test.disablePageReloads = test.fixture.disablePageReloads; + }); + + return this.collectedTests; + } +} +exports.default = TestFile; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvc3RydWN0dXJlL3Rlc3QtZmlsZS5qcyJdLCJuYW1lcyI6WyJCT1JST1dFRF9URVNUX1BST1BFUlRJRVMiLCJUZXN0RmlsZSIsImNvbnN0cnVjdG9yIiwiZmlsZW5hbWUiLCJjdXJyZW50Rml4dHVyZSIsImNvbGxlY3RlZFRlc3RzIiwiZ2V0VGVzdHMiLCJmb3JFYWNoIiwidGVzdCIsInByb3AiLCJmaXh0dXJlIiwiZGlzYWJsZVBhZ2VSZWxvYWRzIl0sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFNQSwyQkFBMkIsQ0FBQyxNQUFELEVBQVMsTUFBVCxFQUFpQixTQUFqQixFQUE0QixpQkFBNUIsQ0FBakM7O0FBRWUsTUFBTUMsUUFBTixDQUFlO0FBQzFCQyxnQkFBYUMsUUFBYixFQUF1QjtBQUNuQixhQUFLQSxRQUFMLEdBQXNCQSxRQUF0QjtBQUNBLGFBQUtDLGNBQUwsR0FBc0IsSUFBdEI7QUFDQSxhQUFLQyxjQUFMLEdBQXNCLEVBQXRCO0FBQ0g7O0FBRURDLGVBQVk7QUFDUixhQUFLRCxjQUFMLENBQW9CRSxPQUFwQixDQUE0QkMsUUFBUTtBQUNoQ1IscUNBQXlCTyxPQUF6QixDQUFpQ0UsUUFBUTtBQUNyQ0QscUJBQUtDLElBQUwsSUFBYUQsS0FBS0MsSUFBTCxLQUFjRCxLQUFLRSxPQUFMLENBQWFELElBQWIsQ0FBM0I7QUFDSCxhQUZEOztBQUlBLGdCQUFJRCxLQUFLRyxrQkFBTCxLQUE0QixLQUFLLENBQXJDLEVBQ0lILEtBQUtHLGtCQUFMLEdBQTBCSCxLQUFLRSxPQUFMLENBQWFDLGtCQUF2QztBQUNQLFNBUEQ7O0FBU0EsZUFBTyxLQUFLTixjQUFaO0FBQ0g7QUFsQnlCO2tCQUFUSixRIiwiZmlsZSI6ImFwaS9zdHJ1Y3R1cmUvdGVzdC1maWxlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgQk9SUk9XRURfVEVTVF9QUk9QRVJUSUVTID0gWydza2lwJywgJ29ubHknLCAncGFnZVVybCcsICdhdXRoQ3JlZGVudGlhbHMnXTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGVzdEZpbGUge1xuICAgIGNvbnN0cnVjdG9yIChmaWxlbmFtZSkge1xuICAgICAgICB0aGlzLmZpbGVuYW1lICAgICAgID0gZmlsZW5hbWU7XG4gICAgICAgIHRoaXMuY3VycmVudEZpeHR1cmUgPSBudWxsO1xuICAgICAgICB0aGlzLmNvbGxlY3RlZFRlc3RzID0gW107XG4gICAgfVxuXG4gICAgZ2V0VGVzdHMgKCkge1xuICAgICAgICB0aGlzLmNvbGxlY3RlZFRlc3RzLmZvckVhY2godGVzdCA9PiB7XG4gICAgICAgICAgICBCT1JST1dFRF9URVNUX1BST1BFUlRJRVMuZm9yRWFjaChwcm9wID0+IHtcbiAgICAgICAgICAgICAgICB0ZXN0W3Byb3BdID0gdGVzdFtwcm9wXSB8fCB0ZXN0LmZpeHR1cmVbcHJvcF07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKHRlc3QuZGlzYWJsZVBhZ2VSZWxvYWRzID09PSB2b2lkIDApXG4gICAgICAgICAgICAgICAgdGVzdC5kaXNhYmxlUGFnZVJlbG9hZHMgPSB0ZXN0LmZpeHR1cmUuZGlzYWJsZVBhZ2VSZWxvYWRzO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5jb2xsZWN0ZWRUZXN0cztcbiAgICB9XG59XG4iXX0= diff --git a/lib/api/structure/test.js b/lib/api/structure/test.js new file mode 100644 index 00000000..05cc6675 --- /dev/null +++ b/lib/api/structure/test.js @@ -0,0 +1,83 @@ +'use strict'; + +exports.__esModule = true; + +var _from = require('babel-runtime/core-js/array/from'); + +var _from2 = _interopRequireDefault(_from); + +var _testingUnit = require('./testing-unit'); + +var _testingUnit2 = _interopRequireDefault(_testingUnit); + +var _typeAssertions = require('../../errors/runtime/type-assertions'); + +var _wrapTestFunction = require('../wrap-test-function'); + +var _wrapTestFunction2 = _interopRequireDefault(_wrapTestFunction); + +var _assertType = require('../request-hooks/assert-type'); + +var _assertType2 = _interopRequireDefault(_assertType); + +var _lodash = require('lodash'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Test extends _testingUnit2.default { + constructor(testFile) { + super(testFile, 'test'); + + this.fixture = testFile.currentFixture; + + this.fn = null; + this.beforeFn = null; + this.afterFn = null; + this.requestHooks = this.fixture.requestHooks.length ? (0, _from2.default)(this.fixture.requestHooks) : []; + + return this.apiOrigin; + } + + _add(name, fn) { + (0, _typeAssertions.assertType)(_typeAssertions.is.string, 'apiOrigin', 'The test name', name); + (0, _typeAssertions.assertType)(_typeAssertions.is.function, 'apiOrigin', 'The test body', fn); + + this.name = name; + this.fn = (0, _wrapTestFunction2.default)(fn); + + if (this.testFile.collectedTests.indexOf(this) < 0) this.testFile.collectedTests.push(this); + + return this.apiOrigin; + } + + _before$(fn) { + (0, _typeAssertions.assertType)(_typeAssertions.is.function, 'before', 'test.before hook', fn); + + this.beforeFn = (0, _wrapTestFunction2.default)(fn); + + return this.apiOrigin; + } + + _after$(fn) { + (0, _typeAssertions.assertType)(_typeAssertions.is.function, 'after', 'test.after hook', fn); + + this.afterFn = (0, _wrapTestFunction2.default)(fn); + + return this.apiOrigin; + } + + _requestHooks$(...hooks) { + hooks = (0, _lodash.flattenDeep)(hooks); + + (0, _assertType2.default)(hooks); + + this.requestHooks = (0, _lodash.union)(this.requestHooks, hooks); + + return this.apiOrigin; + } +} + +exports.default = Test; +_testingUnit2.default._makeAPIListForChildClass(Test); +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvc3RydWN0dXJlL3Rlc3QuanMiXSwibmFtZXMiOlsiVGVzdCIsIlRlc3RpbmdVbml0IiwiY29uc3RydWN0b3IiLCJ0ZXN0RmlsZSIsImZpeHR1cmUiLCJjdXJyZW50Rml4dHVyZSIsImZuIiwiYmVmb3JlRm4iLCJhZnRlckZuIiwicmVxdWVzdEhvb2tzIiwibGVuZ3RoIiwiYXBpT3JpZ2luIiwiX2FkZCIsIm5hbWUiLCJpcyIsInN0cmluZyIsImZ1bmN0aW9uIiwiY29sbGVjdGVkVGVzdHMiLCJpbmRleE9mIiwicHVzaCIsIl9iZWZvcmUkIiwiX2FmdGVyJCIsIl9yZXF1ZXN0SG9va3MkIiwiaG9va3MiLCJfbWFrZUFQSUxpc3RGb3JDaGlsZENsYXNzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBRWUsTUFBTUEsSUFBTixTQUFtQkMscUJBQW5CLENBQStCO0FBQzFDQyxnQkFBYUMsUUFBYixFQUF1QjtBQUNuQixjQUFNQSxRQUFOLEVBQWdCLE1BQWhCOztBQUVBLGFBQUtDLE9BQUwsR0FBZUQsU0FBU0UsY0FBeEI7O0FBRUEsYUFBS0MsRUFBTCxHQUFvQixJQUFwQjtBQUNBLGFBQUtDLFFBQUwsR0FBb0IsSUFBcEI7QUFDQSxhQUFLQyxPQUFMLEdBQW9CLElBQXBCO0FBQ0EsYUFBS0MsWUFBTCxHQUFvQixLQUFLTCxPQUFMLENBQWFLLFlBQWIsQ0FBMEJDLE1BQTFCLEdBQW1DLG9CQUFXLEtBQUtOLE9BQUwsQ0FBYUssWUFBeEIsQ0FBbkMsR0FBMkUsRUFBL0Y7O0FBRUEsZUFBTyxLQUFLRSxTQUFaO0FBQ0g7O0FBRURDLFNBQU1DLElBQU4sRUFBWVAsRUFBWixFQUFnQjtBQUNaLHdDQUFXUSxtQkFBR0MsTUFBZCxFQUFzQixXQUF0QixFQUFtQyxlQUFuQyxFQUFvREYsSUFBcEQ7QUFDQSx3Q0FBV0MsbUJBQUdFLFFBQWQsRUFBd0IsV0FBeEIsRUFBcUMsZUFBckMsRUFBc0RWLEVBQXREOztBQUVBLGFBQUtPLElBQUwsR0FBWUEsSUFBWjtBQUNBLGFBQUtQLEVBQUwsR0FBWSxnQ0FBaUJBLEVBQWpCLENBQVo7O0FBRUEsWUFBSSxLQUFLSCxRQUFMLENBQWNjLGNBQWQsQ0FBNkJDLE9BQTdCLENBQXFDLElBQXJDLElBQTZDLENBQWpELEVBQ0ksS0FBS2YsUUFBTCxDQUFjYyxjQUFkLENBQTZCRSxJQUE3QixDQUFrQyxJQUFsQzs7QUFFSixlQUFPLEtBQUtSLFNBQVo7QUFDSDs7QUFFRFMsYUFBVWQsRUFBVixFQUFjO0FBQ1Ysd0NBQVdRLG1CQUFHRSxRQUFkLEVBQXdCLFFBQXhCLEVBQWtDLGtCQUFsQyxFQUFzRFYsRUFBdEQ7O0FBRUEsYUFBS0MsUUFBTCxHQUFnQixnQ0FBaUJELEVBQWpCLENBQWhCOztBQUVBLGVBQU8sS0FBS0ssU0FBWjtBQUNIOztBQUVEVSxZQUFTZixFQUFULEVBQWE7QUFDVCx3Q0FBV1EsbUJBQUdFLFFBQWQsRUFBd0IsT0FBeEIsRUFBaUMsaUJBQWpDLEVBQW9EVixFQUFwRDs7QUFFQSxhQUFLRSxPQUFMLEdBQWUsZ0NBQWlCRixFQUFqQixDQUFmOztBQUVBLGVBQU8sS0FBS0ssU0FBWjtBQUNIOztBQUVEVyxtQkFBZ0IsR0FBR0MsS0FBbkIsRUFBMEI7QUFDdEJBLGdCQUFRLHlCQUFRQSxLQUFSLENBQVI7O0FBRUEsa0NBQXNCQSxLQUF0Qjs7QUFFQSxhQUFLZCxZQUFMLEdBQW9CLG1CQUFNLEtBQUtBLFlBQVgsRUFBeUJjLEtBQXpCLENBQXBCOztBQUVBLGVBQU8sS0FBS1osU0FBWjtBQUNIO0FBbkR5Qzs7a0JBQXpCWCxJO0FBc0RyQkMsc0JBQVl1Qix5QkFBWixDQUFzQ3hCLElBQXRDIiwiZmlsZSI6ImFwaS9zdHJ1Y3R1cmUvdGVzdC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBUZXN0aW5nVW5pdCBmcm9tICcuL3Rlc3RpbmctdW5pdCc7XG5pbXBvcnQgeyBhc3NlcnRUeXBlLCBpcyB9IGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lL3R5cGUtYXNzZXJ0aW9ucyc7XG5pbXBvcnQgd3JhcFRlc3RGdW5jdGlvbiBmcm9tICcuLi93cmFwLXRlc3QtZnVuY3Rpb24nO1xuaW1wb3J0IGFzc2VydFJlcXVlc3RIb29rVHlwZSBmcm9tICcuLi9yZXF1ZXN0LWhvb2tzL2Fzc2VydC10eXBlJztcbmltcG9ydCB7IGZsYXR0ZW5EZWVwIGFzIGZsYXR0ZW4sIHVuaW9uIH0gZnJvbSAnbG9kYXNoJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGVzdCBleHRlbmRzIFRlc3RpbmdVbml0IHtcbiAgICBjb25zdHJ1Y3RvciAodGVzdEZpbGUpIHtcbiAgICAgICAgc3VwZXIodGVzdEZpbGUsICd0ZXN0Jyk7XG5cbiAgICAgICAgdGhpcy5maXh0dXJlID0gdGVzdEZpbGUuY3VycmVudEZpeHR1cmU7XG5cbiAgICAgICAgdGhpcy5mbiAgICAgICAgICAgPSBudWxsO1xuICAgICAgICB0aGlzLmJlZm9yZUZuICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMuYWZ0ZXJGbiAgICAgID0gbnVsbDtcbiAgICAgICAgdGhpcy5yZXF1ZXN0SG9va3MgPSB0aGlzLmZpeHR1cmUucmVxdWVzdEhvb2tzLmxlbmd0aCA/IEFycmF5LmZyb20odGhpcy5maXh0dXJlLnJlcXVlc3RIb29rcykgOiBbXTtcblxuICAgICAgICByZXR1cm4gdGhpcy5hcGlPcmlnaW47XG4gICAgfVxuXG4gICAgX2FkZCAobmFtZSwgZm4pIHtcbiAgICAgICAgYXNzZXJ0VHlwZShpcy5zdHJpbmcsICdhcGlPcmlnaW4nLCAnVGhlIHRlc3QgbmFtZScsIG5hbWUpO1xuICAgICAgICBhc3NlcnRUeXBlKGlzLmZ1bmN0aW9uLCAnYXBpT3JpZ2luJywgJ1RoZSB0ZXN0IGJvZHknLCBmbik7XG5cbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5mbiAgID0gd3JhcFRlc3RGdW5jdGlvbihmbik7XG5cbiAgICAgICAgaWYgKHRoaXMudGVzdEZpbGUuY29sbGVjdGVkVGVzdHMuaW5kZXhPZih0aGlzKSA8IDApXG4gICAgICAgICAgICB0aGlzLnRlc3RGaWxlLmNvbGxlY3RlZFRlc3RzLnB1c2godGhpcyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXBpT3JpZ2luO1xuICAgIH1cblxuICAgIF9iZWZvcmUkIChmbikge1xuICAgICAgICBhc3NlcnRUeXBlKGlzLmZ1bmN0aW9uLCAnYmVmb3JlJywgJ3Rlc3QuYmVmb3JlIGhvb2snLCBmbik7XG5cbiAgICAgICAgdGhpcy5iZWZvcmVGbiA9IHdyYXBUZXN0RnVuY3Rpb24oZm4pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmFwaU9yaWdpbjtcbiAgICB9XG5cbiAgICBfYWZ0ZXIkIChmbikge1xuICAgICAgICBhc3NlcnRUeXBlKGlzLmZ1bmN0aW9uLCAnYWZ0ZXInLCAndGVzdC5hZnRlciBob29rJywgZm4pO1xuXG4gICAgICAgIHRoaXMuYWZ0ZXJGbiA9IHdyYXBUZXN0RnVuY3Rpb24oZm4pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmFwaU9yaWdpbjtcbiAgICB9XG5cbiAgICBfcmVxdWVzdEhvb2tzJCAoLi4uaG9va3MpIHtcbiAgICAgICAgaG9va3MgPSBmbGF0dGVuKGhvb2tzKTtcblxuICAgICAgICBhc3NlcnRSZXF1ZXN0SG9va1R5cGUoaG9va3MpO1xuXG4gICAgICAgIHRoaXMucmVxdWVzdEhvb2tzID0gdW5pb24odGhpcy5yZXF1ZXN0SG9va3MsIGhvb2tzKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5hcGlPcmlnaW47XG4gICAgfVxufVxuXG5UZXN0aW5nVW5pdC5fbWFrZUFQSUxpc3RGb3JDaGlsZENsYXNzKFRlc3QpO1xuIl19 diff --git a/lib/api/structure/testing-unit.js b/lib/api/structure/testing-unit.js new file mode 100644 index 00000000..c376289b --- /dev/null +++ b/lib/api/structure/testing-unit.js @@ -0,0 +1,117 @@ +'use strict'; + +exports.__esModule = true; + +var _keys = require('babel-runtime/core-js/object/keys'); + +var _keys2 = _interopRequireDefault(_keys); + +var _testPageUrl = require('../test-page-url'); + +var _handleTagArgs = require('../../utils/handle-tag-args'); + +var _handleTagArgs2 = _interopRequireDefault(_handleTagArgs); + +var _delegatedApi = require('../../utils/delegated-api'); + +var _typeAssertions = require('../../errors/runtime/type-assertions'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class TestingUnit { + constructor(testFile, unitTypeName) { + this.testFile = testFile; + this.unitTypeName = unitTypeName; + + this.name = null; + this.pageUrl = null; + this.authCredentials = null; + this.meta = {}; + this.only = false; + this.skip = false; + + this.disablePageReloads = void 0; + + const unit = this; + + this.apiOrigin = function apiOrigin(...args) { + return unit._add(...args); + }; + + (0, _delegatedApi.delegateAPI)(this.apiOrigin, this.constructor.API_LIST, { handler: this }); + } + + _add() { + throw new Error('Not implemented'); + } + + _only$getter() { + this.only = true; + + return this.apiOrigin; + } + + _skip$getter() { + this.skip = true; + + return this.apiOrigin; + } + + _disablePageReloads$getter() { + this.disablePageReloads = true; + + return this.apiOrigin; + } + + _enablePageReloads$getter() { + this.disablePageReloads = false; + + return this.apiOrigin; + } + + _page$(url, ...rest) { + this.pageUrl = (0, _handleTagArgs2.default)(url, rest); + + (0, _typeAssertions.assertType)(_typeAssertions.is.string, 'page', 'The page URL', this.pageUrl); + + (0, _testPageUrl.assertUrl)(this.pageUrl, 'page'); + + this.pageUrl = (0, _testPageUrl.resolvePageUrl)(this.pageUrl, this.testFile.filename); + + return this.apiOrigin; + } + + _httpAuth$(credentials) { + (0, _typeAssertions.assertType)(_typeAssertions.is.nonNullObject, 'httpAuth', 'credentials', credentials); + (0, _typeAssertions.assertType)(_typeAssertions.is.string, 'httpAuth', 'credentials.username', credentials.username); + (0, _typeAssertions.assertType)(_typeAssertions.is.string, 'httpAuth', 'credentials.password', credentials.password); + + if (credentials.domain) (0, _typeAssertions.assertType)(_typeAssertions.is.string, 'httpAuth', 'credentials.domain', credentials.domain); + if (credentials.workstation) (0, _typeAssertions.assertType)(_typeAssertions.is.string, 'httpAuth', 'credentials.workstation', credentials.workstation); + + this.authCredentials = credentials; + + return this.apiOrigin; + } + + _meta$(...args) { + (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.nonNullObject], 'meta', `${this.unitTypeName}.meta`, args[0]); + + const data = typeof args[0] === 'string' ? { [args[0]]: args[1] } : args[0]; + + (0, _keys2.default)(data).forEach(key => { + this.meta[key] = data[key]; + }); + + return this.apiOrigin; + } + + static _makeAPIListForChildClass(ChildClass) { + ChildClass.API_LIST = TestingUnit.API_LIST.concat((0, _delegatedApi.getDelegatedAPIList)(ChildClass.prototype)); + } +} + +exports.default = TestingUnit; +TestingUnit.API_LIST = (0, _delegatedApi.getDelegatedAPIList)(TestingUnit.prototype); +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvc3RydWN0dXJlL3Rlc3RpbmctdW5pdC5qcyJdLCJuYW1lcyI6WyJUZXN0aW5nVW5pdCIsImNvbnN0cnVjdG9yIiwidGVzdEZpbGUiLCJ1bml0VHlwZU5hbWUiLCJuYW1lIiwicGFnZVVybCIsImF1dGhDcmVkZW50aWFscyIsIm1ldGEiLCJvbmx5Iiwic2tpcCIsImRpc2FibGVQYWdlUmVsb2FkcyIsInVuaXQiLCJhcGlPcmlnaW4iLCJhcmdzIiwiX2FkZCIsIkFQSV9MSVNUIiwiaGFuZGxlciIsIkVycm9yIiwiX29ubHkkZ2V0dGVyIiwiX3NraXAkZ2V0dGVyIiwiX2Rpc2FibGVQYWdlUmVsb2FkcyRnZXR0ZXIiLCJfZW5hYmxlUGFnZVJlbG9hZHMkZ2V0dGVyIiwiX3BhZ2UkIiwidXJsIiwicmVzdCIsImlzIiwic3RyaW5nIiwiZmlsZW5hbWUiLCJfaHR0cEF1dGgkIiwiY3JlZGVudGlhbHMiLCJub25OdWxsT2JqZWN0IiwidXNlcm5hbWUiLCJwYXNzd29yZCIsImRvbWFpbiIsIndvcmtzdGF0aW9uIiwiX21ldGEkIiwiZGF0YSIsImZvckVhY2giLCJrZXkiLCJfbWFrZUFQSUxpc3RGb3JDaGlsZENsYXNzIiwiQ2hpbGRDbGFzcyIsImNvbmNhdCIsInByb3RvdHlwZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQTs7QUFDQTs7OztBQUNBOztBQUNBOzs7O0FBR2UsTUFBTUEsV0FBTixDQUFrQjtBQUM3QkMsZ0JBQWFDLFFBQWIsRUFBdUJDLFlBQXZCLEVBQXFDO0FBQ2pDLGFBQUtELFFBQUwsR0FBb0JBLFFBQXBCO0FBQ0EsYUFBS0MsWUFBTCxHQUFvQkEsWUFBcEI7O0FBRUEsYUFBS0MsSUFBTCxHQUF1QixJQUF2QjtBQUNBLGFBQUtDLE9BQUwsR0FBdUIsSUFBdkI7QUFDQSxhQUFLQyxlQUFMLEdBQXVCLElBQXZCO0FBQ0EsYUFBS0MsSUFBTCxHQUF1QixFQUF2QjtBQUNBLGFBQUtDLElBQUwsR0FBdUIsS0FBdkI7QUFD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RCxXQUFPMkIseUJBQVAsQ0FBa0NDLFVBQWxDLEVBQThDO0FBQzFDQSxtQkFBV3pCLFFBQVgsR0FBc0JmLFlBQVllLFFBQVosQ0FBcUIwQixNQUFyQixDQUE0Qix1Q0FBb0JELFdBQVdFLFNBQS9CLENBQTVCLENBQXRCO0FBQ0g7QUE1RjRCOztrQkFBWjFDLFc7QUErRnJCQSxZQUFZZSxRQUFaLEdBQXVCLHVDQUFvQmYsWUFBWTBDLFNBQWhDLENBQXZCIiwiZmlsZSI6ImFwaS9zdHJ1Y3R1cmUvdGVzdGluZy11bml0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYXNzZXJ0VXJsLCByZXNvbHZlUGFnZVVybCB9IGZyb20gJy4uL3Rlc3QtcGFnZS11cmwnO1xuaW1wb3J0IGhhbmRsZVRhZ0FyZ3MgZnJvbSAnLi4vLi4vdXRpbHMvaGFuZGxlLXRhZy1hcmdzJztcbmltcG9ydCB7IGRlbGVnYXRlQVBJLCBnZXREZWxlZ2F0ZWRBUElMaXN0IH0gZnJvbSAnLi4vLi4vdXRpbHMvZGVsZWdhdGVkLWFwaSc7XG5pbXBvcnQgeyBhc3NlcnRUeXBlLCBpcyB9IGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lL3R5cGUtYXNzZXJ0aW9ucyc7XG5cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGVzdGluZ1VuaXQge1xuICAgIGNvbnN0cnVjdG9yICh0ZXN0RmlsZSwgdW5pdFR5cGVOYW1lKSB7XG4gICAgICAgIHRoaXMudGVzdEZpbGUgICAgID0gdGVzdEZpbGU7XG4gICAgICAgIHRoaXMudW5pdFR5cGVOYW1lID0gdW5pdFR5cGVOYW1lO1xuXG4gICAgICAgIHRoaXMubmFtZSAgICAgICAgICAgID0gbnVsbDtcbiAgICAgICAgdGhpcy5wYWdlVXJsICAgICAgICAgPSBudWxsO1xuICAgICAgICB0aGlzLmF1dGhDcmVkZW50aWFscyA9IG51bGw7XG4gICAgICAgIHRoaXMubWV0YSAgICAgICAgICAgID0ge307XG4gICAgICAgIHRoaXMub25seSAgICAgICAgICAgID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2tpcCAgICAgICAgICAgID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5kaXNhYmxlUGFnZVJlbG9hZHMgPSB2b2lkIDA7XG5cbiAgICAgICAgY29uc3QgdW5pdCA9IHRoaXM7XG5cbiAgICAgICAgdGhpcy5hcGlPcmlnaW4gPSBmdW5jdGlvbiBhcGlPcmlnaW4gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgIHJldHVybiB1bml0Ll9hZGQoLi4uYXJncyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZGVsZWdhdGVBUEkodGhpcy5hcGlPcmlnaW4sIHRoaXMuY29uc3RydWN0b3IuQVBJX0xJU1QsIHsgaGFuZGxlcjogdGhpcyB9KTtcbiAgICB9XG5cbiAgICBfYWRkICgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9XG5cbiAgICBfb25seSRnZXR0ZXIgKCkge1xuICAgICAgICB0aGlzLm9ubHkgPSB0cnVlO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmFwaU9yaWdpbjtcbiAgICB9XG5cbiAgICBfc2tpcCRnZXR0ZXIgKCkge1xuICAgICAgICB0aGlzLnNraXAgPSB0cnVlO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmFwaU9yaWdpbjtcbiAgICB9XG5cbiAgICBfZGlzYWJsZVBhZ2VSZWxvYWRzJGdldHRlciAoKSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZVBhZ2VSZWxvYWRzID0gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gdGhpcy5hcGlPcmlnaW47XG4gICAgfVxuXG4gICAgX2VuYWJsZVBhZ2VSZWxvYWRzJGdldHRlciAoKSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZVBhZ2VSZWxvYWRzID0gZmFsc2U7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXBpT3JpZ2luO1xuICAgIH1cblxuICAgIF9wYWdlJCAodXJsLCAuLi5yZXN0KSB7XG4gICAgICAgIHRoaXMucGFnZVVybCA9IGhhbmRsZVRhZ0FyZ3ModXJsLCByZXN0KTtcblxuICAgICAgICBhc3NlcnRUeXBlKGlzLnN0cmluZywgJ3BhZ2UnLCAnVGhlIHBhZ2UgVVJMJywgdGhpcy5wYWdlVXJsKTtcblxuICAgICAgICBhc3NlcnRVcmwodGhpcy5wYWdlVXJsLCAncGFnZScpO1xuXG4gICAgICAgIHRoaXMucGFnZVVybCA9IHJlc29sdmVQYWdlVXJsKHRoaXMucGFnZVVybCwgdGhpcy50ZXN0RmlsZS5maWxlbmFtZSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuYXBpT3JpZ2luO1xuICAgIH1cblxuICAgIF9odHRwQXV0aCQgKGNyZWRlbnRpYWxzKSB7XG4gICAgICAgIGFzc2VydFR5cGUoaXMubm9uTnVsbE9iamVjdCwgJ2h0dHBBdXRoJywgJ2NyZWRlbnRpYWxzJywgY3JlZGVudGlhbHMpO1xuICAgICAgICBhc3NlcnRUeXBlKGlzLnN0cmluZywgJ2h0dHBBdXRoJywgJ2NyZWRlbnRpYWxzLnVzZXJuYW1lJywgY3JlZGVudGlhbHMudXNlcm5hbWUpO1xuICAgICAgICBhc3NlcnRUeXBlKGlzLnN0cmluZywgJ2h0dHBBdXRoJywgJ2NyZWRlbnRpYWxzLnBhc3N3b3JkJywgY3JlZGVudGlhbHMucGFzc3dvcmQpO1xuXG4gICAgICAgIGlmIChjcmVkZW50aWFscy5kb21haW4pXG4gICAgICAgICAgICBhc3NlcnRUeXBlKGlzLnN0cmluZywgJ2h0dHBBdXRoJywgJ2NyZWRlbnRpYWxzLmRvbWFpbicsIGNyZWRlbnRpYWxzLmRvbWFpbik7XG4gICAgICAgIGlmIChjcmVkZW50aWFscy53b3Jrc3RhdGlvbilcbiAgICAgICAgICAgIGFzc2VydFR5cGUoaXMuc3RyaW5nLCAnaHR0cEF1dGgnLCAnY3JlZGVudGlhbHMud29ya3N0YXRpb24nLCBjcmVkZW50aWFscy53b3Jrc3RhdGlvbik7XG5cbiAgICAgICAgdGhpcy5hdXRoQ3JlZGVudGlhbHMgPSBjcmVkZW50aWFscztcblxuICAgICAgICByZXR1cm4gdGhpcy5hcGlPcmlnaW47XG4gICAgfVxuXG4gICAgX21ldGEkICguLi5hcmdzKSB7XG4gICAgICAgIGFzc2VydFR5cGUoW2lzLnN0cmluZywgaXMubm9uTnVsbE9iamVjdF0sICdtZXRhJywgYCR7dGhpcy51bml0VHlwZU5hbWV9Lm1ldGFgLCBhcmdzWzBdKTtcblxuICAgICAgICBjb25zdCBkYXRhID0gdHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnID8geyBbYXJnc1swXV06IGFyZ3NbMV0gfSA6IGFyZ3NbMF07XG5cbiAgICAgICAgT2JqZWN0LmtleXMoZGF0YSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgdGhpcy5tZXRhW2tleV0gPSBkYXRhW2tleV07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmFwaU9yaWdpbjtcbiAgICB9XG5cbiAgICBzdGF0aWMgX21ha2VBUElMaXN0Rm9yQ2hpbGRDbGFzcyAoQ2hpbGRDbGFzcykge1xuICAgICAgICBDaGlsZENsYXNzLkFQSV9MSVNUID0gVGVzdGluZ1VuaXQuQVBJX0xJU1QuY29uY2F0KGdldERlbGVnYXRlZEFQSUxpc3QoQ2hpbGRDbGFzcy5wcm90b3R5cGUpKTtcbiAgICB9XG59XG5cblRlc3RpbmdVbml0LkFQSV9MSVNUID0gZ2V0RGVsZWdhdGVkQVBJTGlzdChUZXN0aW5nVW5pdC5wcm90b3R5cGUpO1xuXG5cbiJdfQ== diff --git a/lib/api/test-controller/assertion.js b/lib/api/test-controller/assertion.js new file mode 100644 index 00000000..29322d3b --- /dev/null +++ b/lib/api/test-controller/assertion.js @@ -0,0 +1,110 @@ +'use strict'; + +exports.__esModule = true; + +var _assertion = require('../../test-run/commands/assertion'); + +var _assertion2 = _interopRequireDefault(_assertion); + +var _testRun = require('../../errors/test-run'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Assertion { + constructor(actual, testController, callsite) { + this.testController = testController; + this.actual = actual; + this.callsite = callsite; + } + + then() { + throw new _testRun.AssertionWithoutMethodCallError(this.callsite); + } + + _enqueueAssertion(apiMethodName, assertionArgs) { + let options = assertionArgs.opts || {}; + let message = assertionArgs.message; + + if (typeof message === 'object') { + options = assertionArgs.message; + message = void 0; + } + + return this.testController._enqueueCommand(apiMethodName, _assertion2.default, { + assertionType: apiMethodName, + actual: this.actual, + expected: assertionArgs.expected, + expected2: assertionArgs.expected2, + message: message, + options: { timeout: options.timeout, allowUnawaitedPromise: options.allowUnawaitedPromise } + }); + } + + eql(expected, message, opts) { + return this._enqueueAssertion('eql', { expected, message, opts }); + } + + notEql(expected, message, opts) { + return this._enqueueAssertion('notEql', { expected, message, opts }); + } + + ok(message, opts) { + return this._enqueueAssertion('ok', { message, opts }); + } + + notOk(message, opts) { + return this._enqueueAssertion('notOk', { message, opts }); + } + + contains(expected, message, opts) { + return this._enqueueAssertion('contains', { expected, message, opts }); + } + + notContains(expected, message, opts) { + return this._enqueueAssertion('notContains', { expected, message, opts }); + } + + typeOf(expected, message, opts) { + return this._enqueueAssertion('typeOf', { expected, message, opts }); + } + + notTypeOf(expected, message, opts) { + return this._enqueueAssertion('notTypeOf', { expected, message, opts }); + } + + gt(expected, message, opts) { + return this._enqueueAssertion('gt', { expected, message, opts }); + } + + gte(expected, message, opts) { + return this._enqueueAssertion('gte', { expected, message, opts }); + } + + lt(expected, message, opts) { + return this._enqueueAssertion('lt', { expected, message, opts }); + } + + lte(expected, message, opts) { + return this._enqueueAssertion('lte', { expected, message, opts }); + } + + within(start, finish, message, opts) { + // NOTE: `within` is not available in Chai `assert` interface. + return this._enqueueAssertion('within', { expected: start, expected2: finish, message, opts }); + } + + notWithin(start, finish, message, opts) { + return this._enqueueAssertion('notWithin', { expected: start, expected2: finish, message, opts }); + } + + match(expected, message, opts) { + return this._enqueueAssertion('match', { expected, message, opts }); + } + + notMatch(expected, message, opts) { + return this._enqueueAssertion('notMatch', { expected, message, opts }); + } +} +exports.default = Assertion; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvdGVzdC1jb250cm9sbGVyL2Fzc2VydGlvbi5qcyJdLCJuYW1lcyI6WyJBc3NlcnRpb24iLCJjb25zdHJ1Y3RvciIsImFjdHVhbCIsInRlc3RDb250cm9sbGVyIiwiY2FsbHNpdGUiLCJ0aGVuIiwiQXNzZXJ0aW9uV2l0aG91dE1ldGhvZENhbGxFcnJvciIsIl9lbnF1ZXVlQXNzZXJ0aW9uIiwiYXBpTWV0aG9kTmFtZSIsImFzc2VydGlvbkFyZ3MiLCJvcHRpb25zIiwib3B0cyIsIm1lc3NhZ2UiLCJfZW5xdWV1ZUNvbW1hbmQiLCJBc3NlcnRpb25Db21tYW5kIiwiYXNzZXJ0aW9uVHlwZSIsImV4cGVjdGVkIiwiZXhwZWN0ZWQyIiwidGltZW91dCIsImFsbG93VW5hd2FpdGVkUHJvbWlzZSIsImVxbCIsIm5vdEVxbCIsIm9rIiwibm90T2siLCJjb250YWlucyIsIm5vdENvbnRhaW5zIiwidHlwZU9mIiwibm90VHlwZU9mIiwiZ3QiLCJndGUiLCJsdCIsImx0ZSIsIndpdGhpbiIsInN0YXJ0IiwiZmluaXNoIiwibm90V2l0aGluIiwibWF0Y2giLCJub3RNYXRjaCJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBOzs7O0FBQ0E7Ozs7QUFFZSxNQUFNQSxTQUFOLENBQWdCO0FBQzNCQyxnQkFBYUMsTUFBYixFQUFxQkMsY0FBckIsRUFBcUNDLFFBQXJDLEVBQStDO0FBQzNDLGFBQUtELGNBQUwsR0FBc0JBLGNBQXRCO0FBQ0EsYUFBS0QsTUFBTCxHQUFzQkEsTUFBdEI7QUFDQSxhQUFLRSxRQUFMLEdBQXNCQSxRQUF0QjtBQUNIOztBQUVEQyxXQUFRO0FBQ0osY0FBTSxJQUFJQyx3Q0FBSixDQUFvQyxLQUFLRixRQUF6QyxDQUFOO0FBQ0g7O0FBRURHLHNCQUFtQkMsYUFBbkIsRUFBa0NDLGFBQWxDLEVBQWlEO0FBQzdDLFlBQUlDLFVBQVVELGNBQWNFLElBQWQsSUFBc0IsRUFBcEM7QUFDQSxZQUFJQyxVQUFVSCxjQUFjRyxPQUE1Qjs7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ImFwaS90ZXN0LWNvbnRyb2xsZXIvYXNzZXJ0aW9uLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFzc2VydGlvbkNvbW1hbmQgZnJvbSAnLi4vLi4vdGVzdC1ydW4vY29tbWFuZHMvYXNzZXJ0aW9uJztcbmltcG9ydCB7IEFzc2VydGlvbldpdGhvdXRNZXRob2RDYWxsRXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvcnMvdGVzdC1ydW4nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBc3NlcnRpb24ge1xuICAgIGNvbnN0cnVjdG9yIChhY3R1YWwsIHRlc3RDb250cm9sbGVyLCBjYWxsc2l0ZSkge1xuICAgICAgICB0aGlzLnRlc3RDb250cm9sbGVyID0gdGVzdENvbnRyb2xsZXI7XG4gICAgICAgIHRoaXMuYWN0dWFsICAgICAgICAgPSBhY3R1YWw7XG4gICAgICAgIHRoaXMuY2FsbHNpdGUgICAgICAgPSBjYWxsc2l0ZTtcbiAgICB9XG5cbiAgICB0aGVuICgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbldpdGhvdXRNZXRob2RDYWxsRXJyb3IodGhpcy5jYWxsc2l0ZSk7XG4gICAgfVxuXG4gICAgX2VucXVldWVBc3NlcnRpb24gKGFwaU1ldGhvZE5hbWUsIGFzc2VydGlvbkFyZ3MpIHtcbiAgICAgICAgbGV0IG9wdGlvbnMgPSBhc3NlcnRpb25BcmdzLm9wdHMgfHwge307XG4gICAgICAgIGxldCBtZXNzYWdlID0gYXNzZXJ0aW9uQXJncy5tZXNzYWdlO1xuXG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBhc3NlcnRpb25BcmdzLm1lc3NhZ2U7XG4gICAgICAgICAgICBtZXNzYWdlID0gdm9pZCAwO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdENvbnRyb2xsZXIuX2VucXVldWVDb21tYW5kKGFwaU1ldGhvZE5hbWUsIEFzc2VydGlvbkNvbW1hbmQsIHtcbiAgICAgICAgICAgIGFzc2VydGlvblR5cGU6IGFwaU1ldGhvZE5hbWUsXG4gICAgICAgICAgICBhY3R1YWw6ICAgICAgICB0aGlzLmFjdHVhbCxcbiAgICAgICAgICAgIGV4cGVjdGVkOiAgICAgIGFzc2VydGlvbkFyZ3MuZXhwZWN0ZWQsXG4gICAgICAgICAgICBleHBlY3RlZDI6ICAgICBhc3NlcnRpb25BcmdzLmV4cGVjdGVkMixcbiAgICAgICAgICAgIG1lc3NhZ2U6ICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgICBvcHRpb25zOiAgICAgICB7IHRpbWVvdXQ6IG9wdGlvbnMudGltZW91dCwgYWxsb3dVbmF3YWl0ZWRQcm9taXNlOiBvcHRpb25zLmFsbG93VW5hd2FpdGVkUHJvbWlzZSB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGVxbCAoZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVBc3NlcnRpb24oJ2VxbCcsIHsgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wdHMgfSk7XG4gICAgfVxuXG4gICAgbm90RXFsIChleHBlY3RlZCwgbWVzc2FnZSwgb3B0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUFzc2VydGlvbignbm90RXFsJywgeyBleHBlY3RlZCwgbWVzc2FnZSwgb3B0cyB9KTtcbiAgICB9XG5cbiAgICBvayAobWVzc2FnZSwgb3B0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUFzc2VydGlvbignb2snLCB7IG1lc3NhZ2UsIG9wdHMgfSk7XG4gICAgfVxuXG4gICAgbm90T2sgKG1lc3NhZ2UsIG9wdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVBc3NlcnRpb24oJ25vdE9rJywgeyBtZXNzYWdlLCBvcHRzIH0pO1xuICAgIH1cblxuICAgIGNvbnRhaW5zIChleHBlY3RlZCwgbWVzc2FnZSwgb3B0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUFzc2VydGlvbignY29udGFpbnMnLCB7IGV4cGVjdGVkLCBtZXNzYWdlLCBvcHRzIH0pO1xuICAgIH1cblxuICAgIG5vdENvbnRhaW5zIChleHBlY3RlZCwgbWVzc2FnZSwgb3B0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUFzc2VydGlvbignbm90Q29udGFpbnMnLCB7IGV4cGVjdGVkLCBtZXNzYWdlLCBvcHRzIH0pO1xuICAgIH1cblxuICAgIHR5cGVPZiAoZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVBc3NlcnRpb24oJ3R5cGVPZicsIHsgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wdHMgfSk7XG4gICAgfVxuXG4gICAgbm90VHlwZU9mIChleHBlY3RlZCwgbWVzc2FnZSwgb3B0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUFzc2VydGlvbignbm90VHlwZU9mJywgeyBleHBlY3RlZCwgbWVzc2FnZSwgb3B0cyB9KTtcbiAgICB9XG5cbiAgICBndCAoZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVBc3NlcnRpb24oJ2d0JywgeyBleHBlY3RlZCwgbWVzc2FnZSwgb3B0cyB9KTtcbiAgICB9XG5cbiAgICBndGUgKGV4cGVjdGVkLCBtZXNzYWdlLCBvcHRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQXNzZXJ0aW9uKCdndGUnLCB7IGV4cGVjdGVkLCBtZXNzYWdlLCBvcHRzIH0pO1xuICAgIH1cblxuICAgIGx0IChleHBlY3RlZCwgbWVzc2FnZSwgb3B0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUFzc2VydGlvbignbHQnLCB7IGV4cGVjdGVkLCBtZXNzYWdlLCBvcHRzIH0pO1xuICAgIH1cblxuICAgIGx0ZSAoZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVBc3NlcnRpb24oJ2x0ZScsIHsgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wdHMgfSk7XG4gICAgfVxuXG4gICAgd2l0aGluIChzdGFydCwgZmluaXNoLCBtZXNzYWdlLCBvcHRzKSB7XG4gICAgICAgIC8vIE5PVEU6IGB3aXRoaW5gIGlzIG5vdCBhdmFpbGFibGUgaW4gQ2hhaSBgYXNzZXJ0YCBpbnRlcmZhY2UuXG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQXNzZXJ0aW9uKCd3aXRoaW4nLCB7IGV4cGVjdGVkOiBzdGFydCwgZXhwZWN0ZWQyOiBmaW5pc2gsIG1lc3NhZ2UsIG9wdHMgfSk7XG4gICAgfVxuXG4gICAgbm90V2l0aGluIChzdGFydCwgZmluaXNoLCBtZXNzYWdlLCBvcHRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQXNzZXJ0aW9uKCdub3RXaXRoaW4nLCB7IGV4cGVjdGVkOiBzdGFydCwgZXhwZWN0ZWQyOiBmaW5pc2gsIG1lc3NhZ2UsIG9wdHMgfSk7XG4gICAgfVxuXG4gICAgbWF0Y2ggKGV4cGVjdGVkLCBtZXNzYWdlLCBvcHRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQXNzZXJ0aW9uKCdtYXRjaCcsIHsgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wdHMgfSk7XG4gICAgfVxuXG4gICAgbm90TWF0Y2ggKGV4cGVjdGVkLCBtZXNzYWdlLCBvcHRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQXNzZXJ0aW9uKCdub3RNYXRjaCcsIHsgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wdHMgfSk7XG4gICAgfVxufVxuIl19 diff --git a/lib/api/test-controller/index.js b/lib/api/test-controller/index.js new file mode 100644 index 00000000..a4be1a8b --- /dev/null +++ b/lib/api/test-controller/index.js @@ -0,0 +1,326 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _set = require('babel-runtime/core-js/set'); + +var _set2 = _interopRequireDefault(_set); + +var _pinkie = require('pinkie'); + +var _pinkie2 = _interopRequireDefault(_pinkie); + +var _lodash = require('lodash'); + +var _getCallsite = require('../../errors/get-callsite'); + +var _clientFunctionBuilder = require('../../client-functions/client-function-builder'); + +var _clientFunctionBuilder2 = _interopRequireDefault(_clientFunctionBuilder); + +var _assertion = require('./assertion'); + +var _assertion2 = _interopRequireDefault(_assertion); + +var _delegatedApi = require('../../utils/delegated-api'); + +var _actions = require('../../test-run/commands/actions'); + +var _browserManipulation = require('../../test-run/commands/browser-manipulation'); + +var _observation = require('../../test-run/commands/observation'); + +var _assertType = require('../request-hooks/assert-type'); + +var _assertType2 = _interopRequireDefault(_assertType); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const originalThen = _pinkie2.default.resolve().then; + +class TestController { + constructor(testRun) { + this.testRun = testRun; + this.executionChain = _pinkie2.default.resolve(); + this.callsitesWithoutAwait = new _set2.default(); + } + + // NOTE: we track missing `awaits` by exposing a special custom Promise to user code. + // Action or assertion is awaited if: + // a)someone used `await` so Promise's `then` function executed + // b)Promise chained by using one of the mixed-in controller methods + // + // In both scenarios, we check that callsite that produced Promise is equal to the one + // that is currently missing await. This is required to workaround scenarios like this: + // + // var t2 = t.click('#btn1'); // <-- stores new callsiteWithoutAwait + // await t2; // <-- callsiteWithoutAwait = null + // t.click('#btn2'); // <-- stores new callsiteWithoutAwait + // await t2.click('#btn3'); // <-- without check it will set callsiteWithoutAwait = null, so we will lost tracking + _createExtendedPromise(promise, callsite) { + const extendedPromise = promise.then(_lodash.identity); + const markCallsiteAwaited = () => this.callsitesWithoutAwait.delete(callsite); + + extendedPromise.then = function () { + markCallsiteAwaited(); + + return originalThen.apply(this, arguments); + }; + + (0, _delegatedApi.delegateAPI)(extendedPromise, TestController.API_LIST, { + handler: this, + proxyMethod: markCallsiteAwaited + }); + + return extendedPromise; + } + + _enqueueTask(apiMethodName, createTaskExecutor) { + const callsite = (0, _getCallsite.getCallsiteForMethod)(apiMethodName); + const executor = createTaskExecutor(callsite); + + this.executionChain.then = originalThen; + this.executionChain = this.executionChain.then(executor); + + this.callsitesWithoutAwait.add(callsite); + + this.executionChain = this._createExtendedPromise(this.executionChain, callsite); + + return this.executionChain; + } + + _enqueueCommand(apiMethodName, CmdCtor, cmdArgs) { + var _this = this; + + return this._enqueueTask(apiMethodName, callsite => { + let command = null; + + try { + command = new CmdCtor(cmdArgs, this.testRun); + } catch (err) { + err.callsite = callsite; + throw err; + } + + if (this.testRun.recordScreenCapture && apiMethodName !== 'takeScreenshot') { + return () => this.testRun.executeCommand(command, callsite).then((0, _asyncToGenerator3.default)(function* () { + if (_this.testRun.recordScreenCapture && apiMethodName !== 'takeScreenshot') { + const date = new Date(); + const dateFolder = `${date.getMonth() + 1}_${date.getDate()}_${date.getFullYear()}`; + const sessionId = _this.testRun.session.id; + const testName = _this.testRun.test.name; + const path = `${dateFolder}/${sessionId}/${Date.now()}_${testName}_${apiMethodName}_auto.png`; + + yield _this.testRun.executeCommand(new _browserManipulation.TakeScreenshotCommand({ path: path })); + } + })); + } + + return () => this.testRun.executeCommand(command, callsite); + }); + } + + // API implementation + // We need implementation methods to obtain correct callsites. If we use plain API + // methods in chained wrappers then we will have callsite for the wrapped method + // in this file instead of chained method callsite in user code. + _ctx$getter() { + return this.testRun.ctx; + } + + _ctx$setter(val) { + this.testRun.ctx = val; + + return this.testRun.ctx; + } + + _fixtureCtx$getter() { + return this.testRun.fixtureCtx; + } + + _click$(selector, options) { + return this._enqueueCommand('click', _actions.ClickCommand, { selector, options }); + } + + _rightClick$(selector, options) { + return this._enqueueCommand('rightClick', _actions.RightClickCommand, { selector, options }); + } + + _doubleClick$(selector, options) { + return this._enqueueCommand('doubleClick', _actions.DoubleClickCommand, { selector, options }); + } + + _hover$(selector, options) { + return this._enqueueCommand('hover', _actions.HoverCommand, { selector, options }); + } + + _drag$(selector, dragOffsetX, dragOffsetY, options) { + return this._enqueueCommand('drag', _actions.DragCommand, { selector, dragOffsetX, dragOffsetY, options }); + } + + _dragToElement$(selector, destinationSelector, options) { + return this._enqueueCommand('dragToElement', _actions.DragToElementCommand, { selector, destinationSelector, options }); + } + + _typeText$(selector, text, options) { + return this._enqueueCommand('typeText', _actions.TypeTextCommand, { selector, text, options }); + } + + _selectText$(selector, startPos, endPos, options) { + return this._enqueueCommand('selectText', _actions.SelectTextCommand, { selector, startPos, endPos, options }); + } + + _selectTextAreaContent$(selector, startLine, startPos, endLine, endPos, options) { + return this._enqueueCommand('selectTextAreaContent', _actions.SelectTextAreaContentCommand, { + selector, + startLine, + startPos, + endLine, + endPos, + options + }); + } + + _selectEditableContent$(startSelector, endSelector, options) { + return this._enqueueCommand('selectEditableContent', _actions.SelectEditableContentCommand, { + startSelector, + endSelector, + options + }); + } + + _pressKey$(keys, options) { + return this._enqueueCommand('pressKey', _actions.PressKeyCommand, { keys, options }); + } + + _wait$(timeout) { + return this._enqueueCommand('wait', _observation.WaitCommand, { timeout }); + } + + _navigateTo$(url) { + return this._enqueueCommand('navigateTo', _actions.NavigateToCommand, { url }); + } + + _setFilesToUpload$(selector, filePath) { + return this._enqueueCommand('setFilesToUpload', _actions.SetFilesToUploadCommand, { selector, filePath }); + } + + _clearUpload$(selector) { + return this._enqueueCommand('clearUpload', _actions.ClearUploadCommand, { selector }); + } + + _takeScreenshot$(path) { + return this._enqueueCommand('takeScreenshot', _browserManipulation.TakeScreenshotCommand, { path }); + } + + _takeElementScreenshot$(selector, ...args) { + const commandArgs = { selector }; + + if (args[1]) { + commandArgs.path = args[0]; + commandArgs.options = args[1]; + } else if (typeof args[0] === 'object') commandArgs.options = args[0];else commandArgs.path = args[0]; + + return this._enqueueCommand('takeElementScreenshot', _browserManipulation.TakeElementScreenshotCommand, commandArgs); + } + + _resizeWindow$(width, height) { + return this._enqueueCommand('resizeWindow', _browserManipulation.ResizeWindowCommand, { width, height }); + } + + _resizeWindowToFitDevice$(device, options) { + return this._enqueueCommand('resizeWindowToFitDevice', _browserManipulation.ResizeWindowToFitDeviceCommand, { device, options }); + } + + _maximizeWindow$() { + return this._enqueueCommand('maximizeWindow', _browserManipulation.MaximizeWindowCommand); + } + + _switchToIframe$(selector) { + return this._enqueueCommand('switchToIframe', _actions.SwitchToIframeCommand, { selector }); + } + + _switchToMainWindow$() { + return this._enqueueCommand('switchToMainWindow', _actions.SwitchToMainWindowCommand); + } + + _eval$(fn, options) { + if (!(0, _lodash.isNil)(options)) options = (0, _lodash.assign)({}, options, { boundTestRun: this }); + + const builder = new _clientFunctionBuilder2.default(fn, options, { instantiation: 'eval', execution: 'eval' }); + const clientFn = builder.getFunction(); + + return clientFn(); + } + + _setNativeDialogHandler$(fn, options) { + return this._enqueueCommand('setNativeDialogHandler', _actions.SetNativeDialogHandlerCommand, { + dialogHandler: { fn, options } + }); + } + + _getNativeDialogHistory$() { + const callsite = (0, _getCallsite.getCallsiteForMethod)('getNativeDialogHistory'); + + return this.testRun.executeCommand(new _actions.GetNativeDialogHistoryCommand(), callsite); + } + + _getBrowserConsoleMessages$() { + const callsite = (0, _getCallsite.getCallsiteForMethod)('getBrowserConsoleMessages'); + + return this.testRun.executeCommand(new _actions.GetBrowserConsoleMessagesCommand(), callsite); + } + + _expect$(actual) { + const callsite = (0, _getCallsite.getCallsiteForMethod)('expect'); + + return new _assertion2.default(actual, this, callsite); + } + + _debug$() { + return this._enqueueCommand('debug', _observation.DebugCommand); + } + + _setTestSpeed$(speed) { + return this._enqueueCommand('setTestSpeed', _actions.SetTestSpeedCommand, { speed }); + } + + _setPageLoadTimeout$(duration) { + return this._enqueueCommand('setPageLoadTimeout', _actions.SetPageLoadTimeoutCommand, { duration }); + } + + _useRole$(role) { + return this._enqueueCommand('useRole', _actions.UseRoleCommand, { role }); + } + + _addRequestHooks$(...hooks) { + return this._enqueueTask('addRequestHooks', () => { + hooks = (0, _lodash.flattenDeep)(hooks); + + (0, _assertType2.default)(hooks); + + hooks.forEach(hook => this.testRun.addRequestHook(hook)); + }); + } + + _removeRequestHooks$(...hooks) { + return this._enqueueTask('removeRequestHooks', () => { + hooks = (0, _lodash.flattenDeep)(hooks); + + (0, _assertType2.default)(hooks); + + hooks.forEach(hook => this.testRun.removeRequestHook(hook)); + }); + } +} + +exports.default = TestController; +TestController.API_LIST = (0, _delegatedApi.getDelegatedAPIList)(TestController.prototype); + +(0, _delegatedApi.delegateAPI)(TestController.prototype, TestController.API_LIST, { useCurrentCtxAsHandler: true }); +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvdGVzdC1jb250cm9sbGVyL2luZGV4LmpzIl0sIm5hbWVzIjpbIm9yaWdpbmFsVGhlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsIlRlc3RDb250cm9sbGVyIiwiY29uc3RydWN0b3IiLCJ0ZXN0UnVuIiwiZXhlY3V0aW9uQ2hhaW4iLCJjYWxsc2l0ZXNXaXRob3V0QXdhaXQiLCJfY3JlYXRlRXh0ZW5kZWRQcm9taXNlIiwicHJvbWlzZSIsImNhbGxzaXRlIiwiZXh0ZW5kZWRQcm9taXNlIiwiaWRlbnRpdHkiLCJtYXJrQ2FsbHNpdGVBd2FpdGVkIiwiZGVsZXRlIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJBUElfTElTVCIsImhhbmRsZXIiLCJwcm94eU1ldGhvZCIsIl9lbnF1ZXVlVGFzayIsImFwaU1ldGhvZE5hbWUiLCJjcmVhdGVUYXNrRXhlY3V0b3IiLCJleGVjdXRvciIsImFkZCIsIl9lbnF1ZXVlQ29tbWFuZCIsIkNtZEN0b3IiLCJjbWRBcmdzIiwiY29tbWFuZCIsImVyciIsInJlY29yZFNjcmVlbkNhcHR1cmUiLCJleGVjdXRlQ29tbWFuZCIsImRhdGUiLCJEYXRlIiwiZGF0ZUZvbGRlciIsImdldE1vbnRoIiwiZ2V0RGF0ZSIsImdldEZ1bGxZZWFyIiwic2Vzc2lvbklkIiwic2Vzc2lvbiIsImlkIiwidGVzdE5hbWUiLCJ0ZXN0IiwibmFtZSIsInBhdGgiLCJub3ciLCJUYWtlU2NyZWVuc2hvdENvbW1hbmQiLCJfY3R4JGdldHRlciIsImN0eCIsIl9jdHgkc2V0dGVyIiwidmFsIiwiX2ZpeHR1cmVDdHgkZ2V0dGVyIiwiZml4dHVyZUN0eCIsIl9jbGljayQiLCJzZWxlY3RvciIsIm9wdGlvbnMiLCJDbGlja0NvbW1hbmQiLCJfcmlnaHRDbGljayQiLCJSaWdodENsaWNrQ29tbWFuZCIsIl9kb3VibGVDbGljayQiLCJEb3VibGVDbGlja0NvbW1hbmQiLCJfaG92ZXIkIiwiSG92ZXJDb21tYW5kIiwiX2RyYWckIiwiZHJhZ09mZnNldFgiLCJkcmFnT2Zmc2V0WSIsIkRyYWdDb21tYW5kIiwiX2RyYWdUb0VsZW1lbnQkIiwiZGVzdGluYXRpb25TZWxlY3RvciIsIkRyYWdUb0VsZW1lbnRDb21tYW5kIiwiX3R5cGVUZXh0JCIsInRleHQiLCJUeXBlVGV4dENvbW1hbmQiLCJfc2VsZWN0VGV4dCQiLCJzdGFydFBvcyIsImVuZFBvcyIsIlNlbGVjdFRleHRDb21tYW5kIiwiX3NlbGVjdFRleHRBcmVhQ29udGVudCQiLCJzdGFydExpbmUiLCJlbmRMaW5lIiwiU2VsZWN0VGV4dEFyZWFDb250ZW50Q29tbWFuZCIsIl9zZWxlY3RFZGl0YWJsZUNvbnRlbnQkIiwic3RhcnRTZWxlY3RvciIsImVuZFNlbGVjdG9yIiwiU2VsZWN0RWRpdGFibGVDb250ZW50Q29tbWFuZCIsIl9wcmVzc0tleSQiLCJrZXlzIiwiUHJlc3NLZXlDb21tYW5kIiwiX3dhaXQkIiwidGltZW91dCIsIldhaXRDb21tYW5kIiwiX25hdmlnYXRlVG8kIiwidXJsIiwiTmF2aWdhdGVUb0NvbW1hbmQiLCJfc2V0RmlsZXNUb1VwbG9hZCQiLCJmaWxlUGF0aCIsIlNldEZpbGVzVG9VcGxvYWRDb21tYW5kIiwiX2NsZWFyVXBsb2FkJCIsIkNsZWFyVXBsb2FkQ29tbWFuZCIsIl90YWtlU2NyZWVuc2hvdCQiLCJfdGFrZUVsZW1lbnRTY3JlZW5zaG90JCIsImFyZ3MiLCJjb21tYW5kQXJncyIsIlRha2VFbGVtZW50U2NyZWVuc2hvdENvbW1hbmQiLCJfcmVzaXplV2luZG93JCIsIndpZHRoIiwiaGVpZ2h0IiwiUmVzaXplV2luZG93Q29tbWFuZCIsIl9yZXNpemVXaW5kb3dUb0ZpdERldmljZSQiLCJkZXZpY2UiLCJSZXNpemVXaW5kb3dUb0ZpdERldmljZUNvbW1hbmQiLCJfbWF4aW1pemVXaW5kb3ckIiwiTWF4aW1pemVXaW5kb3dDb21tYW5kIiwiX3N3aXRjaFRvSWZyYW1lJCIsIlN3aXRjaFRvSWZyYW1lQ29tbWFuZCIsIl9zd2l0Y2hUb01haW5XaW5kb3ckIiwiU3dpdGNoVG9NYWluV2luZG93Q29tbWFuZCIsIl9ldmFsJCIsImZuIiwiYm91bmRUZXN0UnVuIiwiYnVpbGRlciIsIkNsaWVudEZ1bmN0aW9uQnVpbGRlciIsImluc3RhbnRpYXRpb24iLCJleGVjdXRpb24iLCJjbGllbnRGbiIsImdldEZ1bmN0aW9uIiwiX3NldE5hdGl2ZURpYWxvZ0hhbmRsZXIkIiwiU2V0TmF0aXZlRGlhbG9nSGFuZGxlckNvbW1hbmQiLCJkaWFsb2dIYW5kbGVyIiwiX2dldE5hdGl2ZURpYWxvZ0hpc3RvcnkkIiwiR2V0TmF0aXZlRGlhbG9nSGlzdG9yeUNvbW1hbmQiLCJfZ2V0QnJvd3NlckNvbnNvbGVNZXNzYWdlcyQiLCJHZXRCcm93c2VyQ29uc29sZU1lc3NhZ2VzQ29tbWFuZCIsIl9leHBlY3QkIiwiYWN0dWFsIiwiQXNzZXJ0aW9uIiwiX2RlYnVnJCIsIkRlYnVnQ29tbWFuZCIsIl9zZXRUZXN0U3BlZWQkIiwic3BlZWQiLCJTZXRUZXN0U3BlZWRDb21tYW5kIiwiX3NldFBhZ2VMb2FkVGltZW91dCQiLCJkdXJhdGlvbiIsIlNldFBhZ2VMb2FkVGltZW91dENvbW1hbmQiLCJfdXNlUm9sZSQiLCJyb2xlIiwiVXNlUm9sZUNvbW1hbmQiLCJfYWRkUmVxdWVzdEhvb2tzJCIsImhvb2tzIiwiZm9yRWFjaCIsImhvb2siLCJhZGRSZXF1ZXN0SG9vayIsIl9yZW1vdmVSZXF1ZXN0SG9va3MkIiwicmVtb3ZlUmVxdWVzdEhvb2siLCJwcm90b3R5cGUiLCJ1c2VDdXJyZW50Q3R4QXNIYW5kbGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQTs7OztBQUNBOztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7QUFFQTs7QUF5QkE7O0FBUUE7O0FBQ0E7Ozs7OztBQUVBLE1BQU1BLGVBQWVDLGlCQUFRQyxPQUFSLEdBQWtCQyxJQUF2Qzs7QUFFZSxNQUFNQyxjQUFOLENBQXFCO0FBQ2hDQyxnQkFBYUMsT0FBYixFQUFzQjtBQUNsQixhQUFLQSxPQUFMLEdBQTZC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a0JBQWZuSixjO0FBd1JyQkEsZUFBZWMsUUFBZixHQUEwQix1Q0FBb0JkLGVBQWV1SixTQUFuQyxDQUExQjs7QUFFQSwrQkFBWXZKLGVBQWV1SixTQUEzQixFQUFzQ3ZKLGVBQWVjLFFBQXJELEVBQStELEVBQUUwSSx3QkFBd0IsSUFBMUIsRUFBL0QiLCJmaWxlIjoiYXBpL3Rlc3QtY29udHJvbGxlci9pbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlIGZyb20gJ3BpbmtpZSc7XG5pbXBvcnQgeyBpZGVudGl0eSwgYXNzaWduLCBpc05pbCBhcyBpc051bGxPclVuZGVmaW5lZCwgZmxhdHRlbkRlZXAgYXMgZmxhdHRlbiB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBnZXRDYWxsc2l0ZUZvck1ldGhvZCB9IGZyb20gJy4uLy4uL2Vycm9ycy9nZXQtY2FsbHNpdGUnO1xuaW1wb3J0IENsaWVudEZ1bmN0aW9uQnVpbGRlciBmcm9tICcuLi8uLi9jbGllbnQtZnVuY3Rpb25zL2NsaWVudC1mdW5jdGlvbi1idWlsZGVyJztcbmltcG9ydCBBc3NlcnRpb24gZnJvbSAnLi9hc3NlcnRpb24nO1xuaW1wb3J0IHsgZ2V0RGVsZWdhdGVkQVBJTGlzdCwgZGVsZWdhdGVBUEkgfSBmcm9tICcuLi8uLi91dGlscy9kZWxlZ2F0ZWQtYXBpJztcblxuaW1wb3J0IHtcbiAgICBDbGlja0NvbW1hbmQsXG4gICAgUmlnaHRDbGlja0NvbW1hbmQsXG4gICAgRG91YmxlQ2xpY2tDb21tYW5kLFxuICAgIEhvdmVyQ29tbWFuZCxcbiAgICBEcmFnQ29tbWFuZCxcbiAgICBEcmFnVG9FbGVtZW50Q29tbWFuZCxcbiAgICBUeXBlVGV4dENvbW1hbmQsXG4gICAgU2VsZWN0VGV4dENvbW1hbmQsXG4gICAgU2VsZWN0VGV4dEFyZWFDb250ZW50Q29tbWFuZCxcbiAgICBTZWxlY3RFZGl0YWJsZUNvbnRlbnRDb21tYW5kLFxuICAgIFByZXNzS2V5Q29tbWFuZCxcbiAgICBOYXZpZ2F0ZVRvQ29tbWFuZCxcbiAgICBTZXRGaWxlc1RvVXBsb2FkQ29tbWFuZCxcbiAgICBDbGVhclVwbG9hZENvbW1hbmQsXG4gICAgU3dpdGNoVG9JZnJhbWVDb21tYW5kLFxuICAgIFN3aXRjaFRvTWFpbldpbmRvd0NvbW1hbmQsXG4gICAgU2V0TmF0aXZlRGlhbG9nSGFuZGxlckNvbW1hbmQsXG4gICAgR2V0TmF0aXZlRGlhbG9nSGlzdG9yeUNvbW1hbmQsXG4gICAgR2V0QnJvd3NlckNvbnNvbGVNZXNzYWdlc0NvbW1hbmQsXG4gICAgU2V0VGVzdFNwZWVkQ29tbWFuZCxcbiAgICBTZXRQYWdlTG9hZFRpbWVvdXRDb21tYW5kLFxuICAgIFVzZVJvbGVDb21tYW5kXG59IGZyb20gJy4uLy4uL3Rlc3QtcnVuL2NvbW1hbmRzL2FjdGlvbnMnO1xuXG5pbXBvcnQge1xuICAgIFRha2VTY3JlZW5zaG90Q29tbWFuZCxcbiAgICBUYWtlRWxlbWVudFNjcmVlbnNob3RDb21tYW5kLFxuICAgIFJlc2l6ZVdpbmRvd0NvbW1hbmQsXG4gICAgUmVzaXplV2luZG93VG9GaXREZXZpY2VDb21tYW5kLFxuICAgIE1heGltaXplV2luZG93Q29tbWFuZFxufSBmcm9tICcuLi8uLi90ZXN0LXJ1bi9jb21tYW5kcy9icm93c2VyLW1hbmlwdWxhdGlvbic7XG5cbmltcG9ydCB7IFdhaXRDb21tYW5kLCBEZWJ1Z0NvbW1hbmQgfSBmcm9tICcuLi8uLi90ZXN0LXJ1bi9jb21tYW5kcy9vYnNlcnZhdGlvbic7XG5pbXBvcnQgYXNzZXJ0UmVxdWVzdEhvb2tUeXBlIGZyb20gJy4uL3JlcXVlc3QtaG9va3MvYXNzZXJ0LXR5cGUnO1xuXG5jb25zdCBvcmlnaW5hbFRoZW4gPSBQcm9taXNlLnJlc29sdmUoKS50aGVuO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXN0Q29udHJvbGxlciB7XG4gICAgY29uc3RydWN0b3IgKHRlc3RSdW4pIHtcbiAgICAgICAgdGhpcy50ZXN0UnVuICAgICAgICAgICAgICAgPSB0ZXN0UnVuO1xuICAgICAgICB0aGlzLmV4ZWN1dGlvbkNoYWluICAgICAgICA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB0aGlzLmNhbGxzaXRlc1dpdGhvdXRBd2FpdCA9IG5ldyBTZXQoKTtcbiAgICB9XG5cbiAgICAvLyBOT1RFOiB3ZSB0cmFjayBtaXNzaW5nIGBhd2FpdHNgIGJ5IGV4cG9zaW5nIGEgc3BlY2lhbCBjdXN0b20gUHJvbWlzZSB0byB1c2VyIGNvZGUuXG4gICAgLy8gQWN0aW9uIG9yIGFzc2VydGlvbiBpcyBhd2FpdGVkIGlmOlxuICAgIC8vIGEpc29tZW9uZSB1c2VkIGBhd2FpdGAgc28gUHJvbWlzZSdzIGB0aGVuYCBmdW5jdGlvbiBleGVjdXRlZFxuICAgIC8vIGIpUHJvbWlzZSBjaGFpbmVkIGJ5IHVzaW5nIG9uZSBvZiB0aGUgbWl4ZWQtaW4gY29udHJvbGxlciBtZXRob2RzXG4gICAgLy9cbiAgICAvLyBJbiBib3RoIHNjZW5hcmlvcywgd2UgY2hlY2sgdGhhdCBjYWxsc2l0ZSB0aGF0IHByb2R1Y2VkIFByb21pc2UgaXMgZXF1YWwgdG8gdGhlIG9uZVxuICAgIC8vIHRoYXQgaXMgY3VycmVudGx5IG1pc3NpbmcgYXdhaXQuIFRoaXMgaXMgcmVxdWlyZWQgdG8gd29ya2Fyb3VuZCBzY2VuYXJpb3MgbGlrZSB0aGlzOlxuICAgIC8vXG4gICAgLy8gdmFyIHQyID0gdC5jbGljaygnI2J0bjEnKTsgLy8gPC0tIHN0b3JlcyBuZXcgY2FsbHNpdGVXaXRob3V0QXdhaXRcbiAgICAvLyBhd2FpdCB0MjsgICAgICAgICAgICAgICAgICAvLyA8LS0gY2FsbHNpdGVXaXRob3V0QXdhaXQgPSBudWxsXG4gICAgLy8gdC5jbGljaygnI2J0bjInKTsgICAgICAgICAgLy8gPC0tIHN0b3JlcyBuZXcgY2FsbHNpdGVXaXRob3V0QXdhaXRcbiAgICAvLyBhd2FpdCB0Mi5jbGljaygnI2J0bjMnKTsgICAvLyA8LS0gd2l0aG91dCBjaGVjayBpdCB3aWxsIHNldCBjYWxsc2l0ZVdpdGhvdXRBd2FpdCA9IG51bGwsIHNvIHdlIHdpbGwgbG9zdCB0cmFja2luZ1xuICAgIF9jcmVhdGVFeHRlbmRlZFByb21pc2UgKHByb21pc2UsIGNhbGxzaXRlKSB7XG4gICAgICAgIGNvbnN0IGV4dGVuZGVkUHJvbWlzZSAgICAgPSBwcm9taXNlLnRoZW4oaWRlbnRpdHkpO1xuICAgICAgICBjb25zdCBtYXJrQ2FsbHNpdGVBd2FpdGVkID0gKCkgPT4gdGhpcy5jYWxsc2l0ZXNXaXRob3V0QXdhaXQuZGVsZXRlKGNhbGxzaXRlKTtcblxuICAgICAgICBleHRlbmRlZFByb21pc2UudGhlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG1hcmtDYWxsc2l0ZUF3YWl0ZWQoKTtcblxuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsVGhlbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGRlbGVnYXRlQVBJKGV4dGVuZGVkUHJvbWlzZSwgVGVzdENvbnRyb2xsZXIuQVBJX0xJU1QsIHtcbiAgICAgICAgICAgIGhhbmRsZXI6ICAgICB0aGlzLFxuICAgICAgICAgICAgcHJveHlNZXRob2Q6IG1hcmtDYWxsc2l0ZUF3YWl0ZWRcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGV4dGVuZGVkUHJvbWlzZTtcbiAgICB9XG5cbiAgICBfZW5xdWV1ZVRhc2sgKGFwaU1ldGhvZE5hbWUsIGNyZWF0ZVRhc2tFeGVjdXRvcikge1xuICAgICAgICBjb25zdCBjYWxsc2l0ZSA9IGdldENhbGxzaXRlRm9yTWV0aG9kKGFwaU1ldGhvZE5hbWUpO1xuICAgICAgICBjb25zdCBleGVjdXRvciA9IGNyZWF0ZVRhc2tFeGVjdXRvcihjYWxsc2l0ZSk7XG5cbiAgICAgICAgdGhpcy5leGVjdXRpb25DaGFpbi50aGVuID0gb3JpZ2luYWxUaGVuO1xuICAgICAgICB0aGlzLmV4ZWN1dGlvbkNoYWluICAgICAgPSB0aGlzLmV4ZWN1dGlvbkNoYWluLnRoZW4oZXhlY3V0b3IpO1xuXG4gICAgICAgIHRoaXMuY2FsbHNpdGVzV2l0aG91dEF3YWl0LmFkZChjYWxsc2l0ZSk7XG5cbiAgICAgICAgdGhpcy5leGVjdXRpb25DaGFpbiA9IHRoaXMuX2NyZWF0ZUV4dGVuZGVkUHJvbWlzZSh0aGlzLmV4ZWN1dGlvbkNoYWluLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0aW9uQ2hhaW47XG4gICAgfVxuXG4gICAgX2VucXVldWVDb21tYW5kIChhcGlNZXRob2ROYW1lLCBDbWRDdG9yLCBjbWRBcmdzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlVGFzayhhcGlNZXRob2ROYW1lLCBjYWxsc2l0ZSA9PiB7XG4gICAgICAgICAgICBsZXQgY29tbWFuZCA9IG51bGw7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29tbWFuZCA9IG5ldyBDbWRDdG9yKGNtZEFyZ3MsIHRoaXMudGVzdFJ1bik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgZXJyLmNhbGxzaXRlID0gY2FsbHNpdGU7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy50ZXN0UnVuLnJlY29yZFNjcmVlbkNhcHR1cmUgJiYgYXBpTWV0aG9kTmFtZSAhPT0gJ3Rha2VTY3JlZW5zaG90Jykge1xuICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB0aGlzLnRlc3RSdW4uZXhlY3V0ZUNvbW1hbmQoY29tbWFuZCwgY2FsbHNpdGUpLnRoZW4oIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudGVzdFJ1bi5yZWNvcmRTY3JlZW5DYXB0dXJlICYmIGFwaU1ldGhvZE5hbWUgIT09ICd0YWtlU2NyZWVuc2hvdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0ZUZvbGRlciA9IGAke2RhdGUuZ2V0TW9udGgoKSArIDF9XyR7ZGF0ZS5nZXREYXRlKCl9XyR7ZGF0ZS5nZXRGdWxsWWVhcigpfWA7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uSWQgPSB0aGlzLnRlc3RSdW4uc2Vzc2lvbi5pZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRlc3ROYW1lID0gdGhpcy50ZXN0UnVuLnRlc3QubmFtZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGggPSBgJHtkYXRlRm9sZGVyfS8ke3Nlc3Npb25JZH0vJHtEYXRlLm5vdygpfV8ke3Rlc3ROYW1lfV8ke2FwaU1ldGhvZE5hbWV9X2F1dG8ucG5nYDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy50ZXN0UnVuLmV4ZWN1dGVDb21tYW5kKG5ldyBUYWtlU2NyZWVuc2hvdENvbW1hbmQoeyBwYXRoOiBwYXRoIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gKCkgPT4gdGhpcy50ZXN0UnVuLmV4ZWN1dGVDb21tYW5kKGNvbW1hbmQsIGNhbGxzaXRlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQVBJIGltcGxlbWVudGF0aW9uXG4gICAgLy8gV2UgbmVlZCBpbXBsZW1lbnRhdGlvbiBtZXRob2RzIHRvIG9idGFpbiBjb3JyZWN0IGNhbGxzaXRlcy4gSWYgd2UgdXNlIHBsYWluIEFQSVxuICAgIC8vIG1ldGhvZHMgaW4gY2hhaW5lZCB3cmFwcGVycyB0aGVuIHdlIHdpbGwgaGF2ZSBjYWxsc2l0ZSBmb3IgdGhlIHdyYXBwZWQgbWV0aG9kXG4gICAgLy8gaW4gdGhpcyBmaWxlIGluc3RlYWQgb2YgY2hhaW5lZCBtZXRob2QgY2FsbHNpdGUgaW4gdXNlciBjb2RlLlxuICAgIF9jdHgkZ2V0dGVyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdFJ1bi5jdHg7XG4gICAgfVxuXG4gICAgX2N0eCRzZXR0ZXIgKHZhbCkge1xuICAgICAgICB0aGlzLnRlc3RSdW4uY3R4ID0gdmFsO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnRlc3RSdW4uY3R4O1xuICAgIH1cblxuICAgIF9maXh0dXJlQ3R4JGdldHRlciAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRlc3RSdW4uZml4dHVyZUN0eDtcbiAgICB9XG5cbiAgICBfY2xpY2skIChzZWxlY3Rvciwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ2NsaWNrJywgQ2xpY2tDb21tYW5kLCB7IHNlbGVjdG9yLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIF9yaWdodENsaWNrJCAoc2VsZWN0b3IsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdyaWdodENsaWNrJywgUmlnaHRDbGlja0NvbW1hbmQsIHsgc2VsZWN0b3IsIG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgX2RvdWJsZUNsaWNrJCAoc2VsZWN0b3IsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdkb3VibGVDbGljaycsIERvdWJsZUNsaWNrQ29tbWFuZCwgeyBzZWxlY3Rvciwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBfaG92ZXIkIChzZWxlY3Rvciwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ2hvdmVyJywgSG92ZXJDb21tYW5kLCB7IHNlbGVjdG9yLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIF9kcmFnJCAoc2VsZWN0b3IsIGRyYWdPZmZzZXRYLCBkcmFnT2Zmc2V0WSwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ2RyYWcnLCBEcmFnQ29tbWFuZCwgeyBzZWxlY3RvciwgZHJhZ09mZnNldFgsIGRyYWdPZmZzZXRZLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIF9kcmFnVG9FbGVtZW50JCAoc2VsZWN0b3IsIGRlc3RpbmF0aW9uU2VsZWN0b3IsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdkcmFnVG9FbGVtZW50JywgRHJhZ1RvRWxlbWVudENvbW1hbmQsIHsgc2VsZWN0b3IsIGRlc3RpbmF0aW9uU2VsZWN0b3IsIG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgX3R5cGVUZXh0JCAoc2VsZWN0b3IsIHRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCd0eXBlVGV4dCcsIFR5cGVUZXh0Q29tbWFuZCwgeyBzZWxlY3RvciwgdGV4dCwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBfc2VsZWN0VGV4dCQgKHNlbGVjdG9yLCBzdGFydFBvcywgZW5kUG9zLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnc2VsZWN0VGV4dCcsIFNlbGVjdFRleHRDb21tYW5kLCB7IHNlbGVjdG9yLCBzdGFydFBvcywgZW5kUG9zLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIF9zZWxlY3RUZXh0QXJlYUNvbnRlbnQkIChzZWxlY3Rvciwgc3RhcnRMaW5lLCBzdGFydFBvcywgZW5kTGluZSwgZW5kUG9zLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnc2VsZWN0VGV4dEFyZWFDb250ZW50JywgU2VsZWN0VGV4dEFyZWFDb250ZW50Q29tbWFuZCwge1xuICAgICAgICAgICAgc2VsZWN0b3IsXG4gICAgICAgICAgICBzdGFydExpbmUsXG4gICAgICAgICAgICBzdGFydFBvcyxcbiAgICAgICAgICAgIGVuZExpbmUsXG4gICAgICAgICAgICBlbmRQb3MsXG4gICAgICAgICAgICBvcHRpb25zXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9zZWxlY3RFZGl0YWJsZUNvbnRlbnQkIChzdGFydFNlbGVjdG9yLCBlbmRTZWxlY3Rvciwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3NlbGVjdEVkaXRhYmxlQ29udGVudCcsIFNlbGVjdEVkaXRhYmxlQ29udGVudENvbW1hbmQsIHtcbiAgICAgICAgICAgIHN0YXJ0U2VsZWN0b3IsXG4gICAgICAgICAgICBlbmRTZWxlY3RvcixcbiAgICAgICAgICAgIG9wdGlvbnNcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX3ByZXNzS2V5JCAoa2V5cywgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3ByZXNzS2V5JywgUHJlc3NLZXlDb21tYW5kLCB7IGtleXMsIG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgX3dhaXQkICh0aW1lb3V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnd2FpdCcsIFdhaXRDb21tYW5kLCB7IHRpbWVvdXQgfSk7XG4gICAgfVxuXG4gICAgX25hdmlnYXRlVG8kICh1cmwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCduYXZpZ2F0ZVRvJywgTmF2aWdhdGVUb0NvbW1hbmQsIHsgdXJsIH0pO1xuICAgIH1cblxuICAgIF9zZXRGaWxlc1RvVXBsb2FkJCAoc2VsZWN0b3IsIGZpbGVQYXRoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnc2V0RmlsZXNUb1VwbG9hZCcsIFNldEZpbGVzVG9VcGxvYWRDb21tYW5kLCB7IHNlbGVjdG9yLCBmaWxlUGF0aCB9KTtcbiAgICB9XG5cbiAgICBfY2xlYXJVcGxvYWQkIChzZWxlY3Rvcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ2NsZWFyVXBsb2FkJywgQ2xlYXJVcGxvYWRDb21tYW5kLCB7IHNlbGVjdG9yIH0pO1xuICAgIH1cblxuICAgIF90YWtlU2NyZWVuc2hvdCQgKHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCd0YWtlU2NyZWVuc2hvdCcsIFRha2VTY3JlZW5zaG90Q29tbWFuZCwgeyBwYXRoIH0pO1xuICAgIH1cblxuICAgIF90YWtlRWxlbWVudFNjcmVlbnNob3QkIChzZWxlY3RvciwgLi4uYXJncykge1xuICAgICAgICBjb25zdCBjb21tYW5kQXJncyA9IHsgc2VsZWN0b3IgfTtcblxuICAgICAgICBpZiAoYXJnc1sxXSkge1xuICAgICAgICAgICAgY29tbWFuZEFyZ3MucGF0aCAgICA9IGFyZ3NbMF07XG4gICAgICAgICAgICBjb21tYW5kQXJncy5vcHRpb25zID0gYXJnc1sxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgYXJnc1swXSA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICBjb21tYW5kQXJncy5vcHRpb25zID0gYXJnc1swXTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgY29tbWFuZEFyZ3MucGF0aCA9IGFyZ3NbMF07XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCd0YWtlRWxlbWVudFNjcmVlbnNob3QnLCBUYWtlRWxlbWVudFNjcmVlbnNob3RDb21tYW5kLCBjb21tYW5kQXJncyk7XG4gICAgfVxuXG4gICAgX3Jlc2l6ZVdpbmRvdyQgKHdpZHRoLCBoZWlnaHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdyZXNpemVXaW5kb3cnLCBSZXNpemVXaW5kb3dDb21tYW5kLCB7IHdpZHRoLCBoZWlnaHQgfSk7XG4gICAgfVxuXG4gICAgX3Jlc2l6ZVdpbmRvd1RvRml0RGV2aWNlJCAoZGV2aWNlLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgncmVzaXplV2luZG93VG9GaXREZXZpY2UnLCBSZXNpemVXaW5kb3dUb0ZpdERldmljZUNvbW1hbmQsIHsgZGV2aWNlLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIF9tYXhpbWl6ZVdpbmRvdyQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ21heGltaXplV2luZG93JywgTWF4aW1pemVXaW5kb3dDb21tYW5kKTtcbiAgICB9XG5cbiAgICBfc3dpdGNoVG9JZnJhbWUkIChzZWxlY3Rvcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3N3aXRjaFRvSWZyYW1lJywgU3dpdGNoVG9JZnJhbWVDb21tYW5kLCB7IHNlbGVjdG9yIH0pO1xuICAgIH1cblxuICAgIF9zd2l0Y2hUb01haW5XaW5kb3ckICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdzd2l0Y2hUb01haW5XaW5kb3cnLCBTd2l0Y2hUb01haW5XaW5kb3dDb21tYW5kKTtcbiAgICB9XG5cbiAgICBfZXZhbCQgKGZuLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghaXNOdWxsT3JVbmRlZmluZWQob3B0aW9ucykpXG4gICAgICAgICAgICBvcHRpb25zID0gYXNzaWduKHt9LCBvcHRpb25zLCB7IGJvdW5kVGVzdFJ1bjogdGhpcyB9KTtcblxuICAgICAgICBjb25zdCBidWlsZGVyICA9IG5ldyBDbGllbnRGdW5jdGlvbkJ1aWxkZXIoZm4sIG9wdGlvbnMsIHsgaW5zdGFudGlhdGlvbjogJ2V2YWwnLCBleGVjdXRpb246ICdldmFsJyB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50Rm4gPSBidWlsZGVyLmdldEZ1bmN0aW9uKCk7XG5cbiAgICAgICAgcmV0dXJuIGNsaWVudEZuKCk7XG4gICAgfVxuXG4gICAgX3NldE5hdGl2ZURpYWxvZ0hhbmRsZXIkIChmbiwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3NldE5hdGl2ZURpYWxvZ0hhbmRsZXInLCBTZXROYXRpdmVEaWFsb2dIYW5kbGVyQ29tbWFuZCwge1xuICAgICAgICAgICAgZGlhbG9nSGFuZGxlcjogeyBmbiwgb3B0aW9ucyB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9nZXROYXRpdmVEaWFsb2dIaXN0b3J5JCAoKSB7XG4gICAgICAgIGNvbnN0IGNhbGxzaXRlID0gZ2V0Q2FsbHNpdGVGb3JNZXRob2QoJ2dldE5hdGl2ZURpYWxvZ0hpc3RvcnknKTtcblxuICAgICAgICByZXR1cm4gdGhpcy50ZXN0UnVuLmV4ZWN1dGVDb21tYW5kKG5ldyBHZXROYXRpdmVEaWFsb2dIaXN0b3J5Q29tbWFuZCgpLCBjYWxsc2l0ZSk7XG4gICAgfVxuXG4gICAgX2dldEJyb3dzZXJDb25zb2xlTWVzc2FnZXMkICgpIHtcbiAgICAgICAgY29uc3QgY2FsbHNpdGUgPSBnZXRDYWxsc2l0ZUZvck1ldGhvZCgnZ2V0QnJvd3NlckNvbnNvbGVNZXNzYWdlcycpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnRlc3RSdW4uZXhlY3V0ZUNvbW1hbmQobmV3IEdldEJyb3dzZXJDb25zb2xlTWVzc2FnZXNDb21tYW5kKCksIGNhbGxzaXRlKTtcbiAgICB9XG5cbiAgICBfZXhwZWN0JCAoYWN0dWFsKSB7XG4gICAgICAgIGNvbnN0IGNhbGxzaXRlID0gZ2V0Q2FsbHNpdGVGb3JNZXRob2QoJ2V4cGVjdCcpO1xuXG4gICAgICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKGFjdHVhbCwgdGhpcywgY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIF9kZWJ1ZyQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ2RlYnVnJywgRGVidWdDb21tYW5kKTtcbiAgICB9XG5cbiAgICBfc2V0VGVzdFNwZWVkJCAoc3BlZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdzZXRUZXN0U3BlZWQnLCBTZXRUZXN0U3BlZWRDb21tYW5kLCB7IHNwZWVkIH0pO1xuICAgIH1cblxuICAgIF9zZXRQYWdlTG9hZFRpbWVvdXQkIChkdXJhdGlvbikge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3NldFBhZ2VMb2FkVGltZW91dCcsIFNldFBhZ2VMb2FkVGltZW91dENvbW1hbmQsIHsgZHVyYXRpb24gfSk7XG4gICAgfVxuXG4gICAgX3VzZVJvbGUkIChyb2xlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgndXNlUm9sZScsIFVzZVJvbGVDb21tYW5kLCB7IHJvbGUgfSk7XG4gICAgfVxuXG4gICAgX2FkZFJlcXVlc3RIb29rcyQgKC4uLmhvb2tzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlVGFzaygnYWRkUmVxdWVzdEhvb2tzJywgKCkgPT4ge1xuICAgICAgICAgICAgaG9va3MgPSBmbGF0dGVuKGhvb2tzKTtcblxuICAgICAgICAgICAgYXNzZXJ0UmVxdWVzdEhvb2tUeXBlKGhvb2tzKTtcblxuICAgICAgICAgICAgaG9va3MuZm9yRWFjaChob29rID0+IHRoaXMudGVzdFJ1bi5hZGRSZXF1ZXN0SG9vayhob29rKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9yZW1vdmVSZXF1ZXN0SG9va3MkICguLi5ob29rcykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZVRhc2soJ3JlbW92ZVJlcXVlc3RIb29rcycsICgpID0+IHtcbiAgICAgICAgICAgIGhvb2tzID0gZmxhdHRlbihob29rcyk7XG5cbiAgICAgICAgICAgIGFzc2VydFJlcXVlc3RIb29rVHlwZShob29rcyk7XG5cbiAgICAgICAgICAgIGhvb2tzLmZvckVhY2goaG9vayA9PiB0aGlzLnRlc3RSdW4ucmVtb3ZlUmVxdWVzdEhvb2soaG9vaykpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG5cblRlc3RDb250cm9sbGVyLkFQSV9MSVNUID0gZ2V0RGVsZWdhdGVkQVBJTGlzdChUZXN0Q29udHJvbGxlci5wcm90b3R5cGUpO1xuXG5kZWxlZ2F0ZUFQSShUZXN0Q29udHJvbGxlci5wcm90b3R5cGUsIFRlc3RDb250cm9sbGVyLkFQSV9MSVNULCB7IHVzZUN1cnJlbnRDdHhBc0hhbmRsZXI6IHRydWUgfSk7XG4iXX0= diff --git a/lib/api/test-controller/proxy.js b/lib/api/test-controller/proxy.js new file mode 100644 index 00000000..10808b3d --- /dev/null +++ b/lib/api/test-controller/proxy.js @@ -0,0 +1,47 @@ +'use strict'; + +exports.__esModule = true; + +var _create = require('babel-runtime/core-js/object/create'); + +var _create2 = _interopRequireDefault(_create); + +var _ = require('./'); + +var _2 = _interopRequireDefault(_); + +var _delegatedApi = require('../../utils/delegated-api'); + +var _testRunTracker = require('../test-run-tracker'); + +var _testRunTracker2 = _interopRequireDefault(_testRunTracker); + +var _runtime = require('../../errors/runtime'); + +var _message = require('../../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const testControllerProxy = (0, _create2.default)(null); + +(0, _delegatedApi.delegateAPI)(testControllerProxy, _2.default.API_LIST, { + getHandler(propName, accessor) { + const testRun = _testRunTracker2.default.resolveContextTestRun(); + + if (!testRun) { + let callsiteName = null; + + if (accessor === 'getter') callsiteName = 'get';else if (accessor === 'setter') callsiteName = 'set';else callsiteName = propName; + + throw new _runtime.APIError(callsiteName, _message2.default.testControllerProxyCantResolveTestRun); + } + + return testRun.controller; + } +}); + +exports.default = testControllerProxy; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcGkvdGVzdC1jb250cm9sbGVyL3Byb3h5LmpzIl0sIm5hbWVzIjpbInRlc3RDb250cm9sbGVyUHJveHkiLCJUZXN0Q29udHJvbGxlciIsIkFQSV9MSVNUIiwiZ2V0SGFuZGxlciIsInByb3BOYW1lIiwiYWNjZXNzb3IiLCJ0ZXN0UnVuIiwidGVzdFJ1blRyYWNrZXIiLCJyZXNvbHZlQ29udGV4dFRlc3RSdW4iLCJjYWxsc2l0ZU5hbWUiLCJBUElFcnJvciIsIk1FU1NBR0UiLCJ0ZXN0Q29udHJvbGxlclByb3h5Q2FudFJlc29sdmVUZXN0UnVuIiwiY29udHJvbGxlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQTs7OztBQUNBOztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLE1BQU1BLHNCQUFzQixzQkFBYyxJQUFkLENBQTVCOztBQUVBLCtCQUFZQSxtQkFBWixFQUFpQ0MsV0FBZUMsUUFBaEQsRUFBMEQ7QUFDdERDLGVBQVlDLFFBQVosRUFBc0JDLFFBQXRCLEVBQWdDO0FBQzVCLGNBQU1DLFVBQVVDLHlCQUFlQyxxQkFBZixFQUFoQjs7QUFFQSxZQUFJLENBQUNGLE9BQUwsRUFBYztBQUNWLGdCQUFJRyxlQUFlLElBQW5COztBQUVBLGdCQUFJSixhQUFhLFFBQWpCLEVBQ0lJLGVBQWUsS0FBZixDQURKLEtBRUssSUFBSUosYUFBYSxRQUFqQixFQUNESSxlQUFlLEtBQWYsQ0FEQyxLQUdEQSxlQUFlTCxRQUFmOztBQUVKLGtCQUFNLElBQUlNLGlCQUFKLENBQWFELFlBQWIsRUFBMkJFLGtCQUFRQyxxQ0FBbkMsQ0FBTjtBQUNIOztBQUVELGVBQU9OLFFBQVFPLFVBQWY7QUFDSDtBQWxCcUQsQ0FBMUQ7O2tCQXFCZWIsbUIiLCJmaWxlIjoiYXBpL3Rlc3QtY29udHJvbGxlci9wcm94eS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBUZXN0Q29udHJvbGxlciBmcm9tICcuLyc7XG5pbXBvcnQgeyBkZWxlZ2F0ZUFQSSB9IGZyb20gJy4uLy4uL3V0aWxzL2RlbGVnYXRlZC1hcGknO1xuaW1wb3J0IHRlc3RSdW5UcmFja2VyIGZyb20gJy4uL3Rlc3QtcnVuLXRyYWNrZXInO1xuaW1wb3J0IHsgQVBJRXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgTUVTU0FHRSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZS9tZXNzYWdlJztcblxuY29uc3QgdGVzdENvbnRyb2xsZXJQcm94eSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbmRlbGVnYXRlQVBJKHRlc3RDb250cm9sbGVyUHJveHksIFRlc3RDb250cm9sbGVyLkFQSV9MSVNULCB7XG4gICAgZ2V0SGFuZGxlciAocHJvcE5hbWUsIGFjY2Vzc29yKSB7XG4gICAgICAgIGNvbnN0IHRlc3RSdW4gPSB0ZXN0UnVuVHJhY2tlci5yZXNvbHZlQ29udGV4dFRlc3RSdW4oKTtcblxuICAgICAgICBpZiAoIXRlc3RSdW4pIHtcbiAgICAgICAgICAgIGxldCBjYWxsc2l0ZU5hbWUgPSBudWxsO1xuXG4gICAgICAgICAgICBpZiAoYWNjZXNzb3IgPT09ICdnZXR0ZXInKVxuICAgICAgICAgICAgICAgIGNhbGxzaXRlTmFtZSA9ICdnZXQnO1xuICAgICAgICAgICAgZWxzZSBpZiAoYWNjZXNzb3IgPT09ICdzZXR0ZXInKVxuICAgICAgICAgICAgICAgIGNhbGxzaXRlTmFtZSA9ICdzZXQnO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGNhbGxzaXRlTmFtZSA9IHByb3BOYW1lO1xuXG4gICAgICAgICAgICB0aHJvdyBuZXcgQVBJRXJyb3IoY2FsbHNpdGVOYW1lLCBNRVNTQUdFLnRlc3RDb250cm9sbGVyUHJveHlDYW50UmVzb2x2ZVRlc3RSdW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRlc3RSdW4uY29udHJvbGxlcjtcbiAgICB9XG59KTtcblxuZXhwb3J0IGRlZmF1bHQgdGVzdENvbnRyb2xsZXJQcm94eTtcbiJdfQ== diff --git a/lib/api/test-page-url.js b/lib/api/test-page-url.js new file mode 100644 index 00000000..b41fbc04 --- /dev/null +++ b/lib/api/test-page-url.js @@ -0,0 +1,59 @@ +'use strict'; + +exports.__esModule = true; +exports.assertUrl = assertUrl; +exports.resolvePageUrl = resolvePageUrl; + +var _path = require('path'); + +var _path2 = _interopRequireDefault(_path); + +var _osFamily = require('os-family'); + +var _osFamily2 = _interopRequireDefault(_osFamily); + +var _runtime = require('../errors/runtime'); + +var _message = require('../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const PROTOCOL_RE = /^([\w-]+?)(?=:\/\/)/; +const SUPPORTED_PROTOCOL_RE = /^(https?|file):/; +const IMPLICIT_PROTOCOL_RE = /^\/\//; +const ABSOLUTE_PATH_RE = /^\/[^/]/; +const WIN_ABSOLUTE_PATH_RE = /^\w:[/\\]/; +const RELATIVE_PATH_RE = /^\.\.?[/\\]/; + +function isAbsolutePath(url) { + return _osFamily2.default.win ? WIN_ABSOLUTE_PATH_RE.test(url) : ABSOLUTE_PATH_RE.test(url); +} + +function resolveFileUrl(url, testFileName) { + const testFileDir = _path2.default.dirname(testFileName); + + if (RELATIVE_PATH_RE.test(url)) url = _path2.default.join(testFileDir, url); + + return 'file://' + url; +} + +function assertUrl(url, callsiteName) { + const protocol = url.match(PROTOCOL_RE); + const hasUnsupportedProtocol = protocol && !SUPPORTED_PROTOCOL_RE.test(url); + const isWinAbsolutePath = _osFamily2.default.win && WIN_ABSOLUTE_PATH_RE.test(url); + + if (hasUnsupportedProtocol && !isWinAbsolutePath && url !== 'about:blank') throw new _runtime.APIError(callsiteName, _message2.default.unsupportedUrlProtocol, url, protocol[0]); +} + +function resolvePageUrl(url, testFileName) { + if (SUPPORTED_PROTOCOL_RE.test(url) || url === 'about:blank') return url; + + if (isAbsolutePath(url) || RELATIVE_PATH_RE.test(url)) return resolveFileUrl(url, testFileName); + + const protocol = IMPLICIT_PROTOCOL_RE.test(url) ? 'http:' : 'http://'; + + return protocol + url; +} +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvdGVzdC1wYWdlLXVybC5qcyJdLCJuYW1lcyI6WyJhc3NlcnRVcmwiLCJyZXNvbHZlUGFnZVVybCIsIlBST1RPQ09MX1JFIiwiU1VQUE9SVEVEX1BST1RPQ09MX1JFIiwiSU1QTElDSVRfUFJPVE9DT0xfUkUiLCJBQlNPTFVURV9QQVRIX1JFIiwiV0lOX0FCU09MVVRFX1BBVEhfUkUiLCJSRUxBVElWRV9QQVRIX1JFIiwiaXNBYnNvbHV0ZVBhdGgiLCJ1cmwiLCJPUyIsIndpbiIsInRlc3QiLCJyZXNvbHZlRmlsZVVybCIsInRlc3RGaWxlTmFtZSIsInRlc3RGaWxlRGlyIiwicGF0aCIsImRpcm5hbWUiLCJqb2luIiwiY2FsbHNpdGVOYW1lIiwicHJvdG9jb2wiLCJtYXRjaCIsImhhc1Vuc3VwcG9ydGVkUHJvdG9jb2wiLCJpc1dpbkFic29sdXRlUGF0aCIsIkFQSUVycm9yIiwiTUVTU0FHRSIsInVuc3VwcG9ydGVkVXJsUHJvdG9jb2wiXSwibWFwcGluZ3MiOiI7OztRQTBCZ0JBLFMsR0FBQUEsUztRQVNBQyxjLEdBQUFBLGM7O0FBbkNoQjs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLE1BQU1DLGNBQXdCLHFCQUE5QjtBQUNBLE1BQU1DLHdCQUF3QixpQkFBOUI7QUFDQSxNQUFNQyx1QkFBd0IsT0FBOUI7QUFDQSxNQUFNQyxtQkFBd0IsU0FBOUI7QUFDQSxNQUFNQyx1QkFBd0IsV0FBOUI7QUFDQSxNQUFNQyxtQkFBd0IsYUFBOUI7O0FBR0EsU0FBU0MsY0FBVCxDQUF5QkMsR0FBekIsRUFBOEI7QUFDMUIsV0FBT0MsbUJBQUdDLEdBQUgsR0FBU0wscUJBQXFCTSxJQUFyQixDQUEwQkgsR0FBMUIsQ0FBVCxHQUEwQ0osaUJBQWlCTyxJQUFqQixDQUFzQkgsR0FBdEIsQ0FBakQ7QUFDSDs7QUFFRCxTQUFTSSxjQUFULENBQXlCSixHQUF6QixFQUE4QkssWUFBOUIsRUFBNEM7QUFDeEMsVUFBTUMsY0FBY0MsZUFBS0MsT0FBTCxDQUFhSCxZQUFiLENBQXBCOztBQUVBLFFBQUlQLGlCQUFpQkssSUFBakIsQ0FBc0JILEdBQXRCLENBQUosRUFDSUEsTUFBTU8sZUFBS0UsSUFBTCxDQUFVSCxXQUFWLEVBQXVCTixHQUF2QixDQUFOOztBQUVKLFdBQU8sWUFBWUEsR0FBbkI7QUFDSDs7QUFFTSxTQUFTVCxTQUFULENBQW9CUyxHQUFwQixFQUF5QlUsWUFBekIsRUFBdUM7QUFDMUMsVUFBTUMsV0FBeUJYLElBQUlZLEtBQUosQ0FBVW5CLFdBQVYsQ0FBL0I7QUFDQSxVQUFNb0IseUJBQXlCRixZQUFZLENBQUNqQixzQkFBc0JTLElBQXRCLENBQTJCSCxHQUEzQixDQUE1QztBQUNBLFVBQU1jLG9CQUF5QmIsbUJBQUdDLEdBQUgsSUFBVUwscUJBQXFCTSxJQUFyQixDQUEwQkgsR0FBMUIsQ0FBekM7O0FBRUEsUUFBSWEsMEJBQTBCLENBQUNDLGlCQUEzQixJQUFnRGQsUUFBUSxhQUE1RCxFQUNJLE1BQU0sSUFBSWUsaUJBQUosQ0FBYUwsWUFBYixFQUEyQk0sa0JBQVFDLHNCQUFuQyxFQUEyRGpCLEdBQTNELEVBQWdFVyxTQUFTLENBQVQsQ0FBaEUsQ0FBTjtBQUNQOztBQUVNLFNBQVNuQixjQUFULENBQXlCUSxHQUF6QixFQUE4QkssWUFBOUIsRUFBNEM7QUFDL0MsUUFBSVgsc0JBQXNCUyxJQUF0QixDQUEyQkgsR0FBM0IsS0FBbUNBLFFBQVEsYUFBL0MsRUFDSSxPQUFPQSxHQUFQOztBQUVKLFFBQUlELGVBQWVDLEdBQWYsS0FBdUJGLGlCQUFpQkssSUFBakIsQ0FBc0JILEdBQXRCLENBQTNCLEVBQ0ksT0FBT0ksZUFBZUosR0FBZixFQUFvQkssWUFBcEIsQ0FBUDs7QUFFSixVQUFNTSxXQUFXaEIscUJBQXFCUSxJQUFyQixDQUEwQkgsR0FBMUIsSUFBaUMsT0FBakMsR0FBMkMsU0FBNUQ7O0FBRUEsV0FBT1csV0FBV1gsR0FBbEI7QUFDSCIsImZpbGUiOiJhcGkvdGVzdC1wYWdlLXVybC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IE9TIGZyb20gJ29zLWZhbWlseSc7XG5pbXBvcnQgeyBBUElFcnJvciB9IGZyb20gJy4uL2Vycm9ycy9ydW50aW1lJztcbmltcG9ydCBNRVNTQUdFIGZyb20gJy4uL2Vycm9ycy9ydW50aW1lL21lc3NhZ2UnO1xuXG5jb25zdCBQUk9UT0NPTF9SRSAgICAgICAgICAgPSAvXihbXFx3LV0rPykoPz06XFwvXFwvKS87XG5jb25zdCBTVVBQT1JURURfUFJPVE9DT0xfUkUgPSAvXihodHRwcz98ZmlsZSk6LztcbmNvbnN0IElNUExJQ0lUX1BST1RPQ09MX1JFICA9IC9eXFwvXFwvLztcbmNvbnN0IEFCU09MVVRFX1BBVEhfUkUgICAgICA9IC9eXFwvW14vXS87XG5jb25zdCBXSU5fQUJTT0xVVEVfUEFUSF9SRSAgPSAvXlxcdzpbL1xcXFxdLztcbmNvbnN0IFJFTEFUSVZFX1BBVEhfUkUgICAgICA9IC9eXFwuXFwuP1svXFxcXF0vO1xuXG5cbmZ1bmN0aW9uIGlzQWJzb2x1dGVQYXRoICh1cmwpIHtcbiAgICByZXR1cm4gT1Mud2luID8gV0lOX0FCU09MVVRFX1BBVEhfUkUudGVzdCh1cmwpIDogQUJTT0xVVEVfUEFUSF9SRS50ZXN0KHVybCk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVGaWxlVXJsICh1cmwsIHRlc3RGaWxlTmFtZSkge1xuICAgIGNvbnN0IHRlc3RGaWxlRGlyID0gcGF0aC5kaXJuYW1lKHRlc3RGaWxlTmFtZSk7XG5cbiAgICBpZiAoUkVMQVRJVkVfUEFUSF9SRS50ZXN0KHVybCkpXG4gICAgICAgIHVybCA9IHBhdGguam9pbih0ZXN0RmlsZURpciwgdXJsKTtcblxuICAgIHJldHVybiAnZmlsZTovLycgKyB1cmw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRVcmwgKHVybCwgY2FsbHNpdGVOYW1lKSB7XG4gICAgY29uc3QgcHJvdG9jb2wgICAgICAgICAgICAgICA9IHVybC5tYXRjaChQUk9UT0NPTF9SRSk7XG4gICAgY29uc3QgaGFzVW5zdXBwb3J0ZWRQcm90b2NvbCA9IHByb3RvY29sICYmICFTVVBQT1JURURfUFJPVE9DT0xfUkUudGVzdCh1cmwpO1xuICAgIGNvbnN0IGlzV2luQWJzb2x1dGVQYXRoICAgICAgPSBPUy53aW4gJiYgV0lOX0FCU09MVVRFX1BBVEhfUkUudGVzdCh1cmwpO1xuXG4gICAgaWYgKGhhc1Vuc3VwcG9ydGVkUHJvdG9jb2wgJiYgIWlzV2luQWJzb2x1dGVQYXRoICYmIHVybCAhPT0gJ2Fib3V0OmJsYW5rJylcbiAgICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKGNhbGxzaXRlTmFtZSwgTUVTU0FHRS51bnN1cHBvcnRlZFVybFByb3RvY29sLCB1cmwsIHByb3RvY29sWzBdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVQYWdlVXJsICh1cmwsIHRlc3RGaWxlTmFtZSkge1xuICAgIGlmIChTVVBQT1JURURfUFJPVE9DT0xfUkUudGVzdCh1cmwpIHx8IHVybCA9PT0gJ2Fib3V0OmJsYW5rJylcbiAgICAgICAgcmV0dXJuIHVybDtcblxuICAgIGlmIChpc0Fic29sdXRlUGF0aCh1cmwpIHx8IFJFTEFUSVZFX1BBVEhfUkUudGVzdCh1cmwpKVxuICAgICAgICByZXR1cm4gcmVzb2x2ZUZpbGVVcmwodXJsLCB0ZXN0RmlsZU5hbWUpO1xuXG4gICAgY29uc3QgcHJvdG9jb2wgPSBJTVBMSUNJVF9QUk9UT0NPTF9SRS50ZXN0KHVybCkgPyAnaHR0cDonIDogJ2h0dHA6Ly8nO1xuXG4gICAgcmV0dXJuIHByb3RvY29sICsgdXJsO1xufVxuIl19 diff --git a/lib/api/test-run-tracker.js b/lib/api/test-run-tracker.js new file mode 100644 index 00000000..81c09a91 --- /dev/null +++ b/lib/api/test-run-tracker.js @@ -0,0 +1,114 @@ +'use strict'; + +exports.__esModule = true; + +var _callsite = require('callsite'); + +var _callsite2 = _interopRequireDefault(_callsite); + +var _promise = require('babel-runtime/core-js/promise'); + +var _promise2 = _interopRequireDefault(_promise); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const TRACKING_MARK_RE = /^\$\$testcafe_test_run\$\$(\S+)\$\$$/; +const STACK_CAPACITY = 5000; + +// Tracker +exports.default = { + enabled: false, + + activeTestRuns: {}, + + _createContextSwitchingFunctionHook(ctxSwitchingFn, patchedArgsCount) { + const tracker = this; + + return function () { + const testRunId = tracker.getContextTestRunId(); + + if (testRunId) { + for (let i = 0; i < patchedArgsCount; i++) { + if (typeof arguments[i] === 'function') arguments[i] = tracker.addTrackingMarkerToFunction(testRunId, arguments[i]); + } + } + + return ctxSwitchingFn.apply(this, arguments); + }; + }, + + _getStackFrames() { + // NOTE: increase stack capacity to seek deep stack entries + const savedLimit = Error.stackTraceLimit; + + Error.stackTraceLimit = STACK_CAPACITY; + + const frames = (0, _callsite2.default)(); + + Error.stackTraceLimit = savedLimit; + + return frames; + }, + + ensureEnabled() { + if (!this.enabled) { + global.setTimeout = this._createContextSwitchingFunctionHook(global.setTimeout, 1); + global.setInterval = this._createContextSwitchingFunctionHook(global.setInterval, 1); + global.setImmediate = this._createContextSwitchingFunctionHook(global.setImmediate, 1); + process.nextTick = this._createContextSwitchingFunctionHook(process.nextTick, 1); + + _promise2.default.prototype.then = this._createContextSwitchingFunctionHook(_promise2.default.prototype.then, 2); + _promise2.default.prototype.catch = this._createContextSwitchingFunctionHook(_promise2.default.prototype.catch, 1); + + if (global.Promise) { + global.Promise.prototype.then = this._createContextSwitchingFunctionHook(global.Promise.prototype.then, 2); + global.Promise.prototype.catch = this._createContextSwitchingFunctionHook(global.Promise.prototype.catch, 1); + } + + this.enabled = true; + } + }, + + addTrackingMarkerToFunction(testRunId, fn) { + const markerFactoryBody = ` + return function $$testcafe_test_run$$${testRunId}$$ () { + switch (arguments.length) { + case 0: return fn.call(this); + case 1: return fn.call(this, arguments[0]); + case 2: return fn.call(this, arguments[0], arguments[1]); + case 3: return fn.call(this, arguments[0], arguments[1], arguments[2]); + case 4: return fn.call(this, arguments[0], arguments[1], arguments[2], arguments[3]); + default: return fn.apply(this, arguments); + } + }; + `; + + return new Function('fn', markerFactoryBody)(fn); + }, + + getContextTestRunId() { + const frames = this._getStackFrames(); + + // OPTIMIZATION: we start traversing from the bottom of the stack, + // because we'll more likely encounter a marker there. + // Async/await and Promise machinery executes lots of intrinsics + // on timers (where we have a marker). And, since a timer initiates a new + // stack, the marker will be at the very bottom of it. + for (let i = frames.length - 1; i >= 0; i--) { + const fnName = frames[i].getFunctionName(); + const match = fnName && fnName.match(TRACKING_MARK_RE); + + if (match) return match[1]; + } + + return null; + }, + + resolveContextTestRun() { + const testRunId = this.getContextTestRunId(); + + return this.activeTestRuns[testRunId]; + } +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvdGVzdC1ydW4tdHJhY2tlci5qcyJdLCJuYW1lcyI6WyJUUkFDS0lOR19NQVJLX1JFIiwiU1RBQ0tfQ0FQQUNJVFkiLCJlbmFibGVkIiwiYWN0aXZlVGVzdFJ1bnMiLCJfY3JlYXRlQ29udGV4dFN3aXRjaGluZ0Z1bmN0aW9uSG9vayIsImN0eFN3aXRjaGluZ0ZuIiwicGF0Y2hlZEFyZ3NDb3VudCIsInRyYWNrZXIiLCJ0ZXN0UnVuSWQiLCJnZXRDb250ZXh0VGVzdFJ1bklkIiwiaSIsImFyZ3VtZW50cyIsImFkZFRyYWNraW5nTWFya2VyVG9GdW5jdGlvbiIsImFwcGx5IiwiX2dldFN0YWNrRnJhbWVzIiwic2F2ZWRMaW1pdCIsIkVycm9yIiwic3RhY2tUcmFjZUxpbWl0IiwiZnJhbWVzIiwiZW5zdXJlRW5hYmxlZCIsImdsb2JhbCIsInNldFRpbWVvdXQiLCJzZXRJbnRlcnZhbCIsInNldEltbWVkaWF0ZSIsInByb2Nlc3MiLCJuZXh0VGljayIsIkJhYmVsUHJvbWlzZSIsInByb3RvdHlwZSIsInRoZW4iLCJjYXRjaCIsIlByb21pc2UiLCJmbiIsIm1hcmtlckZhY3RvcnlCb2R5IiwiRnVuY3Rpb24iLCJsZW5ndGgiLCJmbk5hbWUiLCJnZXRGdW5jdGlvbk5hbWUiLCJtYXRjaCIsInJlc29sdmVDb250ZXh0VGVzdFJ1biJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBOzs7O0FBQ0E7Ozs7OztBQUVBLE1BQU1BLG1CQUFtQixzQ0FBekI7QUFDQSxNQUFNQyxpQkFBbUIsSUFBekI7O0FBRUE7a0JBQ2U7QUFDWEMsYUFBUyxLQURFOztBQUdYQyxvQkFBZ0IsRUFITDs7QUFLWEMsd0NBQXFDQyxjQUFyQyxFQUFxREMsZ0JBQXJELEVBQXVFO0FBQ25FLGNBQU1DLFVBQVUsSUFBaEI7O0FBRUEsZUFBTyxZQUFZO0FBQ2Ysa0JBQU1DLFlBQVlELFFBQVFFLG1CQUFSLEVBQWxCOztBQUVBLGdCQUFJRCxTQUFKLEVBQWU7QUFDWCxxQkFBSyxJQUFJ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QXhGVTs7QUEwRlhDLDRCQUF5QjtBQUNyQixjQUFNOUIsWUFBWSxLQUFLQyxtQkFBTCxFQUFsQjs7QUFFQSxlQUFPLEtBQUtOLGNBQUwsQ0FBb0JLLFNBQXBCLENBQVA7QUFDSDtBQTlGVSxDIiwiZmlsZSI6ImFwaS90ZXN0LXJ1bi10cmFja2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGdldFN0YWNrRnJhbWVzIGZyb20gJ2NhbGxzaXRlJztcbmltcG9ydCBCYWJlbFByb21pc2UgZnJvbSAnYmFiZWwtcnVudGltZS9jb3JlLWpzL3Byb21pc2UnO1xuXG5jb25zdCBUUkFDS0lOR19NQVJLX1JFID0gL15cXCRcXCR0ZXN0Y2FmZV90ZXN0X3J1blxcJFxcJChcXFMrKVxcJFxcJCQvO1xuY29uc3QgU1RBQ0tfQ0FQQUNJVFkgICA9IDUwMDA7XG5cbi8vIFRyYWNrZXJcbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBlbmFibGVkOiBmYWxzZSxcblxuICAgIGFjdGl2ZVRlc3RSdW5zOiB7fSxcblxuICAgIF9jcmVhdGVDb250ZXh0U3dpdGNoaW5nRnVuY3Rpb25Ib29rIChjdHhTd2l0Y2hpbmdGbiwgcGF0Y2hlZEFyZ3NDb3VudCkge1xuICAgICAgICBjb25zdCB0cmFja2VyID0gdGhpcztcblxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgdGVzdFJ1bklkID0gdHJhY2tlci5nZXRDb250ZXh0VGVzdFJ1bklkKCk7XG5cbiAgICAgICAgICAgIGlmICh0ZXN0UnVuSWQpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdGNoZWRBcmdzQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1tpXSA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3VtZW50c1tpXSA9IHRyYWNrZXIuYWRkVHJhY2tpbmdNYXJrZXJUb0Z1bmN0aW9uKHRlc3RSdW5JZCwgYXJndW1lbnRzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBjdHhTd2l0Y2hpbmdGbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBfZ2V0U3RhY2tGcmFtZXMgKCkge1xuICAgICAgICAvLyBOT1RFOiBpbmNyZWFzZSBzdGFjayBjYXBhY2l0eSB0byBzZWVrIGRlZXAgc3RhY2sgZW50cmllc1xuICAgICAgICBjb25zdCBzYXZlZExpbWl0ID0gRXJyb3Iuc3RhY2tUcmFjZUxpbWl0O1xuXG4gICAgICAgIEVycm9yLnN0YWNrVHJhY2VMaW1pdCA9IFNUQUNLX0NBUEFDSVRZO1xuXG4gICAgICAgIGNvbnN0IGZyYW1lcyA9IGdldFN0YWNrRnJhbWVzKCk7XG5cbiAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID0gc2F2ZWRMaW1pdDtcblxuICAgICAgICByZXR1cm4gZnJhbWVzO1xuICAgIH0sXG5cbiAgICBlbnN1cmVFbmFibGVkICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmVuYWJsZWQpIHtcbiAgICAgICAgICAgIGdsb2JhbC5zZXRUaW1lb3V0ICAgPSB0aGlzLl9jcmVhdGVDb250ZXh0U3dpdGNoaW5nRnVuY3Rpb25Ib29rKGdsb2JhbC5zZXRUaW1lb3V0LCAxKTtcbiAgICAgICAgICAgIGdsb2JhbC5zZXRJbnRlcnZhbCAgPSB0aGlzLl9jcmVhdGVDb250ZXh0U3dpdGNoaW5nRnVuY3Rpb25Ib29rKGdsb2JhbC5zZXRJbnRlcnZhbCwgMSk7XG4gICAgICAgICAgICBnbG9iYWwuc2V0SW1tZWRpYXRlID0gdGhpcy5fY3JlYXRlQ29udGV4dFN3aXRjaGluZ0Z1bmN0aW9uSG9vayhnbG9iYWwuc2V0SW1tZWRpYXRlLCAxKTtcbiAgICAgICAgICAgIHByb2Nlc3MubmV4dFRpY2sgICAgPSB0aGlzLl9jcmVhdGVDb250ZXh0U3dpdGNoaW5nRnVuY3Rpb25Ib29rKHByb2Nlc3MubmV4dFRpY2ssIDEpO1xuXG4gICAgICAgICAgICBCYWJlbFByb21pc2UucHJvdG90eXBlLnRoZW4gID0gdGhpcy5fY3JlYXRlQ29udGV4dFN3aXRjaGluZ0Z1bmN0aW9uSG9vayhCYWJlbFByb21pc2UucHJvdG90eXBlLnRoZW4sIDIpO1xuICAgICAgICAgICAgQmFiZWxQcm9taXNlLnByb3RvdHlwZS5jYXRjaCA9IHRoaXMuX2NyZWF0ZUNvbnRleHRTd2l0Y2hpbmdGdW5jdGlvbkhvb2soQmFiZWxQcm9taXNlLnByb3RvdHlwZS5jYXRjaCwgMSk7XG5cbiAgICAgICAgICAgIGlmIChnbG9iYWwuUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIGdsb2JhbC5Qcm9taXNlLnByb3RvdHlwZS50aGVuICA9IHRoaXMuX2NyZWF0ZUNvbnRleHRTd2l0Y2hpbmdGdW5jdGlvbkhvb2soZ2xvYmFsLlByb21pc2UucHJvdG90eXBlLnRoZW4sIDIpO1xuICAgICAgICAgICAgICAgIGdsb2JhbC5Qcm9taXNlLnByb3RvdHlwZS5jYXRjaCA9IHRoaXMuX2NyZWF0ZUNvbnRleHRTd2l0Y2hpbmdGdW5jdGlvbkhvb2soZ2xvYmFsLlByb21pc2UucHJvdG90eXBlLmNhdGNoLCAxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5lbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBhZGRUcmFja2luZ01hcmtlclRvRnVuY3Rpb24gKHRlc3RSdW5JZCwgZm4pIHtcbiAgICAgICAgY29uc3QgbWFya2VyRmFjdG9yeUJvZHkgPSBgXG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gJCR0ZXN0Y2FmZV90ZXN0X3J1biQkJHt0ZXN0UnVuSWR9JCQgKCkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDA6IHJldHVybiBmbi5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IHJldHVybiBmbi5jYWxsKHRoaXMsIGFyZ3VtZW50c1swXSk7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjogcmV0dXJuIGZuLmNhbGwodGhpcywgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IHJldHVybiBmbi5jYWxsKHRoaXMsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IHJldHVybiBmbi5jYWxsKHRoaXMsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0sIGFyZ3VtZW50c1szXSk7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIGA7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBGdW5jdGlvbignZm4nLCBtYXJrZXJGYWN0b3J5Qm9keSkoZm4pO1xuICAgIH0sXG5cbiAgICBnZXRDb250ZXh0VGVzdFJ1bklkICgpIHtcbiAgICAgICAgY29uc3QgZnJhbWVzID0gdGhpcy5fZ2V0U3RhY2tGcmFtZXMoKTtcblxuICAgICAgICAvLyBPUFRJTUlaQVRJT046IHdlIHN0YXJ0IHRyYXZlcnNpbmcgZnJvbSB0aGUgYm90dG9tIG9mIHRoZSBzdGFjayxcbiAgICAgICAgLy8gYmVjYXVzZSB3ZSdsbCBtb3JlIGxpa2VseSBlbmNvdW50ZXIgYSBtYXJrZXIgdGhlcmUuXG4gICAgICAgIC8vIEFzeW5jL2F3YWl0IGFuZCBQcm9taXNlIG1hY2hpbmVyeSBleGVjdXRlcyBsb3RzIG9mIGludHJpbnNpY3NcbiAgICAgICAgLy8gb24gdGltZXJzICh3aGVyZSB3ZSBoYXZlIGEgbWFya2VyKS4gQW5kLCBzaW5jZSBhIHRpbWVyIGluaXRpYXRlcyBhIG5ld1xuICAgICAgICAvLyBzdGFjaywgdGhlIG1hcmtlciB3aWxsIGJlIGF0IHRoZSB2ZXJ5IGJvdHRvbSBvZiBpdC5cbiAgICAgICAgZm9yIChsZXQgaSA9IGZyYW1lcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgY29uc3QgZm5OYW1lID0gZnJhbWVzW2ldLmdldEZ1bmN0aW9uTmFtZSgpO1xuICAgICAgICAgICAgY29uc3QgbWF0Y2ggID0gZm5OYW1lICYmIGZuTmFtZS5tYXRjaChUUkFDS0lOR19NQVJLX1JFKTtcblxuICAgICAgICAgICAgaWYgKG1hdGNoKVxuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaFsxXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0sXG5cbiAgICByZXNvbHZlQ29udGV4dFRlc3RSdW4gKCkge1xuICAgICAgICBjb25zdCB0ZXN0UnVuSWQgPSB0aGlzLmdldENvbnRleHRUZXN0UnVuSWQoKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5hY3RpdmVUZXN0UnVuc1t0ZXN0UnVuSWRdO1xuICAgIH1cbn07XG4iXX0= diff --git a/lib/api/wrap-test-function.js b/lib/api/wrap-test-function.js new file mode 100644 index 00000000..d2b8f6d0 --- /dev/null +++ b/lib/api/wrap-test-function.js @@ -0,0 +1,61 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +exports.default = wrapTestFunction; + +var _testController = require('./test-controller'); + +var _testController2 = _interopRequireDefault(_testController); + +var _testRunTracker = require('./test-run-tracker'); + +var _testRunTracker2 = _interopRequireDefault(_testRunTracker); + +var _errorList = require('../errors/error-list'); + +var _errorList2 = _interopRequireDefault(_errorList); + +var _testRun = require('../errors/test-run'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function wrapTestFunction(fn) { + return (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (testRun) { + let result = null; + const errList = new _errorList2.default(); + const markeredfn = _testRunTracker2.default.addTrackingMarkerToFunction(testRun.id, fn); + + testRun.controller = new _testController2.default(testRun); + + _testRunTracker2.default.ensureEnabled(); + + try { + result = yield markeredfn(testRun.controller); + } catch (err) { + errList.addError(err); + } + + if (!errList.hasUncaughtErrorsInTestCode) { + testRun.controller.callsitesWithoutAwait.forEach(function (callsite) { + errList.addError(new _testRun.MissingAwaitError(callsite)); + }); + } + + if (errList.hasErrors) throw errList; + + return result; + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; + })(); +} +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvd3JhcC10ZXN0LWZ1bmN0aW9uLmpzIl0sIm5hbWVzIjpbIndyYXBUZXN0RnVuY3Rpb24iLCJmbiIsInRlc3RSdW4iLCJyZXN1bHQiLCJlcnJMaXN0IiwiVGVzdENhZmVFcnJvckxpc3QiLCJtYXJrZXJlZGZuIiwidGVzdFJ1blRyYWNrZXIiLCJhZGRUcmFja2luZ01hcmtlclRvRnVuY3Rpb24iLCJpZCIsImNvbnRyb2xsZXIiLCJUZXN0Q29udHJvbGxlciIsImVuc3VyZUVuYWJsZWQiLCJlcnIiLCJhZGRFcnJvciIsImhhc1VuY2F1Z2h0RXJyb3JzSW5UZXN0Q29kZSIsImNhbGxzaXRlc1dpdGhvdXRBd2FpdCIsImZvckVhY2giLCJNaXNzaW5nQXdhaXRFcnJvciIsImNhbGxzaXRlIiwiaGFzRXJyb3JzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztrQkFLd0JBLGdCOztBQUx4Qjs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUVlLFNBQVNBLGdCQUFULENBQTJCQyxFQUEzQixFQUErQjtBQUMxQztBQUFBLG1EQUFPLFdBQU1DLE9BQU4sRUFBaUI7QUFDcEIsZ0JBQUlDLFNBQWUsSUFBbkI7QUFDQSxrQkFBTUMsVUFBYSxJQUFJQyxtQkFBSixFQUFuQjtBQUNBLGtCQUFNQyxhQUFhQyx5QkFBZUMsMkJBQWYsQ0FBMkNOLFFBQVFPLEVBQW5ELEVBQXVEUixFQUF2RCxDQUFuQjs7QUFFQUMsb0JBQVFRLFVBQVIsR0FBcUIsSUFBSUMsd0JBQUosQ0FBbUJULE9BQW5CLENBQXJCOztBQUVBSyxxQ0FBZUssYUFBZjs7QUFFQSxnQkFBSTtBQUNBVCx5QkFBUyxNQUFNRyxXQUFXSixRQUFRUSxVQUFuQixDQUFmO0FBQ0gsYUFGRCxDQUdBLE9BQU9HLEdBQVAsRUFBWTtBQUNSVCx3QkFBUVUsUUFBUixDQUFpQkQsR0FBakI7QUFDSDs7QUFFRCxnQkFBSSxDQUFDVCxRQUFRVywyQkFBYixFQUEwQztBQUN0Q2Isd0JBQVFRLFVBQVIsQ0FBbUJNLHFCQUFuQixDQUF5Q0MsT0FBekMsQ0FBaUQsb0JBQVk7QUFDekRiLDRCQUFRVSxRQUFSLENBQWlCLElBQUlJLDBCQUFKLENBQXNCQyxRQUF0QixDQUFqQjtBQUNILGlCQUZEO0FBR0g7O0FBRUQsZ0JBQUlmLFFBQVFnQixTQUFaLEVBQ0ksTUFBTWhCLE9BQU47O0FBRUosbUJBQU9ELE1BQVA7QUFDSCxTQTFCRDs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQTJCSCIsImZpbGUiOiJhcGkvd3JhcC10ZXN0LWZ1bmN0aW9uLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFRlc3RDb250cm9sbGVyIGZyb20gJy4vdGVzdC1jb250cm9sbGVyJztcbmltcG9ydCB0ZXN0UnVuVHJhY2tlciBmcm9tICcuL3Rlc3QtcnVuLXRyYWNrZXInO1xuaW1wb3J0IFRlc3RDYWZlRXJyb3JMaXN0IGZyb20gJy4uL2Vycm9ycy9lcnJvci1saXN0JztcbmltcG9ydCB7IE1pc3NpbmdBd2FpdEVycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3Rlc3QtcnVuJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gd3JhcFRlc3RGdW5jdGlvbiAoZm4pIHtcbiAgICByZXR1cm4gYXN5bmMgdGVzdFJ1biA9PiB7XG4gICAgICAgIGxldCByZXN1bHQgICAgICAgPSBudWxsO1xuICAgICAgICBjb25zdCBlcnJMaXN0ICAgID0gbmV3IFRlc3RDYWZlRXJyb3JMaXN0KCk7XG4gICAgICAgIGNvbnN0IG1hcmtlcmVkZm4gPSB0ZXN0UnVuVHJhY2tlci5hZGRUcmFja2luZ01hcmtlclRvRnVuY3Rpb24odGVzdFJ1bi5pZCwgZm4pO1xuXG4gICAgICAgIHRlc3RSdW4uY29udHJvbGxlciA9IG5ldyBUZXN0Q29udHJvbGxlcih0ZXN0UnVuKTtcblxuICAgICAgICB0ZXN0UnVuVHJhY2tlci5lbnN1cmVFbmFibGVkKCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IG1hcmtlcmVkZm4odGVzdFJ1bi5jb250cm9sbGVyKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBlcnJMaXN0LmFkZEVycm9yKGVycik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWVyckxpc3QuaGFzVW5jYXVnaHRFcnJvcnNJblRlc3RDb2RlKSB7XG4gICAgICAgICAgICB0ZXN0UnVuLmNvbnRyb2xsZXIuY2FsbHNpdGVzV2l0aG91dEF3YWl0LmZvckVhY2goY2FsbHNpdGUgPT4ge1xuICAgICAgICAgICAgICAgIGVyckxpc3QuYWRkRXJyb3IobmV3IE1pc3NpbmdBd2FpdEVycm9yKGNhbGxzaXRlKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlcnJMaXN0Lmhhc0Vycm9ycylcbiAgICAgICAgICAgIHRocm93IGVyckxpc3Q7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xufVxuIl19 diff --git a/lib/assertions/executor.js b/lib/assertions/executor.js new file mode 100644 index 00000000..5dc63cea --- /dev/null +++ b/lib/assertions/executor.js @@ -0,0 +1,105 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _events = require('events'); + +var _delay = require('../utils/delay'); + +var _delay2 = _interopRequireDefault(_delay); + +var _thennable = require('../utils/thennable'); + +var _testRun = require('../errors/test-run'); + +var _reExecutablePromise = require('../utils/re-executable-promise'); + +var _reExecutablePromise2 = _interopRequireDefault(_reExecutablePromise); + +var _getFn = require('./get-fn'); + +var _getFn2 = _interopRequireDefault(_getFn); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const ASSERTION_DELAY = 200; + +class AssertionExecutor extends _events.EventEmitter { + constructor(command, timeout, callsite) { + super(); + + this.command = command; + this.timeout = timeout; + this.callsite = callsite; + + this.startTime = null; + this.passed = false; + this.inRetry = false; + + const fn = (0, _getFn2.default)(this.command); + const actualCommand = this.command.actual; + + if (actualCommand instanceof _reExecutablePromise2.default) this.fn = this._wrapFunction(fn);else if (!this.command.options.allowUnawaitedPromise && (0, _thennable.isThennable)(actualCommand)) throw new _testRun.AssertionUnawaitedPromiseError(this.callsite);else this.fn = fn; + } + + _getTimeLeft() { + return this.timeout - (new Date() - this.startTime); + } + + _onExecutionFinished() { + if (this.inRetry) this.emit('end-assertion-retries', this.passed); + } + + _wrapFunction(fn) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + const resultPromise = _this.command.actual; + + while (!_this.passed) { + _this.command.actual = yield resultPromise._reExecute(); + + try { + fn(); + _this.passed = true; + _this._onExecutionFinished(); + } catch (err) { + if (_this._getTimeLeft() <= 0) { + _this._onExecutionFinished(); + throw err; + } + + yield (0, _delay2.default)(ASSERTION_DELAY); + + _this.inRetry = true; + _this.emit('start-assertion-retries', _this._getTimeLeft()); + } + } + }); + } + + run() { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this2.startTime = new Date(); + + try { + yield _this2.fn(); + } catch (err) { + if (err.name === 'AssertionError' || err.constructor.name === 'AssertionError') throw new _testRun.ExternalAssertionLibraryError(err, _this2.callsite); + + if (err.isTestCafeError) err.callsite = _this2.callsite; + + throw err; + } + })(); + } +} +exports.default = AssertionExecutor; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hc3NlcnRpb25zL2V4ZWN1dG9yLmpzIl0sIm5hbWVzIjpbIkFTU0VSVElPTl9ERUxBWSIsIkFzc2VydGlvbkV4ZWN1dG9yIiwiRXZlbnRFbWl0dGVyIiwiY29uc3RydWN0b3IiLCJjb21tYW5kIiwidGltZW91dCIsImNhbGxzaXRlIiwic3RhcnRUaW1lIiwicGFzc2VkIiwiaW5SZXRyeSIsImZuIiwiYWN0dWFsQ29tbWFuZCIsImFjdHVhbCIsIlJlRXhlY3V0YWJsZVByb21pc2UiLCJfd3JhcEZ1bmN0aW9uIiwib3B0aW9ucyIsImFsbG93VW5hd2FpdGVkUHJvbWlzZSIsIkFzc2VydGlvblVuYXdhaXRlZFByb21pc2VFcnJvciIsIl9nZXRUaW1lTGVmdCIsIkRhdGUiLCJfb25FeGVjdXRpb25GaW5pc2hlZCIsImVtaXQiLCJyZXN1bHRQcm9taXNlIiwiX3JlRXhlY3V0ZSIsImVyciIsInJ1biIsIm5hbWUiLCJFeHRlcm5hbEFzc2VydGlvbkxpYnJhcnlFcnJvciIsImlzVGVzdENhZmVFcnJvciJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQTs7QUFDQTs7OztBQUNBOztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7OztBQUVBLE1BQU1BLGtCQUFrQixHQUF4Qjs7QUFFZSxNQUFNQyxpQkFBTixTQUFnQ0Msb0JBQWhDLENBQTZDO0FBQ3hEQyxnQkFBYUMsT0FBYixFQUFzQkMsT0FBdEIsRUFBK0JDLFFBQS9CLEVBQXlDO0FBQ3JDOztBQUVBLGFBQUtGLE9BQUwsR0FBZ0JBLE9BQWhCO0FBQ0EsYUFBS0MsT0FBTCxHQUFnQkEsT0FBaEI7QUFDQSxhQUFLQyxRQUFMLEdBQWdCQSxRQUFoQjs7QUFFQSxhQUFLQyxTQUFMLEdBQWlCLElBQWpCO0FBQ0EsYUFBS0MsTUFBTCxHQUFpQixLQUFqQjtBQUNBLGFBQUtDLE9BQUwsR0FBaUIsS0FBakI7O0FBRUEsY0FBTUMsS0FBZ0IscUJBQU0sS0FBS04sT0FBWCxDQUF0QjtBQUNBLGNBQU1PLGdCQUFnQixLQUFLUCxPQUFMLENBQWFRLE1BQW5DOztBQUVBLFlBQUlELHlCQUF5QkUsNkJBQTdCLEVBQ0ksS0FBS0gsRUFBTCxHQUFVLEtBQUtJLGFBQUwsQ0FBbUJKLEVBQW5CLENBQVYsQ0FESixLQUVLLElBQUksQ0FBQyxLQUFLTixPQUFMLENBQWFXLE9BQWIsQ0FBcUJDLHFCQUF0QixJQUErQyw0QkFBWUwsYUFBWixDQUFuRCxFQUNELE1BQU0sSUFBSU0sdUNBQUosQ0FBbUMsS0FBS1gsUUFBeEMsQ0FBTixDQURDLEtBR0QsS0FBS0ksRUFBTCxHQUFVQSxFQUFWO0FBQ1A7O0FBRURRLG1CQUFnQjtBQUNaLGVBQU8sS0FBS2IsT0FBTCxJQUFnQixJQUFJYyxJQUFKLEtBQWEsS0FBS1osU0FBbEMsQ0FBUDtBQUNIOztBQUVEYSwyQkFBd0I7QUFDcEIsWUFBSSxLQUFLWCxPQUFULEVBQ0ksS0FBS1ksSUFBTCxDQUFVLHVCQUFWLEVBQW1DLEtBQUtiLE1BQXhDO0FBQ1A7O0FBRURNLGtCQUFlSixFQUFmLEVBQW1CO0FBQUE7O0FBQ2YsK0NBQU8sYUFBWTtBQUNmLGtCQUFNWSxnQkFBZ0IsTUFBS2xCLE9BQUwsQ0FBYVEsTUFBbkM7O0FBRUEsbUJBQU8sQ0FBQyxNQUFLSixNQUFiLEVBQXFCO0FBQ2pCLHNCQUFLSixPQUFMLENBQWFRLE1BQWIsR0FBc0IsTUFBTVUsY0FBY0MsVUFBZCxFQUE1Qjs7QUFFQSxvQkFBSTtBQUNBYjtBQUNBLDBCQUFLRixNQUFMLEdBQWMsSUFBZDtBQUNBLDBCQUFLWSxvQkFBTDtBQUNILGlCQUpELENBTUEsT0FBT0ksR0FBUCxFQUFZO0FBQ1Isd0JBQUksTUFBS04sWUFBTCxNQUF1QixDQUEzQixFQUE4QjtBQUMxQiw4QkFBS0Usb0JBQUw7QUFDQSw4QkFBTUksR0FBTjtBQUNIOztBQUVELDBCQUFNLHFCQUFNeEIsZUFBTixDQUFOOztBQUVBLDBCQUFLUyxPQUFMLEdBQWUsSUFBZjtBQUNBLDBCQUFLWSxJQUFMLENBQVUseUJBQVYsRUFBcUMsTUFBS0gsWUFBTCxFQUFyQztBQUNIO0FBQ0o7QUFDSixTQXhCRDtBQXlCSDs7QUFFS08sT0FBTixHQUFhO0FBQUE7O0FBQUE7QUFDVCxtQkFBS2xCLFNBQUwsR0FBaUIsSUFBSVksSUFBSixFQUFqQjs7QUFFQSxnQkFBSTtBQUNBLHNCQUFNLE9BQUtULEVBQUwsRUFBTjtBQUNILGFBRkQsQ0FJQSxPQUFPYyxHQUFQLEVBQVk7QUFDUixvQkFBSUEsSUFBSUUsSUFBSixLQUFhLGdCQUFiLElBQWlDRixJQUFJckIsV0FBSixDQUFnQnVCLElBQWhCLEtBQXlCLGdCQUE5RCxFQUNJLE1BQU0sSUFBSUMsc0NBQUosQ0FBa0NILEdBQWxDLEVBQXVDLE9BQUtsQixRQUE1QyxDQUFOOztBQUVKLG9CQUFJa0IsSUFBSUksZUFBUixFQUNJSixJQUFJbEIsUUFBSixHQUFlLE9BQUtBLFFBQXBCOztBQUVKLHNCQUFNa0IsR0FBTjtBQUNIO0FBZlE7QUFnQlo7QUE1RXVEO2tCQUF2Q3ZCLGlCIiwiZmlsZSI6ImFzc2VydGlvbnMvZXhlY3V0b3IuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdldmVudHMnO1xuaW1wb3J0IGRlbGF5IGZyb20gJy4uL3V0aWxzL2RlbGF5JztcbmltcG9ydCB7IGlzVGhlbm5hYmxlIH0gZnJvbSAnLi4vdXRpbHMvdGhlbm5hYmxlJztcbmltcG9ydCB7IEV4dGVybmFsQXNzZXJ0aW9uTGlicmFyeUVycm9yLCBBc3NlcnRpb25VbmF3YWl0ZWRQcm9taXNlRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvdGVzdC1ydW4nO1xuaW1wb3J0IFJlRXhlY3V0YWJsZVByb21pc2UgZnJvbSAnLi4vdXRpbHMvcmUtZXhlY3V0YWJsZS1wcm9taXNlJztcbmltcG9ydCBnZXRGbiBmcm9tICcuL2dldC1mbic7XG5cbmNvbnN0IEFTU0VSVElPTl9ERUxBWSA9IDIwMDtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQXNzZXJ0aW9uRXhlY3V0b3IgZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yIChjb21tYW5kLCB0aW1lb3V0LCBjYWxsc2l0ZSkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXMuY29tbWFuZCAgPSBjb21tYW5kO1xuICAgICAgICB0aGlzLnRpbWVvdXQgID0gdGltZW91dDtcbiAgICAgICAgdGhpcy5jYWxsc2l0ZSA9IGNhbGxzaXRlO1xuXG4gICAgICAgIHRoaXMuc3RhcnRUaW1lID0gbnVsbDtcbiAgICAgICAgdGhpcy5wYXNzZWQgICAgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pblJldHJ5ICAgPSBmYWxzZTtcblxuICAgICAgICBjb25zdCBmbiAgICAgICAgICAgID0gZ2V0Rm4odGhpcy5jb21tYW5kKTtcbiAgICAgICAgY29uc3QgYWN0dWFsQ29tbWFuZCA9IHRoaXMuY29tbWFuZC5hY3R1YWw7XG5cbiAgICAgICAgaWYgKGFjdHVhbENvbW1hbmQgaW5zdGFuY2VvZiBSZUV4ZWN1dGFibGVQcm9taXNlKVxuICAgICAgICAgICAgdGhpcy5mbiA9IHRoaXMuX3dyYXBGdW5jdGlvbihmbik7XG4gICAgICAgIGVsc2UgaWYgKCF0aGlzLmNvbW1hbmQub3B0aW9ucy5hbGxvd1VuYXdhaXRlZFByb21pc2UgJiYgaXNUaGVubmFibGUoYWN0dWFsQ29tbWFuZCkpXG4gICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uVW5hd2FpdGVkUHJvbWlzZUVycm9yKHRoaXMuY2FsbHNpdGUpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLmZuID0gZm47XG4gICAgfVxuXG4gICAgX2dldFRpbWVMZWZ0ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGltZW91dCAtIChuZXcgRGF0ZSgpIC0gdGhpcy5zdGFydFRpbWUpO1xuICAgIH1cblxuICAgIF9vbkV4ZWN1dGlvbkZpbmlzaGVkICgpIHtcbiAgICAgICAgaWYgKHRoaXMuaW5SZXRyeSlcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZW5kLWFzc2VydGlvbi1yZXRyaWVzJywgdGhpcy5wYXNzZWQpO1xuICAgIH1cblxuICAgIF93cmFwRnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHRQcm9taXNlID0gdGhpcy5jb21tYW5kLmFjdHVhbDtcblxuICAgICAgICAgICAgd2hpbGUgKCF0aGlzLnBhc3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29tbWFuZC5hY3R1YWwgPSBhd2FpdCByZXN1bHRQcm9taXNlLl9yZUV4ZWN1dGUoKTtcblxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGZuKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFzc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb25FeGVjdXRpb25GaW5pc2hlZCgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX2dldFRpbWVMZWZ0KCkgPD0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fb25FeGVjdXRpb25GaW5pc2hlZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZGVsYXkoQVNTRVJUSU9OX0RFTEFZKTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluUmV0cnkgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ3N0YXJ0LWFzc2VydGlvbi1yZXRyaWVzJywgdGhpcy5fZ2V0VGltZUxlZnQoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGFzeW5jIHJ1biAoKSB7XG4gICAgICAgIHRoaXMuc3RhcnRUaW1lID0gbmV3IERhdGUoKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5mbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKGVyci5uYW1lID09PSAnQXNzZXJ0aW9uRXJyb3InIHx8IGVyci5jb25zdHJ1Y3Rvci5uYW1lID09PSAnQXNzZXJ0aW9uRXJyb3InKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeHRlcm5hbEFzc2VydGlvbkxpYnJhcnlFcnJvcihlcnIsIHRoaXMuY2FsbHNpdGUpO1xuXG4gICAgICAgICAgICBpZiAoZXJyLmlzVGVzdENhZmVFcnJvcilcbiAgICAgICAgICAgICAgICBlcnIuY2FsbHNpdGUgPSB0aGlzLmNhbGxzaXRlO1xuXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0= diff --git a/lib/assertions/get-fn.js b/lib/assertions/get-fn.js new file mode 100644 index 00000000..09719d20 --- /dev/null +++ b/lib/assertions/get-fn.js @@ -0,0 +1,63 @@ +'use strict'; + +exports.__esModule = true; +exports.default = getFn; + +var _chai = require('chai'); + +function getFn(command) { + switch (command.assertionType) { + case 'eql': + return () => _chai.assert.deepEqual(command.actual, command.expected, command.message); + + case 'notEql': + return () => _chai.assert.notDeepEqual(command.actual, command.expected, command.message); + + case 'ok': + return () => _chai.assert.isOk(command.actual, command.message); + + case 'notOk': + return () => _chai.assert.isNotOk(command.actual, command.message); + + case 'contains': + return () => _chai.assert.include(command.actual, command.expected, command.message); + + case 'notContains': + return () => _chai.assert.notInclude(command.actual, command.expected, command.message); + + case 'typeOf': + return () => _chai.assert.typeOf(command.actual, command.expected, command.message); + + case 'notTypeOf': + return () => _chai.assert.notTypeOf(command.actual, command.expected, command.message); + + case 'gt': + return () => _chai.assert.isAbove(command.actual, command.expected, command.message); + + case 'gte': + return () => _chai.assert.isAtLeast(command.actual, command.expected, command.message); + + case 'lt': + return () => _chai.assert.isBelow(command.actual, command.expected, command.message); + + case 'lte': + return () => _chai.assert.isAtMost(command.actual, command.expected, command.message); + + case 'within': + return () => (0, _chai.expect)(command.actual).to.be.within(command.expected, command.expected2, command.message); + + case 'notWithin': + return () => (0, _chai.expect)(command.actual).not.to.be.within(command.expected, command.expected2, command.message); + + case 'match': + return () => _chai.assert.match(command.actual, command.expected, command.message); + + case 'notMatch': + return () => _chai.assert.notMatch(command.actual, command.expected, command.message); + + default: + return () => {}; + } +} +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hc3NlcnRpb25zL2dldC1mbi5qcyJdLCJuYW1lcyI6WyJnZXRGbiIsImNvbW1hbmQiLCJhc3NlcnRpb25UeXBlIiwiYXNzZXJ0IiwiZGVlcEVxdWFsIiwiYWN0dWFsIiwiZXhwZWN0ZWQiLCJtZXNzYWdlIiwibm90RGVlcEVxdWFsIiwiaXNPayIsImlzTm90T2siLCJpbmNsdWRlIiwibm90SW5jbHVkZSIsInR5cGVPZiIsIm5vdFR5cGVPZiIsImlzQWJvdmUiLCJpc0F0TGVhc3QiLCJpc0JlbG93IiwiaXNBdE1vc3QiLCJ0byIsImJlIiwid2l0aGluIiwiZXhwZWN0ZWQyIiwibm90IiwibWF0Y2giLCJub3RNYXRjaCJdLCJtYXBwaW5ncyI6Ijs7O2tCQUV3QkEsSzs7QUFGeEI7O0FBRWUsU0FBU0EsS0FBVCxDQUFnQkMsT0FBaEIsRUFBeUI7QUFDcEMsWUFBUUEsUUFBUUMsYUFBaEI7QUFDSSxhQUFLLEtBQUw7QUFDSSxtQkFBTyxNQUFNQyxhQUFPQyxTQUFQLENBQWlCSCxRQUFRSSxNQUF6QixFQUFpQ0osUUFBUUssUUFBekMsRUFBbURMLFFBQVFNLE9BQTNELENBQWI7O0FBRUosYUFBSyxRQUFMO0FBQ0ksbUJBQU8sTUFBTUosYUFBT0ssWUFBUCxDQUFvQlAsUUFBUUksTUFBNUIsRUFBb0NKLFFBQVFLLFFBQTVDLEVBQXNETCxRQUFRTSxPQUE5RCxDQUFiOztBQUVKLGFBQUssSUFBTDtBQUNJLG1CQUFPLE1BQU1KLGFBQU9NLElBQVAsQ0FBWVIsUUFBUUksTUFBcEIsRUFBNEJKLFFBQVFNLE9BQXBDLENBQWI7O0FBRUosYUFBSyxPQUFMO0FBQ0ksbUJBQU8sTUFBTUosYUFBT08sT0FBUCxDQUFlVCxRQUFRSSxNQUF2QixFQUErQkosUUFBUU0sT0FBdkMsQ0FBYjs7QUFFSixhQUFLLFVBQUw7QUFDSSxtQkFBTyxNQUFNSixhQUFPUSxPQUFQLENBQWVWLFFBQVFJLE1BQXZCLEVBQStCSixRQUFRSyxRQUF2QyxFQUFpREwsUUFBUU0sT0FBekQsQ0FBYjs7QUFFSixhQUFLLGFBQUw7QUFDSSxtQkFBTyxNQUFNSixhQUFPUyxVQUFQLENBQWtCWCxRQUFRSSxNQUExQixFQUFrQ0osUUFBUUssUUFBMUMsRUFBb0RMLFFBQVFNLE9BQTVELENBQWI7O0FBRUosYUFBSyxRQUFMO0FBQ0ksbUJBQU8sTUFBTUosYUFBT1UsTUFBUCxDQUFjWixRQUFRSSxNQUF0QixFQUE4QkosUUFBUUssUUFBdEMsRUFBZ0RMLFFBQVFNLE9BQXhELENBQWI7O0FBRUosYUFBSyxXQUFMO0FBQ0ksbUJBQU8sTUFBTUosYUFBT1csU0FBUCxDQUFpQmIsUUFBUUksTUFBekIsRUFBaUNKLFFBQVFLLFFBQXpDLEVBQW1ETCxRQUFRTSxPQUEzRCxDQUFiOztBQUVKLGFBQUssSUFBTDtBQUNJLG1CQUFPLE1BQU1KLGFBQU9ZLE9BQVAsQ0FBZWQsUUFBUUksTUFBdkIsRUFBK0JKLFFBQVFLLFFBQXZDLEVBQWlETCxRQUFRTSxPQUF6RCxDQUFiOztBQUVKLGFBQUssS0FBTDtBQUNJLG1CQUFPLE1BQU1KLGFBQU9hLFNBQVAsQ0FBaUJmLFFBQVFJLE1BQXpCLEVBQWlDSixRQUFRSyxRQUF6QyxFQUFtREwsUUFBUU0sT0FBM0QsQ0FBYjs7QUFFSixhQUFLLElBQUw7QUFDSSxtQkFBTyxNQUFNSixhQUFPYyxPQUFQLENBQWVoQixRQUFRSSxNQUF2QixFQUErQkosUUFBUUssUUFBdkMsRUFBaURMLFFBQVFNLE9BQXpELENBQWI7O0FBRUosYUFBSyxLQUFMO0FBQ0ksbUJBQU8sTUFBTUosYUFBT2UsUUFBUCxDQUFnQmpCLFFBQVFJLE1BQXhCLEVBQWdDSixRQUFRSyxRQUF4QyxFQUFrREwsUUFBUU0sT0FBMUQsQ0FBYjs7QUFFSixhQUFLLFFBQUw7QUFDSSxtQkFBTyxNQUFNLGtCQUFPTixRQUFRSSxNQUFmLEVBQXVCYyxFQUF2QixDQUEwQkMsRUFBMUIsQ0FBNkJDLE1BQTdCLENBQW9DcEIsUUFBUUssUUFBNUMsRUFBc0RMLFFBQVFxQixTQUE5RCxFQUF5RXJCLFFBQVFNLE9BQWpGLENBQWI7O0FBRUosYUFBSyxXQUFMO0FBQ0ksbUJBQU8sTUFBTSxrQkFBT04sUUFBUUksTUFBZixFQUF1QmtCLEdBQXZCLENBQTJCSixFQUEzQixDQUE4QkMsRUFBOUIsQ0FBaUNDLE1BQWpDLENBQXdDcEIsUUFBUUssUUFBaEQsRUFBMERMLFFBQVFxQixTQUFsRSxFQUE2RXJCLFFBQVFNLE9BQXJGLENBQWI7O0FBRUosYUFBSyxPQUFMO0FBQ0ksbUJBQU8sTUFBTUosYUFBT3FCLEtBQVAsQ0FBYXZCLFFBQVFJLE1BQXJCLEVBQTZCSixRQUFRSyxRQUFyQyxFQUErQ0wsUUFBUU0sT0FBdkQsQ0FBYjs7QUFFSixhQUFLLFVBQUw7QUFDSSxtQkFBTyxNQUFNSixhQUFPc0IsUUFBUCxDQUFnQnhCLFFBQVFJLE1BQXhCLEVBQWdDSixRQUFRSyxRQUF4QyxFQUFrREwsUUFBUU0sT0FBMUQsQ0FBYjs7QUFFSjtBQUNJLG1CQUFPLE1BQU0sQ0FDWixDQUREO0FBbERSO0FBcURIIiwiZmlsZSI6ImFzc2VydGlvbnMvZ2V0LWZuLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYXNzZXJ0LCBleHBlY3QgfSBmcm9tICdjaGFpJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Rm4gKGNvbW1hbmQpIHtcbiAgICBzd2l0Y2ggKGNvbW1hbmQuYXNzZXJ0aW9uVHlwZSkge1xuICAgICAgICBjYXNlICdlcWwnOlxuICAgICAgICAgICAgcmV0dXJuICgpID0+IGFzc2VydC5kZWVwRXF1YWwoY29tbWFuZC5hY3R1YWwsIGNvbW1hbmQuZXhwZWN0ZWQsIGNvbW1hbmQubWVzc2FnZSk7XG5cbiAgICAgICAgY2FzZSAnbm90RXFsJzpcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiBhc3NlcnQubm90RGVlcEVxdWFsKGNvbW1hbmQuYWN0dWFsLCBjb21tYW5kLmV4cGVjdGVkLCBjb21tYW5kLm1lc3NhZ2UpO1xuXG4gICAgICAgIGNhc2UgJ29rJzpcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiBhc3NlcnQuaXNPayhjb21tYW5kLmFjdHVhbCwgY29tbWFuZC5tZXNzYWdlKTtcblxuICAgICAgICBjYXNlICdub3RPayc6XG4gICAgICAgICAgICByZXR1cm4gKCkgPT4gYXNzZXJ0LmlzTm90T2soY29tbWFuZC5hY3R1YWwsIGNvbW1hbmQubWVzc2FnZSk7XG5cbiAgICAgICAgY2FzZSAnY29udGFpbnMnOlxuICAgICAgICAgICAgcmV0dXJuICgpID0+IGFzc2VydC5pbmNsdWRlKGNvbW1hbmQuYWN0dWFsLCBjb21tYW5kLmV4cGVjdGVkLCBjb21tYW5kLm1lc3NhZ2UpO1xuXG4gICAgICAgIGNhc2UgJ25vdENvbnRhaW5zJzpcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiBhc3NlcnQubm90SW5jbHVkZShjb21tYW5kLmFjdHVhbCwgY29tbWFuZC5leHBlY3RlZCwgY29tbWFuZC5tZXNzYWdlKTtcblxuICAgICAgICBjYXNlICd0eXBlT2YnOlxuICAgICAgICAgICAgcmV0dXJuICgpID0+IGFzc2VydC50eXBlT2YoY29tbWFuZC5hY3R1YWwsIGNvbW1hbmQuZXhwZWN0ZWQsIGNvbW1hbmQubWVzc2FnZSk7XG5cbiAgICAgICAgY2FzZSAnbm90VHlwZU9mJzpcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiBhc3NlcnQubm90VHlwZU9mKGNvbW1hbmQuYWN0dWFsLCBjb21tYW5kLmV4cGVjdGVkLCBjb21tYW5kLm1lc3NhZ2UpO1xuXG4gICAgICAgIGNhc2UgJ2d0JzpcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiBhc3NlcnQuaXNBYm92ZShjb21tYW5kLmFjdHVhbCwgY29tbWFuZC5leHBlY3RlZCwgY29tbWFuZC5tZXNzYWdlKTtcblxuICAgICAgICBjYXNlICdndGUnOlxuICAgICAgICAgICAgcmV0dXJuICgpID0+IGFzc2VydC5pc0F0TGVhc3QoY29tbWFuZC5hY3R1YWwsIGNvbW1hbmQuZXhwZWN0ZWQsIGNvbW1hbmQubWVzc2FnZSk7XG5cbiAgICAgICAgY2FzZSAnbHQnOlxuICAgICAgICAgICAgcmV0dXJuICgpID0+IGFzc2VydC5pc0JlbG93KGNvbW1hbmQuYWN0dWFsLCBjb21tYW5kLmV4cGVjdGVkLCBjb21tYW5kLm1lc3NhZ2UpO1xuXG4gICAgICAgIGNhc2UgJ2x0ZSc6XG4gICAgICAgICAgICByZXR1cm4gKCkgPT4gYXNzZXJ0LmlzQXRNb3N0KGNvbW1hbmQuYWN0dWFsLCBjb21tYW5kLmV4cGVjdGVkLCBjb21tYW5kLm1lc3NhZ2UpO1xuXG4gICAgICAgIGNhc2UgJ3dpdGhpbic6XG4gICAgICAgICAgICByZXR1cm4gKCkgPT4gZXhwZWN0KGNvbW1hbmQuYWN0dWFsKS50by5iZS53aXRoaW4oY29tbWFuZC5leHBlY3RlZCwgY29tbWFuZC5leHBlY3RlZDIsIGNvbW1hbmQubWVzc2FnZSk7XG5cbiAgICAgICAgY2FzZSAnbm90V2l0aGluJzpcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiBleHBlY3QoY29tbWFuZC5hY3R1YWwpLm5vdC50by5iZS53aXRoaW4oY29tbWFuZC5leHBlY3RlZCwgY29tbWFuZC5leHBlY3RlZDIsIGNvbW1hbmQubWVzc2FnZSk7XG5cbiAgICAgICAgY2FzZSAnbWF0Y2gnOlxuICAgICAgICAgICAgcmV0dXJuICgpID0+IGFzc2VydC5tYXRjaChjb21tYW5kLmFjdHVhbCwgY29tbWFuZC5leHBlY3RlZCwgY29tbWFuZC5tZXNzYWdlKTtcblxuICAgICAgICBjYXNlICdub3RNYXRjaCc6XG4gICAgICAgICAgICByZXR1cm4gKCkgPT4gYXNzZXJ0Lm5vdE1hdGNoKGNvbW1hbmQuYWN0dWFsLCBjb21tYW5kLmV4cGVjdGVkLCBjb21tYW5kLm1lc3NhZ2UpO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgfTtcbiAgICB9XG59XG4iXX0= diff --git a/lib/browser/connection/command.js b/lib/browser/connection/command.js new file mode 100644 index 00000000..93c604a8 --- /dev/null +++ b/lib/browser/connection/command.js @@ -0,0 +1,14 @@ +'use strict'; + +exports.__esModule = true; +// -------------------------------------------------------- +// WARNING: this file is used by both the client and the server. +// Do not use any browser or node-specific API! +// -------------------------------------------------------- + +exports.default = { + run: 'run', + idle: 'idle' +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2Nvbm5lY3Rpb24vY29tbWFuZC5qcyJdLCJuYW1lcyI6WyJydW4iLCJpZGxlIl0sIm1hcHBpbmdzIjoiOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7a0JBRWU7QUFDWEEsU0FBTSxLQURLO0FBRVhDLFVBQU07QUFGSyxDIiwiZmlsZSI6ImJyb3dzZXIvY29ubmVjdGlvbi9jb21tYW5kLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFdBUk5JTkc6IHRoaXMgZmlsZSBpcyB1c2VkIGJ5IGJvdGggdGhlIGNsaWVudCBhbmQgdGhlIHNlcnZlci5cbi8vIERvIG5vdCB1c2UgYW55IGJyb3dzZXIgb3Igbm9kZS1zcGVjaWZpYyBBUEkhXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgcnVuOiAgJ3J1bicsXG4gICAgaWRsZTogJ2lkbGUnXG59O1xuIl19 diff --git a/lib/browser/connection/gateway.js b/lib/browser/connection/gateway.js new file mode 100644 index 00000000..41b2ffc7 --- /dev/null +++ b/lib/browser/connection/gateway.js @@ -0,0 +1,189 @@ +'use strict'; + +exports.__esModule = true; + +var _keys = require('babel-runtime/core-js/object/keys'); + +var _keys2 = _interopRequireDefault(_keys); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _readFileRelative = require('read-file-relative'); + +var _http = require('../../utils/http'); + +var _remotesQueue = require('./remotes-queue'); + +var _remotesQueue2 = _interopRequireDefault(_remotesQueue); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Const +const IDLE_PAGE_SCRIPT = (0, _readFileRelative.readSync)('../../client/browser/idle-page/index.js'); +const IDLE_PAGE_STYLE = (0, _readFileRelative.readSync)('../../client/browser/idle-page/styles.css'); +const IDLE_PAGE_LOGO = (0, _readFileRelative.readSync)('../../client/browser/idle-page/logo.svg', true); + +// Gateway +class BrowserConnectionGateway { + constructor(proxy, options = {}) { + this.connections = {}; + this.remotesQueue = new _remotesQueue2.default(); + this.domain = proxy.server1Info.domain; + + this.connectUrl = `${this.domain}/browser/connect`; + + this.retryTestPages = options.retryTestPages; + + this._registerRoutes(proxy); + } + + _dispatch(url, proxy, handler, method = 'GET') { + proxy[method](url, (req, res, si, params) => { + const connection = this.connections[params.id]; + + (0, _http.preventCaching)(res); + + if (connection) handler(req, res, connection);else (0, _http.respond404)(res); + }); + } + + _registerRoutes(proxy) { + this._dispatch('/browser/connect/{id}', proxy, BrowserConnectionGateway.onConnection); + this._dispatch('/browser/heartbeat/{id}', proxy, BrowserConnectionGateway.onHeartbeat); + this._dispatch('/browser/idle/{id}', proxy, BrowserConnectionGateway.onIdle); + this._dispatch('/browser/idle-forced/{id}', proxy, BrowserConnectionGateway.onIdleForced); + this._dispatch('/browser/status/{id}', proxy, BrowserConnectionGateway.onStatusRequest); + this._dispatch('/browser/status-done/{id}', proxy, BrowserConnectionGateway.onStatusRequestOnTestDone); + this._dispatch('/browser/init-script/{id}', proxy, BrowserConnectionGateway.onInitScriptRequest); + this._dispatch('/browser/init-script/{id}', proxy, BrowserConnectionGateway.onInitScriptResponse, 'POST'); + + proxy.GET('/browser/connect', (req, res) => this._connectNextRemoteBrowser(req, res)); + proxy.GET('/browser/connect/', (req, res) => this._connectNextRemoteBrowser(req, res)); + + proxy.GET('/browser/assets/index.js', { content: IDLE_PAGE_SCRIPT, contentType: 'application/x-javascript' }); + proxy.GET('/browser/assets/styles.css', { content: IDLE_PAGE_STYLE, contentType: 'text/css' }); + proxy.GET('/browser/assets/logo.svg', { content: IDLE_PAGE_LOGO, contentType: 'image/svg+xml' }); + } + + // Helpers + static ensureConnectionReady(res, connection) { + if (!connection.ready) { + (0, _http.respond500)(res, 'The connection is not ready yet.'); + return false; + } + + return true; + } + + // Route handlers + static onConnection(req, res, connection) { + if (connection.ready) (0, _http.respond500)(res, 'The connection is already established.');else { + const userAgent = req.headers['user-agent']; + + connection.establish(userAgent); + (0, _http.redirect)(res, connection.idleUrl); + } + } + + static onHeartbeat(req, res, connection) { + if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { + const status = connection.heartbeat(); + + (0, _http.respondWithJSON)(res, status); + } + } + + static onIdle(req, res, connection) { + if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) res.end(connection.renderIdlePage()); + } + + static onIdleForced(req, res, connection) { + return (0, _asyncToGenerator3.default)(function* () { + if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { + const status = yield connection.getStatus(true); + + (0, _http.redirect)(res, status.url); + } + })(); + } + + static onStatusRequest(req, res, connection) { + return (0, _asyncToGenerator3.default)(function* () { + return BrowserConnectionGateway._onStatusRequestCore(req, res, connection, false); + })(); + } + + static onStatusRequestOnTestDone(req, res, connection) { + return (0, _asyncToGenerator3.default)(function* () { + return BrowserConnectionGateway._onStatusRequestCore(req, res, connection, true); + })(); + } + + static _onStatusRequestCore(req, res, connection, isTestDone) { + return (0, _asyncToGenerator3.default)(function* () { + if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { + const status = yield connection.getStatus(isTestDone); + + (0, _http.respondWithJSON)(res, status); + } + })(); + } + + static onInitScriptRequest(req, res, connection) { + if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { + const script = connection.getInitScript(); + + (0, _http.respondWithJSON)(res, script); + } + } + + static onInitScriptResponse(req, res, connection) { + if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { + let data = ''; + + req.on('data', chunk => { + data += chunk; + }); + + req.on('end', () => { + connection.handleInitScriptResult(data); + + res.end(); + }); + } + } + + _connectNextRemoteBrowser(req, res) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + (0, _http.preventCaching)(res); + + const remoteConnection = yield _this.remotesQueue.shift(); + + if (remoteConnection) (0, _http.redirect)(res, remoteConnection.url);else (0, _http.respond500)(res, 'There are no available connections to establish.'); + })(); + } + + // API + startServingConnection(connection) { + this.connections[connection.id] = connection; + + if (connection.browserInfo.providerName === 'remote') this.remotesQueue.add(connection); + } + + stopServingConnection(connection) { + delete this.connections[connection.id]; + + if (connection.browserInfo.providerName === 'remote') this.remotesQueue.remove(connection); + } + + close() { + (0, _keys2.default)(this.connections).forEach(id => this.connections[id].close()); + } +} +exports.default = BrowserConnectionGateway; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2Nvbm5lY3Rpb24vZ2F0ZXdheS5qcyJdLCJuYW1lcyI6WyJJRExFX1BBR0VfU0NSSVBUIiwiSURMRV9QQUdFX1NUWUxFIiwiSURMRV9QQUdFX0xPR08iLCJCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkiLCJjb25zdHJ1Y3RvciIsInByb3h5Iiwib3B0aW9ucyIsImNvbm5lY3Rpb25zIiwicmVtb3Rlc1F1ZXVlIiwiUmVtb3Rlc1F1ZXVlIiwiZG9tYWluIiwic2VydmVyMUluZm8iLCJjb25uZWN0VXJsIiwicmV0cnlUZXN0UGFnZXMiLCJfcmVnaXN0ZXJSb3V0ZXMiLCJfZGlzcGF0Y2giLCJ1cmwiLCJoYW5kbGVyIiwibWV0aG9kIiwicmVxIiwicmVzIiwic2kiLCJwYXJhbXMiLCJjb25uZWN0aW9uIiwiaWQiLCJvbkNvbm5lY3Rpb24iLCJvbkhlYXJ0YmVhdCIsIm9uSWRsZSIsIm9uSWRsZUZvcmNlZCIsIm9uU3RhdHVzUmVxdWVzdCIsIm9uU3RhdHVzUmVxdWVzdE9uVGVzdERvbmUiLCJvbkluaXRTY3JpcHRSZXF1ZXN0Iiwib25Jbml0U2NyaXB0UmVzcG9uc2UiLCJHRVQiLCJfY29ubmVjdE5leHRSZW1vdGVCcm93c2VyIiwiY29udGVudCIsImNvbnRlbnRUeXBlIiwiZW5zdXJlQ29ubmVjdGlvblJlYWR5IiwicmVhZHkiLCJ1c2VyQWdlbnQiLCJoZWFkZXJzIiwiZXN0YWJsaXNoIiwiaWRsZVVybCIsInN0YXR1cyIsImhlYXJ0YmVhdCIsImVuZCIsInJlbmRlcklkbGVQYWdlIiwiZ2V0U3RhdHVzIiwiX29uU3RhdHVzUmVxdWVzdENvcmUiLCJpc1Rlc3REb25lIiwic2NyaXB0IiwiZ2V0SW5pdFNjcmlwdCIsImRhdGEiLCJvbiIsImNodW5rIiwiaGFuZGxlSW5pdFNjcmlwdFJlc3VsdCIsInJlbW90ZUNvbm5lY3Rpb24iLCJzaGlmdCIsInN0YXJ0U2VydmluZ0Nvbm5lY3Rpb24iLCJicm93c2VySW5mbyIsInByb3ZpZGVyTmFtZSIsImFkZCIsInN0b3BTZXJ2aW5nQ29ubmVjdGlvbiIsInJlbW92ZSIsImNsb3NlIiwiZm9yRWFjaCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7OztBQUdBO0FBQ0EsTUFBTUEsbUJBQW1CLGdDQUFLLHlDQUFMLENBQXpCO0FBQ0EsTUFBTUMsa0JBQW1CLGdDQUFLLDJDQUFMLENBQXpCO0FBQ0EsTUFBTUMsaUJBQW1CLGdDQUFLLHlDQUFMLEVBQWdELElBQWhELENBQXpCOztBQUVBO0FBQ2UsTUFBTUMsd0JBQU4sQ0FBK0I7QUFDMUNDLGdCQUFhQyxLQUFiLEVBQW9CQyxVQUFVLEVBQTlCLEVBQWtDO0FBQzlCLGFBQUtDLFdBQUwsR0FBb0IsRUFBcEI7QUFDQSxhQUFLQyxZQUFMLEdBQW9CLElBQUlDLHNCQUFKLEVBQXBCO0FBQ0EsYUFBS0MsTUFBTCxHQUFvQkwsTUFBTU0sV0FBTixDQUFrQkQsTUFBdEM7O0FBRUEsYUFBS0UsVUFBTCxHQUFtQixHQUFFLEtBQUtGLE1BQU8sa0JBQWpDOztBQUVBLGFBQUtHLGNBQUwsR0FBc0JQLFFBQVFPLGNBQTlCOztBQUVBLGFBQUtDLGVBQUwsQ0FBcUJULEtBQXJCO0FBQ0g7O0FBRURVLGNBQVdDLEdBQVgsRUFBZ0JYLEtBQWhCLEVBQXVCWSxPQUF2QixFQUFnQ0MsU0FBUyxLQUF6QyxFQUFnRDtBQUM1Q2IsY0FBTWEsTUFBTixFQUFjRixHQUFkLEVBQW1CLENBQUNHLEdBQUQsRUFBTUMsR0FBTixFQUFXQyxFQUFYLEVBQWVDLE1BQWYsS0FBMEI7QUFDekMsa0JBQU1DLGFBQWEsS0FBS2hCLFdBQUwsQ0FBaUJlLE9BQU9FLEVBQXhCLENBQW5COztBQUVBLHNDQUFlSixHQUFmOztBQUVBLGdCQUFJRyxVQUFKLEVBQ0lOLFFBQVFFLEdBQVIsRUFBYUMsR0FBYixFQUFrQkcsVUFBbEIsRUFESixLQUdJLHNCQUFXSCxHQUFYO0FBQ1AsU0FURDtBQVVIOztBQUVETixvQkFBaUJULEtBQWpCLEVBQXdCO0FBQ3BCLGFB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QUF1QnZDLFVBQXZCLEVBQW1DO0FBQy9CLGVBQU8sS0FBS2hCLFdBQUwsQ0FBaUJnQixXQUFXQyxFQUE1QixDQUFQOztBQUVBLFlBQUlELFdBQVdvQyxXQUFYLENBQXVCQyxZQUF2QixLQUF3QyxRQUE1QyxFQUNJLEtBQUtwRCxZQUFMLENBQWtCdUQsTUFBbEIsQ0FBeUJ4QyxVQUF6QjtBQUNQOztBQUVEeUMsWUFBUztBQUNMLDRCQUFZLEtBQUt6RCxXQUFqQixFQUE4QjBELE9BQTlCLENBQXNDekMsTUFBTSxLQUFLakIsV0FBTCxDQUFpQmlCLEVBQWpCLEVBQXFCd0MsS0FBckIsRUFBNUM7QUFDSDtBQTdKeUM7a0JBQXpCN0Qsd0IiLCJmaWxlIjoiYnJvd3Nlci9jb25uZWN0aW9uL2dhdGV3YXkuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZWFkU3luYyBhcyByZWFkIH0gZnJvbSAncmVhZC1maWxlLXJlbGF0aXZlJztcbmltcG9ydCB7IHJlc3BvbmQ0MDQsIHJlc3BvbmQ1MDAsIHJlc3BvbmRXaXRoSlNPTiwgcmVkaXJlY3QsIHByZXZlbnRDYWNoaW5nIH0gZnJvbSAnLi4vLi4vdXRpbHMvaHR0cCc7XG5pbXBvcnQgUmVtb3Rlc1F1ZXVlIGZyb20gJy4vcmVtb3Rlcy1xdWV1ZSc7XG5cblxuLy8gQ29uc3RcbmNvbnN0IElETEVfUEFHRV9TQ1JJUFQgPSByZWFkKCcuLi8uLi9jbGllbnQvYnJvd3Nlci9pZGxlLXBhZ2UvaW5kZXguanMnKTtcbmNvbnN0IElETEVfUEFHRV9TVFlMRSAgPSByZWFkKCcuLi8uLi9jbGllbnQvYnJvd3Nlci9pZGxlLXBhZ2Uvc3R5bGVzLmNzcycpO1xuY29uc3QgSURMRV9QQUdFX0xPR08gICA9IHJlYWQoJy4uLy4uL2NsaWVudC9icm93c2VyL2lkbGUtcGFnZS9sb2dvLnN2ZycsIHRydWUpO1xuXG4vLyBHYXRld2F5XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkge1xuICAgIGNvbnN0cnVjdG9yIChwcm94eSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbnMgID0ge307XG4gICAgICAgIHRoaXMucmVtb3Rlc1F1ZXVlID0gbmV3IFJlbW90ZXNRdWV1ZSgpO1xuICAgICAgICB0aGlzLmRvbWFpbiAgICAgICA9IHByb3h5LnNlcnZlcjFJbmZvLmRvbWFpbjtcblxuICAgICAgICB0aGlzLmNvbm5lY3RVcmwgPSBgJHt0aGlzLmRvbWFpbn0vYnJvd3Nlci9jb25uZWN0YDtcblxuICAgICAgICB0aGlzLnJldHJ5VGVzdFBhZ2VzID0gb3B0aW9ucy5yZXRyeVRlc3RQYWdlcztcblxuICAgICAgICB0aGlzLl9yZWdpc3RlclJvdXRlcyhwcm94eSk7XG4gICAgfVxuXG4gICAgX2Rpc3BhdGNoICh1cmwsIHByb3h5LCBoYW5kbGVyLCBtZXRob2QgPSAnR0VUJykge1xuICAgICAgICBwcm94eVttZXRob2RdKHVybCwgKHJlcSwgcmVzLCBzaSwgcGFyYW1zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5jb25uZWN0aW9uc1twYXJhbXMuaWRdO1xuXG4gICAgICAgICAgICBwcmV2ZW50Q2FjaGluZyhyZXMpO1xuXG4gICAgICAgICAgICBpZiAoY29ubmVjdGlvbilcbiAgICAgICAgICAgICAgICBoYW5kbGVyKHJlcSwgcmVzLCBjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICByZXNwb25kNDA0KHJlcyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9yZWdpc3RlclJvdXRlcyAocHJveHkpIHtcbiAgICAgICAgdGhpcy5fZGlzcGF0Y2goJy9icm93c2VyL2Nvbm5lY3Qve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkub25Db25uZWN0aW9uKTtcbiAgICAgICAgdGhpcy5fZGlzcGF0Y2goJy9icm93c2VyL2hlYXJ0YmVhdC97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5vbkhlYXJ0YmVhdCk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9pZGxlL3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Lm9uSWRsZSk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9pZGxlLWZvcmNlZC97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5vbklkbGVGb3JjZWQpO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvc3RhdHVzL3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Lm9uU3RhdHVzUmVxdWVzdCk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9zdGF0dXMtZG9uZS97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5vblN0YXR1c1JlcXVlc3RPblRlc3REb25lKTtcbiAgICAgICAgdGhpcy5fZGlzcGF0Y2goJy9icm93c2VyL2luaXQtc2NyaXB0L3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Lm9uSW5pdFNjcmlwdFJlcXVlc3QpO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvaW5pdC1zY3JpcHQve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkub25Jbml0U2NyaXB0UmVzcG9uc2UsICdQT1NUJyk7XG5cbiAgICAgICAgcHJveHkuR0VUKCcvYnJvd3Nlci9jb25uZWN0JywgKHJlcSwgcmVzKSA9PiB0aGlzLl9jb25uZWN0TmV4dFJlbW90ZUJyb3dzZXIocmVxLCByZXMpKTtcbiAgICAgICAgcHJveHkuR0VUKCcvYnJvd3Nlci9jb25uZWN0LycsIChyZXEsIHJlcykgPT4gdGhpcy5fY29ubmVjdE5leHRSZW1vdGVCcm93c2VyKHJlcSwgcmVzKSk7XG5cbiAgICAgICAgcHJveHkuR0VUKCcvYnJvd3Nlci9hc3NldHMvaW5kZXguanMnLCB7IGNvbnRlbnQ6IElETEVfUEFHRV9TQ1JJUFQsIGNvbnRlbnRUeXBlOiAnYXBwbGljYXRpb24veC1qYXZhc2NyaXB0JyB9KTtcbiAgICAgICAgcHJveHkuR0VUKCcvYnJvd3Nlci9hc3NldHMvc3R5bGVzLmNzcycsIHsgY29udGVudDogSURMRV9QQUdFX1NUWUxFLCBjb250ZW50VHlwZTogJ3RleHQvY3NzJyB9KTtcbiAgICAgICAgcHJveHkuR0VUKCcvYnJvd3Nlci9hc3NldHMvbG9nby5zdmcnLCB7IGNvbnRlbnQ6IElETEVfUEFHRV9MT0dPLCBjb250ZW50VHlwZTogJ2ltYWdlL3N2Zyt4bWwnIH0pO1xuICAgIH1cblxuICAgIC8vIEhlbHBlcnNcbiAgICBzdGF0aWMgZW5zdXJlQ29ubmVjdGlvblJlYWR5IChyZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKCFjb25uZWN0aW9uLnJlYWR5KSB7XG4gICAgICAgICAgICByZXNwb25kNTAwKHJlcywgJ1RoZSBjb25uZWN0aW9uIGlzIG5vdCByZWFkeSB5ZXQuJyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cblxuICAgIC8vIFJvdXRlIGhhbmRsZXJzXG4gICAgc3RhdGljIG9uQ29ubmVjdGlvbiAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKGNvbm5lY3Rpb24ucmVhZHkpXG4gICAgICAgICAgICByZXNwb25kNTAwKHJlcywgJ1RoZSBjb25uZWN0aW9uIGlzIGFscmVhZHkgZXN0YWJsaXNoZWQuJyk7XG5cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB1c2VyQWdlbnQgPSByZXEuaGVhZGVyc1sndXNlci1hZ2VudCddO1xuXG4gICAgICAgICAgICBjb25uZWN0aW9uLmVzdGFibGlzaCh1c2VyQWdlbnQpO1xuICAgICAgICAgICAgcmVkaXJlY3QocmVzLCBjb25uZWN0aW9uLmlkbGVVcmwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIG9uSGVhcnRiZWF0IChyZXEsIHJlcywgY29ubmVjdGlvbikge1xuICAgICAgICBpZiAoQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5LmVuc3VyZUNvbm5lY3Rpb25SZWFkeShyZXMsIGNvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBjb25zdCBzdGF0dXMgPSBjb25uZWN0aW9uLmhlYXJ0YmVhdCgpO1xuXG4gICAgICAgICAgICByZXNwb25kV2l0aEpTT04ocmVzLCBzdGF0dXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIG9uSWRsZSAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSlcbiAgICAgICAgICAgIHJlcy5lbmQoY29ubmVjdGlvbi5yZW5kZXJJZGxlUGFnZSgpKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgYXN5bmMgb25JZGxlRm9yY2VkIChyZXEsIHJlcywgY29ubmVjdGlvbikge1xuICAgICAgICBpZiAoQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5LmVuc3VyZUNvbm5lY3Rpb25SZWFkeShyZXMsIGNvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCBjb25uZWN0aW9uLmdldFN0YXR1cyh0cnVlKTtcblxuICAgICAgICAgICAgcmVkaXJlY3QocmVzLCBzdGF0dXMudXJsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBhc3luYyBvblN0YXR1c1JlcXVlc3QgKHJlcSwgcmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuX29uU3RhdHVzUmVxdWVzdENvcmUocmVxLCByZXMsIGNvbm5lY3Rpb24sIGZhbHNlKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgYXN5bmMgb25TdGF0dXNSZXF1ZXN0T25UZXN0RG9uZSAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fb25TdGF0dXNSZXF1ZXN0Q29yZShyZXEsIHJlcywgY29ubmVjdGlvbiwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGFzeW5jIF9vblN0YXR1c1JlcXVlc3RDb3JlIChyZXEsIHJlcywgY29ubmVjdGlvbiwgaXNUZXN0RG9uZSkge1xuICAgICAgICBpZiAoQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5LmVuc3VyZUNvbm5lY3Rpb25SZWFkeShyZXMsIGNvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCBjb25uZWN0aW9uLmdldFN0YXR1cyhpc1Rlc3REb25lKTtcblxuICAgICAgICAgICAgcmVzcG9uZFdpdGhKU09OKHJlcywgc3RhdHVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBvbkluaXRTY3JpcHRSZXF1ZXN0IChyZXEsIHJlcywgY29ubmVjdGlvbikge1xuICAgICAgICBpZiAoQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5LmVuc3VyZUNvbm5lY3Rpb25SZWFkeShyZXMsIGNvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBjb25zdCBzY3JpcHQgPSBjb25uZWN0aW9uLmdldEluaXRTY3JpcHQoKTtcblxuICAgICAgICAgICAgcmVzcG9uZFdpdGhKU09OKHJlcywgc2NyaXB0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBvbkluaXRTY3JpcHRSZXNwb25zZSAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgbGV0IGRhdGEgPSAnJztcblxuICAgICAgICAgICAgcmVxLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgICAgICAgICAgIGRhdGEgKz0gY2h1bms7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmVxLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbi5oYW5kbGVJbml0U2NyaXB0UmVzdWx0KGRhdGEpO1xuXG4gICAgICAgICAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBfY29ubmVjdE5leHRSZW1vdGVCcm93c2VyIChyZXEsIHJlcykge1xuICAgICAgICBwcmV2ZW50Q2FjaGluZyhyZXMpO1xuXG4gICAgICAgIGNvbnN0IHJlbW90ZUNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLnJlbW90ZXNRdWV1ZS5zaGlmdCgpO1xuXG4gICAgICAgIGlmIChyZW1vdGVDb25uZWN0aW9uKVxuICAgICAgICAgICAgcmVkaXJlY3QocmVzLCByZW1vdGVDb25uZWN0aW9uLnVybCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJlc3BvbmQ1MDAocmVzLCAnVGhlcmUgYXJlIG5vIGF2YWlsYWJsZSBjb25uZWN0aW9ucyB0byBlc3RhYmxpc2guJyk7XG4gICAgfVxuXG4gICAgLy8gQVBJXG4gICAgc3RhcnRTZXJ2aW5nQ29ubmVjdGlvbiAoY29ubmVjdGlvbikge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uaWRdID0gY29ubmVjdGlvbjtcblxuICAgICAgICBpZiAoY29ubmVjdGlvbi5icm93c2VySW5mby5wcm92aWRlck5hbWUgPT09ICdyZW1vdGUnKVxuICAgICAgICAgICAgdGhpcy5yZW1vdGVzUXVldWUuYWRkKGNvbm5lY3Rpb24pO1xuICAgIH1cblxuICAgIHN0b3BTZXJ2aW5nQ29ubmVjdGlvbiAoY29ubmVjdGlvbikge1xuICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uc1tjb25uZWN0aW9uLmlkXTtcblxuICAgICAgICBpZiAoY29ubmVjdGlvbi5icm93c2VySW5mby5wcm92aWRlck5hbWUgPT09ICdyZW1vdGUnKVxuICAgICAgICAgICAgdGhpcy5yZW1vdGVzUXVldWUucmVtb3ZlKGNvbm5lY3Rpb24pO1xuICAgIH1cblxuICAgIGNsb3NlICgpIHtcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5jb25uZWN0aW9ucykuZm9yRWFjaChpZCA9PiB0aGlzLmNvbm5lY3Rpb25zW2lkXS5jbG9zZSgpKTtcbiAgICB9XG59XG5cbiJdfQ== diff --git a/lib/browser/connection/index.js b/lib/browser/connection/index.js new file mode 100644 index 00000000..7398471d --- /dev/null +++ b/lib/browser/connection/index.js @@ -0,0 +1,367 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _events = require('events'); + +var _pinkie = require('pinkie'); + +var _pinkie2 = _interopRequireDefault(_pinkie); + +var _mustache = require('mustache'); + +var _mustache2 = _interopRequireDefault(_mustache); + +var _lodash = require('lodash'); + +var _useragent = require('useragent'); + +var _readFileRelative = require('read-file-relative'); + +var _promisifyEvent = require('promisify-event'); + +var _promisifyEvent2 = _interopRequireDefault(_promisifyEvent); + +var _nanoid = require('nanoid'); + +var _nanoid2 = _interopRequireDefault(_nanoid); + +var _command = require('./command'); + +var _command2 = _interopRequireDefault(_command); + +var _status = require('./status'); + +var _status2 = _interopRequireDefault(_status); + +var _runtime = require('../../errors/runtime'); + +var _message = require('../../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const IDLE_PAGE_TEMPLATE = (0, _readFileRelative.readSync)('../../client/browser/idle-page/index.html.mustache'); +const connections = {}; + +class BrowserConnection extends _events.EventEmitter { + constructor(gateway, browserInfo, permanent) { + super(); + + this.HEARTBEAT_TIMEOUT = 2 * 60 * 1000; + this.BROWSER_RESTART_TIMEOUT = 60 * 1000; + + this.id = BrowserConnection._generateId(); + this.jobQueue = []; + this.initScriptsQueue = []; + this.browserConnectionGateway = gateway; + this.errorSuppressed = false; + this.testRunAborted = false; + + this.browserInfo = browserInfo; + this.browserInfo.userAgent = ''; + this.browserInfo.userAgentProviderMetaInfo = ''; + + this.provider = browserInfo.provider; + + this.permanent = permanent; + this.closing = false; + this.closed = false; + this.ready = false; + this.opened = false; + this.idle = true; + this.heartbeatTimeout = null; + this.pendingTestRunUrl = null; + + this.url = `${gateway.domain}/browser/connect/${this.id}`; + this.idleUrl = `${gateway.domain}/browser/idle/${this.id}`; + this.forcedIdleUrl = `${gateway.domain}/browser/idle-forced/${this.id}`; + this.initScriptUrl = `${gateway.domain}/browser/init-script/${this.id}`; + + this.heartbeatRelativeUrl = `/browser/heartbeat/${this.id}`; + this.statusRelativeUrl = `/browser/status/${this.id}`; + this.statusDoneRelativeUrl = `/browser/status-done/${this.id}`; + + this.heartbeatUrl = `${gateway.domain}${this.heartbeatRelativeUrl}`; + this.statusUrl = `${gateway.domain}${this.statusRelativeUrl}`; + this.statusDoneUrl = `${gateway.domain}${this.statusDoneRelativeUrl}`; + + this.on('error', () => { + this._forceIdle(); + this.close(); + }); + + connections[this.id] = this; + + this.browserConnectionGateway.startServingConnection(this); + + process.nextTick(() => this._runBrowser()); + } + + static _generateId() { + return (0, _nanoid2.default)(7); + } + + _runBrowser() { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + try { + yield _this.provider.openBrowser(_this.id, _this.url, _this.browserInfo.browserName); + + if (!_this.ready) yield (0, _promisifyEvent2.default)(_this, 'ready'); + + _this.opened = true; + _this.emit('opened'); + } catch (err) { + _this.emit('error', new _runtime.GeneralError(_message2.default.unableToOpenBrowser, _this.browserInfo.providerName + ':' + _this.browserInfo.browserName, err.stack)); + } + })(); + } + + _closeBrowser() { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (!_this2.idle) yield (0, _promisifyEvent2.default)(_this2, 'idle'); + + try { + yield _this2.provider.closeBrowser(_this2.id); + } catch (err) { + // NOTE: A warning would be really nice here, but it can't be done while log is stored in a task. + } + })(); + } + + _forceIdle() { + if (!this.idle) { + this.switchingToIdle = false; + this.idle = true; + this.emit('idle'); + } + } + + _createBrowserDisconnectedError() { + return new _runtime.GeneralError(_message2.default.browserDisconnected, this.userAgent); + } + + _waitForHeartbeat() { + this.heartbeatTimeout = setTimeout(() => { + const err = this._createBrowserDisconnectedError(); + + this.opened = false; + this.errorSuppressed = false; + this.testRunAborted = true; + + this.emit('disconnected', err); + + if (!this.errorSuppressed) this.emit('error', err); + }, this.HEARTBEAT_TIMEOUT); + } + + _getTestRunUrl(needPopNext) { + var _this3 = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (needPopNext || !_this3.pendingTestRunUrl) _this3.pendingTestRunUrl = yield _this3._popNextTestRunUrl(); + + return _this3.pendingTestRunUrl; + })(); + } + + _popNextTestRunUrl() { + var _this4 = this; + + return (0, _asyncToGenerator3.default)(function* () { + while (_this4.hasQueuedJobs && !_this4.currentJob.hasQueuedTestRuns) _this4.jobQueue.shift(); + + return _this4.hasQueuedJobs ? yield _this4.currentJob.popNextTestRunUrl(_this4) : null; + })(); + } + + static getById(id) { + return connections[id] || null; + } + + restartBrowser() { + var _this5 = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this5.ready = false; + + _this5._forceIdle(); + + let resolveTimeout = null; + let isTimeoutExpired = false; + let timeout = null; + + const restartPromise = _this5._closeBrowser().then(function () { + return _this5._runBrowser(); + }); + + const timeoutPromise = new _pinkie2.default(function (resolve) { + resolveTimeout = resolve; + + timeout = setTimeout(function () { + isTimeoutExpired = true; + + resolve(); + }, _this5.BROWSER_RESTART_TIMEOUT); + }); + + _pinkie2.default.race([restartPromise, timeoutPromise]).then(function () { + clearTimeout(timeout); + + if (isTimeoutExpired) _this5.emit('error', _this5._createBrowserDisconnectedError());else resolveTimeout(); + }); + })(); + } + + suppressError() { + this.errorSuppressed = true; + } + + addWarning(...args) { + if (this.currentJob) this.currentJob.warningLog.addWarning(...args); + } + + setProviderMetaInfo(str) { + this.browserInfo.userAgentProviderMetaInfo = str; + } + + get userAgent() { + let userAgent = this.browserInfo.userAgent; + + if (this.browserInfo.userAgentProviderMetaInfo) userAgent += ` (${this.browserInfo.userAgentProviderMetaInfo})`; + + return userAgent; + } + + get hasQueuedJobs() { + return !!this.jobQueue.length; + } + + get currentJob() { + return this.jobQueue[0]; + } + + // API + runInitScript(code) { + return new _pinkie2.default(resolve => this.initScriptsQueue.push({ code, resolve })); + } + + addJob(job) { + this.jobQueue.push(job); + } + + removeJob(job) { + (0, _lodash.pull)(this.jobQueue, job); + } + + close() { + if (this.closed || this.closing) return; + + this.closing = true; + + this._closeBrowser().then(() => { + this.browserConnectionGateway.stopServingConnection(this); + clearTimeout(this.heartbeatTimeout); + + delete connections[this.id]; + + this.ready = false; + this.closed = true; + + this.emit('closed'); + }); + } + + establish(userAgent) { + this.ready = true; + + const parsedUserAgent = (0, _useragent.parse)(userAgent); + + this.browserInfo.userAgent = parsedUserAgent.toString(); + this.browserInfo.fullUserAgent = userAgent; + this.browserInfo.parsedUserAgent = parsedUserAgent; + + this._waitForHeartbeat(); + this.emit('ready'); + } + + heartbeat() { + clearTimeout(this.heartbeatTimeout); + this._waitForHeartbeat(); + + return { + code: this.closing ? _status2.default.closing : _status2.default.ok, + url: this.closing ? this.idleUrl : '' + }; + } + + renderIdlePage() { + return _mustache2.default.render(IDLE_PAGE_TEMPLATE, { + userAgent: this.userAgent, + statusUrl: this.statusUrl, + heartbeatUrl: this.heartbeatUrl, + initScriptUrl: this.initScriptUrl, + retryTestPages: !!this.browserConnectionGateway.retryTestPages + }); + } + + getInitScript() { + const initScriptPromise = this.initScriptsQueue[0]; + + return { code: initScriptPromise ? initScriptPromise.code : null }; + } + + handleInitScriptResult(data) { + const initScriptPromise = this.initScriptsQueue.shift(); + + if (initScriptPromise) initScriptPromise.resolve(JSON.parse(data)); + } + + isHeadlessBrowser() { + return this.provider.isHeadlessBrowser(this.id); + } + + reportJobResult(status, data) { + var _this6 = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _this6.provider.reportJobResult(_this6.id, status, data); + })(); + } + + getStatus(isTestDone) { + var _this7 = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (!_this7.idle && !isTestDone) { + _this7.idle = true; + _this7.emit('idle'); + } + + if (_this7.opened) { + const testRunUrl = yield _this7._getTestRunUrl(isTestDone || _this7.testRunAborted); + + _this7.testRunAborted = false; + + if (testRunUrl) { + _this7.idle = false; + return { cmd: _command2.default.run, url: testRunUrl }; + } + } + + return { cmd: _command2.default.idle, url: _this7.idleUrl }; + })(); + } +} +exports.default = BrowserConnection; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2Nvbm5lY3Rpb24vaW5kZXguanMiXSwibmFtZXMiOlsiSURMRV9QQUdFX1RFTVBMQVRFIiwiY29ubmVjdGlvbnMiLCJCcm93c2VyQ29ubmVjdGlvbiIsIkV2ZW50RW1pdHRlciIsImNvbnN0cnVjdG9yIiwiZ2F0ZXdheSIsImJyb3dzZXJJbmZvIiwicGVybWFuZW50IiwiSEVBUlRCRUFUX1RJTUVPVVQiLCJCUk9XU0VSX1JFU1RBUlRfVElNRU9VVCIsImlkIiwiX2dlbmVyYXRlSWQiLCJqb2JRdWV1ZSIsImluaXRTY3JpcHRzUXVldWUiLCJicm93c2VyQ29ubmVjdGlvbkdhdGV3YXkiLCJlcnJvclN1cHByZXNzZWQiLCJ0ZXN0UnVuQWJvcnRlZCIsInVzZXJBZ2VudCIsInVzZXJBZ2VudFByb3ZpZGVyTWV0YUluZm8iLCJwcm92aWRlciIsImNsb3NpbmciLCJjbG9zZWQiLCJyZWFkeSIsIm9wZW5lZCIsImlkbGUiLCJoZWFydGJlYXRUaW1lb3V0IiwicGVuZGluZ1Rlc3RSdW5VcmwiLCJ1cmwiLCJkb21haW4iLCJpZGxlVXJsIiwiZm9yY2VkSWRsZVVybCIsImluaXRTY3JpcHRVcmwiLCJoZWFydGJlYXRSZWxhdGl2ZVVybCIsInN0YXR1c1JlbGF0aXZlVXJsIiwic3RhdHVzRG9uZVJlbGF0aXZlVXJsIiwiaGVhcnRiZWF0VXJsIiwic3RhdHVzVXJsIiwic3RhdHVzRG9uZVVybCIsIm9uIiwiX2ZvcmNlSWRsZSIsImNsb3NlIiwic3RhcnRTZXJ2aW5nQ29ubmVjdGlvbiIsInByb2Nlc3MiLCJuZXh0VGljayIsIl9ydW5Ccm93c2VyIiwib3BlbkJyb3dzZXIiLCJicm93c2VyTmFtZSIsImVtaXQiLCJlcnIiLCJHZW5lcmFsRXJyb3IiLCJNRVNTQUdFIiwidW5hYmxlVG9PcGVuQnJvd3NlciIsInByb3ZpZGVyTmFtZSIsInN0YWNrIiwiX2Nsb3NlQnJvd3NlciIsImNsb3NlQnJvd3NlciIsInN3aXRjaGluZ1RvSWRsZSIsIl9jcmVhdGVCcm93c2VyRGlzY29ubmVjdGVkRXJyb3IiLCJicm93c2VyRGlzY29ubmVjdGVkIiwiX3dhaXRGb3JIZWFydGJlYXQiLCJzZXRUaW1lb3V0IiwiX2dldFRlc3RSdW5VcmwiLCJuZWVkUG9wTmV4dCIsIl9wb3BOZXh0VGVzdFJ1blVybCIsImhhc1F1ZXVlZEpvYnMiLCJjdXJyZW50Sm9iIiwiaGFzUXVldWVkVGVzdFJ1bnMiLCJzaGlmdCIsInBvcE5leHRUZXN0UnVuVXJsIiwiZ2V0QnlJZCIsInJlc3RhcnRCcm93c2VyIiwicmVzb2x2ZVRpbWVvdXQiLCJpc1RpbWVvdXRFeHBpcmVkIiwidGltZW91dCIsInJlc3RhcnRQcm9taXNlIiwidGhlbiIsInRpbWVvdXRQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyYWNlIiwiY2xlYXJUaW1lb3V0Iiwic3VwcHJlc3NFcnJvciIsImFkZFdhcm5pbmciLCJhcmdzIiwid2FybmluZ0xvZyIsInNldFByb3ZpZGVyTWV0YUluZm8iLCJzdHIiLCJsZW5ndGgiLCJydW5Jbml0U2NyaXB0IiwiY29kZSIsInB1c2giLCJhZGRKb2IiLCJqb2IiLCJyZW1vdmVKb2IiLCJzdG9wU2VydmluZ0Nvbm5lY3Rpb24iLCJlc3RhYmxpc2giLCJwYXJzZWRVc2VyQWdlbnQiLCJ0b1N0cmluZyIsImZ1bGxVc2VyQWdlbnQiLCJoZWFydGJlYXQiLCJTVEFUVVMiLCJvayIsInJlbmRlcklkbGVQYWdlIiwiTXVzdGFjaGUiLCJyZW5kZXIiLCJyZXRyeVRlc3RQYWdlcyIsImdldEluaXRTY3JpcHQiLCJpbml0U2NyaXB0UHJvbWlzZSIsImhhbmRsZUluaXRTY3JpcHRSZXN1bHQiLCJkYXRhIiwiSlNPTiIsInBhcnNlIiwiaXNIZWFkbGVzc0Jyb3dzZXIiLCJyZXBvcnRKb2JSZXN1bHQiLCJzdGF0dXMiLCJnZXRTdGF0dXMiLCJpc1Rlc3REb25lIiwidGVzdFJ1blVybCIsImNtZCIsIkNPTU1BTkQiLCJydW4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7O0FBQ0E7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akIsZUFBTyxLQUFLN0YsUUFBTCxDQUFjNkYsaUJBQWQsQ0FBZ0MsS0FBS3RHLEVBQXJDLENBQVA7QUFDSDs7QUFFS3VHLG1CQUFOLENBQXVCQyxNQUF2QixFQUErQkwsSUFBL0IsRUFBcUM7QUFBQTs7QUFBQTtBQUNqQyxrQkFBTSxPQUFLMUYsUUFBTCxDQUFjOEYsZUFBZCxDQUE4QixPQUFLdkcsRUFBbkMsRUFBdUN3RyxNQUF2QyxFQUErQ0wsSUFBL0MsQ0FBTjtBQURpQztBQUVwQzs7QUFFS00sYUFBTixDQUFpQkMsVUFBakIsRUFBNkI7QUFBQTs7QUFBQTtBQUN6QixnQkFBSSxDQUFDLE9BQUs1RixJQUFOLElBQWMsQ0FBQzRGLFVBQW5CLEVBQStCO0FBQzNCLHVCQUFLNUYsSUFBTCxHQUFZLElBQVo7QUFDQSx1QkFBS3VCLElBQUwsQ0FBVSxNQUFWO0FBQ0g7O0FBRUQsZ0JBQUksT0FBS3hCLE1BQVQsRUFBaUI7QUFDYixzQkFBTThGLGFBQWEsTUFBTSxPQUFLeEQsY0FBTCxDQUFvQnVELGNBQWMsT0FBS3BHLGNBQXZDLENBQXpCOztBQUVBLHVCQUFLQSxjQUFMLEdBQXNCLEtBQXRCOztBQUVBLG9CQUFJcUcsVUFBSixFQUFnQjtBQUNaLDJCQUFLN0YsSUFBTCxHQUFZLEtBQVo7QUFDQSwyQkFBTyxFQUFFOEYsS0FBS0Msa0JBQVFDLEdBQWYsRUFBb0I3RixLQUFLMEYsVUFBekIsRUFBUDtBQUNIO0FBQ0o7O0FBRUQsbUJBQU8sRUFBRUMsS0FBS0Msa0JBQVEvRixJQUFmLEVBQXFCRyxLQUFLLE9BQUtFLE9BQS9CLEVBQVA7QUFqQnlCO0FBa0I1QjtBQS9TdUQ7a0JBQXZDM0IsaUIiLCJmaWxlIjoiYnJvd3Nlci9jb25uZWN0aW9uL2luZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCBQcm9taXNlIGZyb20gJ3BpbmtpZSc7XG5pbXBvcnQgTXVzdGFjaGUgZnJvbSAnbXVzdGFjaGUnO1xuaW1wb3J0IHsgcHVsbCBhcyByZW1vdmUgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgcGFyc2UgYXMgcGFyc2VVc2VyQWdlbnQgfSBmcm9tICd1c2VyYWdlbnQnO1xuaW1wb3J0IHsgcmVhZFN5bmMgYXMgcmVhZCB9IGZyb20gJ3JlYWQtZmlsZS1yZWxhdGl2ZSc7XG5pbXBvcnQgcHJvbWlzaWZ5RXZlbnQgZnJvbSAncHJvbWlzaWZ5LWV2ZW50JztcbmltcG9ydCBuYW5vaWQgZnJvbSAnbmFub2lkJztcbmltcG9ydCBDT01NQU5EIGZyb20gJy4vY29tbWFuZCc7XG5pbXBvcnQgU1RBVFVTIGZyb20gJy4vc3RhdHVzJztcbmltcG9ydCB7IEdlbmVyYWxFcnJvciB9IGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lJztcbmltcG9ydCBNRVNTQUdFIGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lL21lc3NhZ2UnO1xuXG5jb25zdCBJRExFX1BBR0VfVEVNUExBVEUgPSByZWFkKCcuLi8uLi9jbGllbnQvYnJvd3Nlci9pZGxlLXBhZ2UvaW5kZXguaHRtbC5tdXN0YWNoZScpO1xuY29uc3QgY29ubmVjdGlvbnMgICAgICAgID0ge307XG5cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnJvd3NlckNvbm5lY3Rpb24gZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yIChnYXRld2F5LCBicm93c2VySW5mbywgcGVybWFuZW50KSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpcy5IRUFSVEJFQVRfVElNRU9VVCAgICAgICA9IDIgKiA2MCAqIDEwMDA7XG4gICAgICAgIHRoaXMuQlJPV1NFUl9SRVNUQVJUX1RJTUVPVVQgPSA2MCAqIDEwMDA7XG5cbiAgICAgICAgdGhpcy5pZCAgICAgICAgICAgICAgICAgICAgICAgPSBCcm93c2VyQ29ubmVjdGlvbi5fZ2VuZXJhdGVJZCgpO1xuICAgICAgICB0aGlzLmpvYlF1ZXVlICAgICAgICAgICAgICAgICA9IFtdO1xuICAgICAgICB0aGlzLmluaXRTY3JpcHRzUXVldWUgICAgICAgICA9IFtdO1xuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheSA9IGdhdGV3YXk7XG4gICAgICAgIHRoaXMuZXJyb3JTdXBwcmVzc2VkICAgICAgICAgID0gZmFsc2U7XG4gICAgICAgIHRoaXMudGVzdFJ1bkFib3J0ZWQgICAgICAgICAgID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5icm93c2VySW5mbyAgICAgICAgICAgICAgICAgICAgICAgICAgID0gYnJvd3NlckluZm87XG4gICAgICAgIHRoaXMuYnJvd3NlckluZm8udXNlckFnZW50ICAgICAgICAgICAgICAgICA9ICcnO1xuICAgICAgICB0aGlzLmJyb3dzZXJJbmZvLnVzZXJBZ2VudFByb3ZpZGVyTWV0YUluZm8gPSAnJztcblxuICAgICAgICB0aGlzLnByb3ZpZGVyID0gYnJvd3NlckluZm8ucHJvdmlkZXI7XG5cbiAgICAgICAgdGhpcy5wZXJtYW5lbnQgICAgICAgICA9IHBlcm1hbmVudDtcbiAgICAgICAgdGhpcy5jbG9zaW5nICAgICAgICAgICA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNsb3NlZCAgICAgICAgICAgID0gZmFsc2U7XG4gICAgICAgIHRoaXMucmVhZHkgICAgICAgICAgICAgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5vcGVuZWQgICAgICAgICAgICA9IGZhbHNlO1xuICAgICAgICB0aGlzLmlkbGUgICAgICAgICAgICAgID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5oZWFydGJlYXRUaW1lb3V0ICA9IG51bGw7XG4gICAgICAgIHRoaXMucGVuZGluZ1Rlc3RSdW5VcmwgPSBudWxsO1xuXG4gICAgICAgIHRoaXMudXJsICAgICAgICAgICA9IGAke2dhdGV3YXkuZG9tYWlufS9icm93c2VyL2Nvbm5lY3QvJHt0aGlzLmlkfWA7XG4gICAgICAgIHRoaXMuaWRsZVVybCAgICAgICA9IGAke2dhdGV3YXkuZG9tYWlufS9icm93c2VyL2lkbGUvJHt0aGlzLmlkfWA7XG4gICAgICAgIHRoaXMuZm9yY2VkSWRsZVVybCA9IGAke2dhdGV3YXkuZG9tYWlufS9icm93c2VyL2lkbGUtZm9yY2VkLyR7dGhpcy5pZH1gO1xuICAgICAgICB0aGlzLmluaXRTY3JpcHRVcmwgPSBgJHtnYXRld2F5LmRvbWFpbn0vYnJvd3Nlci9pbml0LXNjcmlwdC8ke3RoaXMuaWR9YDtcblxuICAgICAgICB0aGlzLmhlYXJ0YmVhdFJlbGF0aXZlVXJsICA9IGAvYnJvd3Nlci9oZWFydGJlYXQvJHt0aGlzLmlkfWA7XG4gICAgICAgIHRoaXMuc3RhdHVzUmVsYXRpdmVVcmwgICAgID0gYC9icm93c2VyL3N0YXR1cy8ke3RoaXMuaWR9YDtcbiAgICAgICAgdGhpcy5zdGF0dXNEb25lUmVsYXRpdmVVcmwgPSBgL2Jyb3dzZXIvc3RhdHVzLWRvbmUvJHt0aGlzLmlkfWA7XG5cbiAgICAgICAgdGhpcy5oZWFydGJlYXRVcmwgID0gYCR7Z2F0ZXdheS5kb21haW59JHt0aGlzLmhlYXJ0YmVhdFJlbGF0aXZlVXJsfWA7XG4gICAgICAgIHRoaXMuc3RhdHVzVXJsICAgICA9IGAke2dhdGV3YXkuZG9tYWlufSR7dGhpcy5zdGF0dXNSZWxhdGl2ZVVybH1gO1xuICAgICAgICB0aGlzLnN0YXR1c0RvbmVVcmwgPSBgJHtnYXRld2F5LmRvbWFpbn0ke3RoaXMuc3RhdHVzRG9uZVJlbGF0aXZlVXJsfWA7XG5cbiAgICAgICAgdGhpcy5vbignZXJyb3InLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9mb3JjZUlkbGUoKTtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29ubmVjdGlvbnNbdGhpcy5pZF0gPSB0aGlzO1xuXG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb25HYXRld2F5LnN0YXJ0U2VydmluZ0Nvbm5lY3Rpb24odGhpcyk7XG5cbiAgICAgICAgcHJvY2Vzcy5uZXh0VGljaygoKSA9PiB0aGlzLl9ydW5Ccm93c2VyKCkpO1xuICAgIH1cblxuICAgIHN0YXRpYyBfZ2VuZXJhdGVJZCAoKSB7XG4gICAgICAgIHJldHVybiBuYW5vaWQoNyk7XG4gICAgfVxuXG4gICAgYXN5bmMgX3J1bkJyb3dzZXIgKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5vcGVuQnJvd3Nlcih0aGlzLmlkLCB0aGlzLnVybCwgdGhpcy5icm93c2VySW5mby5icm93c2VyTmFtZSk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5yZWFkeSlcbiAgICAgICAgICAgICAgICBhd2FpdCBwcm9taXNpZnlFdmVudCh0aGlzLCAncmVhZHknKTtcblxuICAgICAgICAgICAgdGhpcy5vcGVuZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdvcGVuZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEdlbmVyYWxFcnJvcihcbiAgICAgICAgICAgICAgICBNRVNTQUdFLnVuYWJsZVRvT3BlbkJyb3dzZXIsXG4gICAgICAgICAgICAgICAgdGhpcy5icm93c2VySW5mby5wcm92aWRlck5hbWUgKyAnOicgKyB0aGlzLmJyb3dzZXJJbmZvLmJyb3dzZXJOYW1lLFxuICAgICAgICAgICAgICAgIGVyci5zdGFja1xuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBfY2xvc2VCcm93c2VyICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkbGUpXG4gICAgICAgICAgICBhd2FpdCBwcm9taXNpZnlFdmVudCh0aGlzLCAnaWRsZScpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnByb3ZpZGVyLmNsb3NlQnJvd3Nlcih0aGlzLmlkKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBBIHdhcm5pbmcgd291bGQgYmUgcmVhbGx5IG5pY2UgaGVyZSwgYnV0IGl0IGNhbid0IGJlIGRvbmUgd2hpbGUgbG9nIGlzIHN0b3JlZCBpbiBhIHRhc2suXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfZm9yY2VJZGxlICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlkbGUpIHtcbiAgICAgICAgICAgIHRoaXMuc3dpdGNoaW5nVG9JZGxlID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmlkbGUgICAgICAgICAgICA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2lkbGUnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9jcmVhdGVCcm93c2VyRGlzY29ubmVjdGVkRXJyb3IgKCkge1xuICAgICAgICByZXR1cm4gbmV3IEdlbmVyYWxFcnJvcihNRVNTQUdFLmJyb3dzZXJEaXNjb25uZWN0ZWQsIHRoaXMudXNlckFnZW50KTtcbiAgICB9XG5cbiAgICBfd2FpdEZvckhlYXJ0YmVhdCAoKSB7XG4gICAgICAgIHRoaXMuaGVhcnRiZWF0VGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXJyID0gdGhpcy5fY3JlYXRlQnJvd3NlckRpc2Nvbm5lY3RlZEVycm9yKCk7XG5cbiAgICAgICAgICAgIHRoaXMub3BlbmVkICAgICAgICAgID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmVycm9yU3VwcHJlc3NlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy50ZXN0UnVuQWJvcnRlZCAgPSB0cnVlO1xuXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2Rpc2Nvbm5lY3RlZCcsIGVycik7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5lcnJvclN1cHByZXNzZWQpXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG5cbiAgICAgICAgfSwgdGhpcy5IRUFSVEJFQVRfVElNRU9VVCk7XG4gICAgfVxuXG4gICAgYXN5bmMgX2dldFRlc3RSdW5VcmwgKG5lZWRQb3BOZXh0KSB7XG4gICAgICAgIGlmIChuZWVkUG9wTmV4dCB8fCAhdGhpcy5wZW5kaW5nVGVzdFJ1blVybClcbiAgICAgICAgICAgIHRoaXMucGVuZGluZ1Rlc3RSdW5VcmwgPSBhd2FpdCB0aGlzLl9wb3BOZXh0VGVzdFJ1blVybCgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnBlbmRpbmdUZXN0UnVuVXJsO1xuICAgIH1cblxuICAgIGFzeW5jIF9wb3BOZXh0VGVzdFJ1blVybCAoKSB7XG4gICAgICAgIHdoaWxlICh0aGlzLmhhc1F1ZXVlZEpvYnMgJiYgIXRoaXMuY3VycmVudEpvYi5oYXNRdWV1ZWRUZXN0UnVucylcbiAgICAgICAgICAgIHRoaXMuam9iUXVldWUuc2hpZnQoKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5oYXNRdWV1ZWRKb2JzID8gYXdhaXQgdGhpcy5jdXJyZW50Sm9iLnBvcE5leHRUZXN0UnVuVXJsKHRoaXMpIDogbnVsbDtcbiAgICB9XG5cbiAgICBzdGF0aWMgZ2V0QnlJZCAoaWQpIHtcbiAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb25zW2lkXSB8fCBudWxsO1xuICAgIH1cblxuICAgIGFzeW5jIHJlc3RhcnRCcm93c2VyICgpIHtcbiAgICAgICAgdGhpcy5yZWFkeSA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuX2ZvcmNlSWRsZSgpO1xuXG4gICAgICAgIGxldCByZXNvbHZlVGltZW91dCAgID0gbnVsbDtcbiAgICAgICAgbGV0IGlzVGltZW91dEV4cGlyZWQgPSBmYWxzZTtcbiAgICAgICAgbGV0IHRpbWVvdXQgICAgICAgICAgPSBudWxsO1xuXG4gICAgICAgIGNvbnN0IHJlc3RhcnRQcm9taXNlID0gdGhpcy5fY2xvc2VCcm93c2VyKClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMuX3J1bkJyb3dzZXIoKSk7XG5cbiAgICAgICAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVUaW1lb3V0ID0gcmVzb2x2ZTtcblxuICAgICAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlzVGltZW91dEV4cGlyZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfSwgdGhpcy5CUk9XU0VSX1JFU1RBUlRfVElNRU9VVCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIFByb21pc2UucmFjZShbIHJlc3RhcnRQcm9taXNlLCB0aW1lb3V0UHJvbWlzZSBdKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcblxuICAgICAgICAgICAgICAgIGlmIChpc1RpbWVvdXRFeHBpcmVkKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgdGhpcy5fY3JlYXRlQnJvd3NlckRpc2Nvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZVRpbWVvdXQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN1cHByZXNzRXJyb3IgKCkge1xuICAgICAgICB0aGlzLmVycm9yU3VwcHJlc3NlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgYWRkV2FybmluZyAoLi4uYXJncykge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50Sm9iKVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50Sm9iLndhcm5pbmdMb2cuYWRkV2FybmluZyguLi5hcmdzKTtcbiAgICB9XG5cbiAgICBzZXRQcm92aWRlck1ldGFJbmZvIChzdHIpIHtcbiAgICAgICAgdGhpcy5icm93c2VySW5mby51c2VyQWdlbnRQcm92aWRlck1ldGFJbmZvID0gc3RyO1xuICAgIH1cblxuICAgIGdldCB1c2VyQWdlbnQgKCkge1xuICAgICAgICBsZXQgdXNlckFnZW50ID0gdGhpcy5icm93c2VySW5mby51c2VyQWdlbnQ7XG5cbiAgICAgICAgaWYgKHRoaXMuYnJvd3NlckluZm8udXNlckFnZW50UHJvdmlkZXJNZXRhSW5mbylcbiAgICAgICAgICAgIHVzZXJBZ2VudCArPSBgICgke3RoaXMuYnJvd3NlckluZm8udXNlckFnZW50UHJvdmlkZXJNZXRhSW5mb30pYDtcblxuICAgICAgICByZXR1cm4gdXNlckFnZW50O1xuICAgIH1cblxuICAgIGdldCBoYXNRdWV1ZWRKb2JzICgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5qb2JRdWV1ZS5sZW5ndGg7XG4gICAgfVxuXG4gICAgZ2V0IGN1cnJlbnRKb2IgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5qb2JRdWV1ZVswXTtcbiAgICB9XG5cbiAgICAvLyBBUElcbiAgICBydW5Jbml0U2NyaXB0IChjb2RlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHRoaXMuaW5pdFNjcmlwdHNRdWV1ZS5wdXNoKHsgY29kZSwgcmVzb2x2ZSB9KSk7XG4gICAgfVxuXG4gICAgYWRkSm9iIChqb2IpIHtcbiAgICAgICAgdGhpcy5qb2JRdWV1ZS5wdXNoKGpvYik7XG4gICAgfVxuXG4gICAgcmVtb3ZlSm9iIChqb2IpIHtcbiAgICAgICAgcmVtb3ZlKHRoaXMuam9iUXVldWUsIGpvYik7XG4gICAgfVxuXG4gICAgY2xvc2UgKCkge1xuICAgICAgICBpZiAodGhpcy5jbG9zZWQgfHwgdGhpcy5jbG9zaW5nKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMuY2xvc2luZyA9IHRydWU7XG5cbiAgICAgICAgdGhpcy5fY2xvc2VCcm93c2VyKClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5zdG9wU2VydmluZ0Nvbm5lY3Rpb24odGhpcyk7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuaGVhcnRiZWF0VGltZW91dCk7XG5cbiAgICAgICAgICAgICAgICBkZWxldGUgY29ubmVjdGlvbnNbdGhpcy5pZF07XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJlYWR5ICA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VkID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnY2xvc2VkJyk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBlc3RhYmxpc2ggKHVzZXJBZ2VudCkge1xuICAgICAgICB0aGlzLnJlYWR5ID0gdHJ1ZTtcblxuICAgICAgICBjb25zdCBwYXJzZWRVc2VyQWdlbnQgPSBwYXJzZVVzZXJBZ2VudCh1c2VyQWdlbnQpO1xuXG4gICAgICAgIHRoaXMuYnJvd3NlckluZm8udXNlckFnZW50ICAgICAgID0gcGFyc2VkVXNlckFnZW50LnRvU3RyaW5nKCk7XG4gICAgICAgIHRoaXMuYnJvd3NlckluZm8uZnVsbFVzZXJBZ2VudCAgID0gdXNlckFnZW50O1xuICAgICAgICB0aGlzLmJyb3dzZXJJbmZvLnBhcnNlZFVzZXJBZ2VudCA9IHBhcnNlZFVzZXJBZ2VudDtcblxuICAgICAgICB0aGlzLl93YWl0Rm9ySGVhcnRiZWF0KCk7XG4gICAgICAgIHRoaXMuZW1pdCgncmVhZHknKTtcbiAgICB9XG5cbiAgICBoZWFydGJlYXQgKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5oZWFydGJlYXRUaW1lb3V0KTtcbiAgICAgICAgdGhpcy5fd2FpdEZvckhlYXJ0YmVhdCgpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb2RlOiB0aGlzLmNsb3NpbmcgPyBTVEFUVVMuY2xvc2luZyA6IFNUQVRVUy5vayxcbiAgICAgICAgICAgIHVybDogIHRoaXMuY2xvc2luZyA/IHRoaXMuaWRsZVVybCA6ICcnXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmVuZGVySWRsZVBhZ2UgKCkge1xuICAgICAgICByZXR1cm4gTXVzdGFjaGUucmVuZGVyKElETEVfUEFHRV9URU1QTEFURSwge1xuICAgICAgICAgICAgdXNlckFnZW50OiAgICAgIHRoaXMudXNlckFnZW50LFxuICAgICAgICAgICAgc3RhdHVzVXJsOiAgICAgIHRoaXMuc3RhdHVzVXJsLFxuICAgICAgICAgICAgaGVhcnRiZWF0VXJsOiAgIHRoaXMuaGVhcnRiZWF0VXJsLFxuICAgICAgICAgICAgaW5pdFNjcmlwdFVybDogIHRoaXMuaW5pdFNjcmlwdFVybCxcbiAgICAgICAgICAgIHJldHJ5VGVzdFBhZ2VzOiAhIXRoaXMuYnJvd3NlckNvbm5lY3Rpb25HYXRld2F5LnJldHJ5VGVzdFBhZ2VzXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldEluaXRTY3JpcHQgKCkge1xuICAgICAgICBjb25zdCBpbml0U2NyaXB0UHJvbWlzZSA9IHRoaXMuaW5pdFNjcmlwdHNRdWV1ZVswXTtcblxuICAgICAgICByZXR1cm4geyBjb2RlOiBpbml0U2NyaXB0UHJvbWlzZSA/IGluaXRTY3JpcHRQcm9taXNlLmNvZGUgOiBudWxsIH07XG4gICAgfVxuXG4gICAgaGFuZGxlSW5pdFNjcmlwdFJlc3VsdCAoZGF0YSkge1xuICAgICAgICBjb25zdCBpbml0U2NyaXB0UHJvbWlzZSA9IHRoaXMuaW5pdFNjcmlwdHNRdWV1ZS5zaGlmdCgpO1xuXG4gICAgICAgIGlmIChpbml0U2NyaXB0UHJvbWlzZSlcbiAgICAgICAgICAgIGluaXRTY3JpcHRQcm9taXNlLnJlc29sdmUoSlNPTi5wYXJzZShkYXRhKSk7XG4gICAgfVxuXG4gICAgaXNIZWFkbGVzc0Jyb3dzZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm92aWRlci5pc0hlYWRsZXNzQnJvd3Nlcih0aGlzLmlkKTtcbiAgICB9XG5cbiAgICBhc3luYyByZXBvcnRKb2JSZXN1bHQgKHN0YXR1cywgZGF0YSkge1xuICAgICAgICBhd2FpdCB0aGlzLnByb3ZpZGVyLnJlcG9ydEpvYlJlc3VsdCh0aGlzLmlkLCBzdGF0dXMsIGRhdGEpO1xuICAgIH1cblxuICAgIGFzeW5jIGdldFN0YXR1cyAoaXNUZXN0RG9uZSkge1xuICAgICAgICBpZiAoIXRoaXMuaWRsZSAmJiAhaXNUZXN0RG9uZSkge1xuICAgICAgICAgICAgdGhpcy5pZGxlID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnaWRsZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMub3BlbmVkKSB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0UnVuVXJsID0gYXdhaXQgdGhpcy5fZ2V0VGVzdFJ1blVybChpc1Rlc3REb25lIHx8IHRoaXMudGVzdFJ1bkFib3J0ZWQpO1xuXG4gICAgICAgICAgICB0aGlzLnRlc3RSdW5BYm9ydGVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmICh0ZXN0UnVuVXJsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZGxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgY21kOiBDT01NQU5ELnJ1biwgdXJsOiB0ZXN0UnVuVXJsIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBjbWQ6IENPTU1BTkQuaWRsZSwgdXJsOiB0aGlzLmlkbGVVcmwgfTtcbiAgICB9XG59XG4iXX0= diff --git a/lib/browser/connection/remotes-queue.js b/lib/browser/connection/remotes-queue.js new file mode 100644 index 00000000..d0ee23a0 --- /dev/null +++ b/lib/browser/connection/remotes-queue.js @@ -0,0 +1,76 @@ +'use strict'; + +exports.__esModule = true; + +var _keys = require('babel-runtime/core-js/object/keys'); + +var _keys2 = _interopRequireDefault(_keys); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _pinkie = require('pinkie'); + +var _pinkie2 = _interopRequireDefault(_pinkie); + +var _events = require('events'); + +var _promisifyEvent = require('promisify-event'); + +var _promisifyEvent2 = _interopRequireDefault(_promisifyEvent); + +var _timeLimitPromise = require('time-limit-promise'); + +var _timeLimitPromise2 = _interopRequireDefault(_timeLimitPromise); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const REMOTE_REDIRECT_TIMEOUT = 10000; +const ADDING_CONNECTION_WAITING_TIMEOUT = 10000; + +class RemotesQueue { + constructor() { + this.events = new _events.EventEmitter(); + this.shiftingTimeout = _pinkie2.default.resolve(); + this.pendingConnections = {}; + } + + add(remoteConnection) { + const connectionReadyPromise = (0, _promisifyEvent2.default)(remoteConnection, 'ready').then(() => this.remove(remoteConnection)); + + this.pendingConnections[remoteConnection.id] = { + connection: remoteConnection, + readyPromise: connectionReadyPromise + }; + + this.events.emit('connection-added', remoteConnection.id); + } + + remove(remoteConnection) { + delete this.pendingConnections[remoteConnection.id]; + } + + shift() { + var _this = this; + + const shiftingPromise = this.shiftingTimeout.then((0, _asyncToGenerator3.default)(function* () { + let headId = (0, _keys2.default)(_this.pendingConnections)[0]; + + if (!headId) headId = yield (0, _timeLimitPromise2.default)((0, _promisifyEvent2.default)(_this.events, 'connection-added'), ADDING_CONNECTION_WAITING_TIMEOUT); + + return headId ? _this.pendingConnections[headId].connection : null; + })); + + this.shiftingTimeout = shiftingPromise.then(connection => { + if (!connection) return _pinkie2.default.resolve(); + + return (0, _timeLimitPromise2.default)(this.pendingConnections[connection.id].readyPromise, REMOTE_REDIRECT_TIMEOUT); + }); + + return shiftingPromise; + } +} +exports.default = RemotesQueue; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2Nvbm5lY3Rpb24vcmVtb3Rlcy1xdWV1ZS5qcyJdLCJuYW1lcyI6WyJSRU1PVEVfUkVESVJFQ1RfVElNRU9VVCIsIkFERElOR19DT05ORUNUSU9OX1dBSVRJTkdfVElNRU9VVCIsIlJlbW90ZXNRdWV1ZSIsImNvbnN0cnVjdG9yIiwiZXZlbnRzIiwiRXZlbnRFbWl0dGVyIiwic2hpZnRpbmdUaW1lb3V0IiwiUHJvbWlzZSIsInJlc29sdmUiLCJwZW5kaW5nQ29ubmVjdGlvbnMiLCJhZGQiLCJyZW1vdGVDb25uZWN0aW9uIiwiY29ubmVjdGlvblJlYWR5UHJvbWlzZSIsInRoZW4iLCJyZW1vdmUiLCJpZCIsImNvbm5lY3Rpb24iLCJyZWFkeVByb21pc2UiLCJlbWl0Iiwic2hpZnQiLCJzaGlmdGluZ1Byb21pc2UiLCJoZWFkSWQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBR0EsTUFBTUEsMEJBQW9DLEtBQTFDO0FBQ0EsTUFBTUMsb0NBQW9DLEtBQTFDOztBQUVlLE1BQU1DLFlBQU4sQ0FBbUI7QUFDOUJDLGtCQUFlO0FBQ1gsYUFBS0MsTUFBTCxHQUEwQixJQUFJQyxvQkFBSixFQUExQjtBQUNBLGFBQUtDLGVBQUwsR0FBMEJDLGlCQUFRQyxPQUFSLEVBQTFCO0FBQ0EsYUFBS0Msa0JBQUwsR0FBMEIsRUFBMUI7QUFDSDs7QUFFREMsUUFBS0MsZ0JBQUwsRUFBdUI7QUFDbkIsY0FBTUMseUJBQXlCLDhCQUFlRCxnQkFBZixFQUFpQyxPQUFqQyxFQUMxQkUsSUFEMEIsQ0FDckIsTUFBTSxLQUFLQyxNQUFMLENBQVlILGdCQUFaLENBRGUsQ0FBL0I7O0FBR0EsYUFBS0Ysa0JBQUwsQ0FBd0JFLGlCQUFpQkksRUFBekMsSUFBK0M7QUFDM0NDLHdCQUFjTCxnQkFENkI7QUFFM0NNLDBCQUFjTDtBQUY2QixTQUEvQzs7QUFLQSxhQUFLUixNQUFMLENBQVljLElBQVosQ0FBaUIsa0JBQWpCLEVBQXFDUCxpQkFBaUJJLEVBQXREO0FBQ0g7O0FBRURELFdBQVFILGdCQUFSLEVBQTBCO0FBQ3RCLGVBQU8sS0FBS0Ysa0JBQUwsQ0FBd0JFLGlCQUFpQkksRUFBekMsQ0FBUDtBQUNIOztBQUVESSxZQUFTO0FBQUE7O0FBQ0wsY0FBTUMsa0JBQWtCLEtBQUtkLGVBQUwsQ0FDbkJPLElBRG1CLGlDQUNkLGFBQVk7QUFDZCxnQkFBSVEsU0FBUyxvQkFBWSxNQUFLWixrQkFBakIsRUFBcUMsQ0FBckMsQ0FBYjs7QUFFQSxnQkFBSSxDQUFDWSxNQUFMLEVBQ0lBLFNBQVMsTUFBTSxnQ0FBc0IsOEJBQWUsTUFBS2pCLE1BQXBCLEVBQTRCLGtCQUE1QixDQUF0QixFQUF1RUgsaUNBQXZFLENBQWY7O0FBRUosbUJBQU9vQixTQUFTLE1BQUtaLGtCQUFMLENBQXdCWSxNQUF4QixFQUFnQ0wsVUFBekMsR0FBc0QsSUFBN0Q7QUFDSCxTQVJtQixFQUF4Qjs7QUFVQSxhQUFLVixlQUFMLEdBQXVCYyxnQkFDbEJQLElBRGtCLENBQ2JHLGNBQWM7QUFDaEIsZ0JBQUksQ0FBQ0EsVUFBTCxFQUNJLE9BQU9ULGlCQUFRQyxPQUFSLEVBQVA7O0FBRUosbUJBQU8sZ0NBQXNCLEtBQUtDLGtCQUFMLENBQXdCTyxXQUFXRCxFQUFuQyxFQUF1Q0UsWUFBN0QsRUFBMkVqQix1QkFBM0UsQ0FBUDtBQUNILFNBTmtCLENBQXZCOztBQVFBLGVBQU9vQixlQUFQO0FBQ0g7QUEzQzZCO2tCQUFibEIsWSIsImZpbGUiOiJicm93c2VyL2Nvbm5lY3Rpb24vcmVtb3Rlcy1xdWV1ZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlIGZyb20gJ3BpbmtpZSc7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tICdldmVudHMnO1xuaW1wb3J0IHByb21pc2lmeUV2ZW50IGZyb20gJ3Byb21pc2lmeS1ldmVudCc7XG5pbXBvcnQgZ2V0VGltZUxpbWl0ZWRQcm9taXNlIGZyb20gJ3RpbWUtbGltaXQtcHJvbWlzZSc7XG5cblxuY29uc3QgUkVNT1RFX1JFRElSRUNUX1RJTUVPVVQgICAgICAgICAgID0gMTAwMDA7XG5jb25zdCBBRERJTkdfQ09OTkVDVElPTl9XQUlUSU5HX1RJTUVPVVQgPSAxMDAwMDtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVtb3Rlc1F1ZXVlIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuZXZlbnRzICAgICAgICAgICAgID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgICAgICB0aGlzLnNoaWZ0aW5nVGltZW91dCAgICA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB0aGlzLnBlbmRpbmdDb25uZWN0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIGFkZCAocmVtb3RlQ29ubmVjdGlvbikge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9uUmVhZHlQcm9taXNlID0gcHJvbWlzaWZ5RXZlbnQocmVtb3RlQ29ubmVjdGlvbiwgJ3JlYWR5JylcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVtb3ZlKHJlbW90ZUNvbm5lY3Rpb24pKTtcblxuICAgICAgICB0aGlzLnBlbmRpbmdDb25uZWN0aW9uc1tyZW1vdGVDb25uZWN0aW9uLmlkXSA9IHtcbiAgICAgICAgICAgIGNvbm5lY3Rpb246ICAgcmVtb3RlQ29ubmVjdGlvbixcbiAgICAgICAgICAgIHJlYWR5UHJvbWlzZTogY29ubmVjdGlvblJlYWR5UHJvbWlzZVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuZXZlbnRzLmVtaXQoJ2Nvbm5lY3Rpb24tYWRkZWQnLCByZW1vdGVDb25uZWN0aW9uLmlkKTtcbiAgICB9XG5cbiAgICByZW1vdmUgKHJlbW90ZUNvbm5lY3Rpb24pIHtcbiAgICAgICAgZGVsZXRlIHRoaXMucGVuZGluZ0Nvbm5lY3Rpb25zW3JlbW90ZUNvbm5lY3Rpb24uaWRdO1xuICAgIH1cblxuICAgIHNoaWZ0ICgpIHtcbiAgICAgICAgY29uc3Qgc2hpZnRpbmdQcm9taXNlID0gdGhpcy5zaGlmdGluZ1RpbWVvdXRcbiAgICAgICAgICAgIC50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgaGVhZElkID0gT2JqZWN0LmtleXModGhpcy5wZW5kaW5nQ29ubmVjdGlvbnMpWzBdO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFoZWFkSWQpXG4gICAgICAgICAgICAgICAgICAgIGhlYWRJZCA9IGF3YWl0IGdldFRpbWVMaW1pdGVkUHJvbWlzZShwcm9taXNpZnlFdmVudCh0aGlzLmV2ZW50cywgJ2Nvbm5lY3Rpb24tYWRkZWQnKSwgQURESU5HX0NPTk5FQ1RJT05fV0FJVElOR19USU1FT1VUKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBoZWFkSWQgPyB0aGlzLnBlbmRpbmdDb25uZWN0aW9uc1toZWFkSWRdLmNvbm5lY3Rpb24gOiBudWxsO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zaGlmdGluZ1RpbWVvdXQgPSBzaGlmdGluZ1Byb21pc2VcbiAgICAgICAgICAgIC50aGVuKGNvbm5lY3Rpb24gPT4ge1xuICAgICAgICAgICAgICAgIGlmICghY29ubmVjdGlvbilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldFRpbWVMaW1pdGVkUHJvbWlzZSh0aGlzLnBlbmRpbmdDb25uZWN0aW9uc1tjb25uZWN0aW9uLmlkXS5yZWFkeVByb21pc2UsIFJFTU9URV9SRURJUkVDVF9USU1FT1VUKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBzaGlmdGluZ1Byb21pc2U7XG4gICAgfVxufVxuIl19 diff --git a/lib/browser/connection/status.js b/lib/browser/connection/status.js new file mode 100644 index 00000000..ac263784 --- /dev/null +++ b/lib/browser/connection/status.js @@ -0,0 +1,9 @@ +'use strict'; + +exports.__esModule = true; +exports.default = { + ok: 'ok', + closing: 'closing' +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2Nvbm5lY3Rpb24vc3RhdHVzLmpzIl0sIm5hbWVzIjpbIm9rIiwiY2xvc2luZyJdLCJtYXBwaW5ncyI6Ijs7O2tCQUFlO0FBQ1hBLFFBQVMsSUFERTtBQUVYQyxhQUFTO0FBRkUsQyIsImZpbGUiOiJicm93c2VyL2Nvbm5lY3Rpb24vc3RhdHVzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQge1xuICAgIG9rOiAgICAgICdvaycsXG4gICAgY2xvc2luZzogJ2Nsb3NpbmcnXG59O1xuIl19 diff --git a/lib/browser/connection/unstable-network-mode.js b/lib/browser/connection/unstable-network-mode.js new file mode 100644 index 00000000..37ec8fff --- /dev/null +++ b/lib/browser/connection/unstable-network-mode.js @@ -0,0 +1,5 @@ +'use strict'; + +exports.__esModule = true; +const UNSTABLE_NETWORK_MODE_HEADER = exports.UNSTABLE_NETWORK_MODE_HEADER = 'x-testcafe-cache-page-request'; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2Nvbm5lY3Rpb24vdW5zdGFibGUtbmV0d29yay1tb2RlLmpzIl0sIm5hbWVzIjpbIlVOU1RBQkxFX05FVFdPUktfTU9ERV9IRUFERVIiXSwibWFwcGluZ3MiOiI7OztBQUFPLE1BQU1BLHNFQUErQiwrQkFBckMiLCJmaWxlIjoiYnJvd3Nlci9jb25uZWN0aW9uL3Vuc3RhYmxlLW5ldHdvcmstbW9kZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCBVTlNUQUJMRV9ORVRXT1JLX01PREVfSEVBREVSID0gJ3gtdGVzdGNhZmUtY2FjaGUtcGFnZS1yZXF1ZXN0JztcbiJdfQ== diff --git a/lib/browser/provider/built-in/chrome/cdp.js b/lib/browser/provider/built-in/chrome/cdp.js new file mode 100644 index 00000000..4b2d92b2 --- /dev/null +++ b/lib/browser/provider/built-in/chrome/cdp.js @@ -0,0 +1,205 @@ +'use strict'; + +exports.__esModule = true; +exports.resizeWindow = exports.takeScreenshot = exports.updateMobileViewportSize = exports.closeTab = exports.createClient = undefined; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +let getActiveTab = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (cdpPort, browserId) { + const tabs = yield _chromeRemoteInterface2.default.listTabs({ port: cdpPort }); + const tab = tabs.filter(function (t) { + return t.type === 'page' && t.url.indexOf(browserId) > -1; + })[0]; + + return tab; + }); + + return function getActiveTab(_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); + +let setEmulationBounds = (() => { + var _ref2 = (0, _asyncToGenerator3.default)(function* ({ client, config, viewportSize, emulatedDevicePixelRatio }) { + yield client.Emulation.setDeviceMetricsOverride({ + width: viewportSize.width, + height: viewportSize.height, + deviceScaleFactor: emulatedDevicePixelRatio, + mobile: config.mobile, + fitWindow: false + }); + + yield client.Emulation.setVisibleSize({ width: viewportSize.width, height: viewportSize.height }); + }); + + return function setEmulationBounds(_x3) { + return _ref2.apply(this, arguments); + }; +})(); + +let setEmulation = (() => { + var _ref3 = (0, _asyncToGenerator3.default)(function* (runtimeInfo) { + const client = runtimeInfo.client, + config = runtimeInfo.config; + + + if (config.userAgent !== void 0) yield client.Network.setUserAgentOverride({ userAgent: config.userAgent }); + + if (config.touch !== void 0) { + const touchConfig = { + enabled: config.touch, + configuration: config.mobile ? 'mobile' : 'desktop', + maxTouchPoints: 1 + }; + + if (client.Emulation.setEmitTouchEventsForMouse) yield client.Emulation.setEmitTouchEventsForMouse(touchConfig); + + if (client.Emulation.setTouchEmulationEnabled) yield client.Emulation.setTouchEmulationEnabled(touchConfig); + } + + yield resizeWindow({ width: config.width, height: config.height }, runtimeInfo); + }); + + return function setEmulation(_x4) { + return _ref3.apply(this, arguments); + }; +})(); + +let createClient = exports.createClient = (() => { + var _ref4 = (0, _asyncToGenerator3.default)(function* (runtimeInfo) { + const browserId = runtimeInfo.browserId, + config = runtimeInfo.config, + cdpPort = runtimeInfo.cdpPort; + + + let tab = null; + let client = null; + + try { + tab = yield getActiveTab(cdpPort, browserId); + + if (!tab) return; + + client = yield (0, _chromeRemoteInterface2.default)({ target: tab, port: cdpPort }); + } catch (e) { + return; + } + + runtimeInfo.tab = tab; + runtimeInfo.client = client; + + yield client.Page.enable(); + yield client.Network.enable(); + yield client.Runtime.enable(); + + const devicePixelRatioQueryResult = yield client.Runtime.evaluate({ expression: 'window.devicePixelRatio' }); + + runtimeInfo.originalDevicePixelRatio = devicePixelRatioQueryResult.result.value; + runtimeInfo.emulatedDevicePixelRatio = config.scaleFactor || runtimeInfo.originalDevicePixelRatio; + + if (config.emulation) yield setEmulation(runtimeInfo); + }); + + return function createClient(_x5) { + return _ref4.apply(this, arguments); + }; +})(); + +let closeTab = exports.closeTab = (() => { + var _ref5 = (0, _asyncToGenerator3.default)(function* ({ tab, cdpPort }) { + yield _chromeRemoteInterface2.default.closeTab({ id: tab.id, port: cdpPort }); + }); + + return function closeTab(_x6) { + return _ref5.apply(this, arguments); + }; +})(); + +let updateMobileViewportSize = exports.updateMobileViewportSize = (() => { + var _ref6 = (0, _asyncToGenerator3.default)(function* (runtimeInfo) { + const windowDimensionsQueryResult = yield runtimeInfo.client.Runtime.evaluate({ + expression: `(${_clientFunctions.GET_WINDOW_DIMENSIONS_INFO_SCRIPT})()`, + returnByValue: true + }); + + const windowDimensions = windowDimensionsQueryResult.result.value; + + runtimeInfo.viewportSize.width = windowDimensions.outerWidth; + runtimeInfo.viewportSize.height = windowDimensions.outerHeight; + }); + + return function updateMobileViewportSize(_x7) { + return _ref6.apply(this, arguments); + }; +})(); + +let takeScreenshot = exports.takeScreenshot = (() => { + var _ref7 = (0, _asyncToGenerator3.default)(function* (path, { client }) { + var _ref8 = yield client.Page.getLayoutMetrics(); + + const visualViewport = _ref8.visualViewport; + + + const clipRegion = { + x: visualViewport.pageX, + y: visualViewport.pageY, + width: visualViewport.clientWidth, + height: visualViewport.clientHeight, + scale: visualViewport.scale + }; + + const screenshot = yield client.Page.captureScreenshot({ fromSurface: true, clip: clipRegion }); + + yield (0, _promisifiedFunctions.writeFile)(path, screenshot.data, { encoding: 'base64' }); + }); + + return function takeScreenshot(_x8, _x9) { + return _ref7.apply(this, arguments); + }; +})(); + +let resizeWindow = exports.resizeWindow = (() => { + var _ref9 = (0, _asyncToGenerator3.default)(function* (newDimensions, runtimeInfo) { + const browserId = runtimeInfo.browserId, + config = runtimeInfo.config, + viewportSize = runtimeInfo.viewportSize, + providerMethods = runtimeInfo.providerMethods; + + + const currentWidth = viewportSize.width; + const currentHeight = viewportSize.height; + const newWidth = newDimensions.width || currentWidth; + const newHeight = newDimensions.height || currentHeight; + + if (!config.headless) yield providerMethods.resizeLocalBrowserWindow(browserId, newWidth, newHeight, currentWidth, currentHeight); + + viewportSize.width = newWidth; + viewportSize.height = newHeight; + + if (config.emulation) yield setEmulationBounds(runtimeInfo); + }); + + return function resizeWindow(_x10, _x11) { + return _ref9.apply(this, arguments); + }; +})(); + +exports.isHeadlessTab = isHeadlessTab; + +var _chromeRemoteInterface = require('chrome-remote-interface'); + +var _chromeRemoteInterface2 = _interopRequireDefault(_chromeRemoteInterface); + +var _promisifiedFunctions = require('../../../../utils/promisified-functions'); + +var _clientFunctions = require('../../utils/client-functions'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function isHeadlessTab({ tab, config }) { + return tab && config.headless; +} +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2Nocm9tZS9jZHAuanMiXSwibmFtZXMiOlsiY2RwUG9ydCIsImJyb3dzZXJJZCIsInRhYnMiLCJyZW1vdGVDaHJvbWUiLCJsaXN0VGFicyIsInBvcnQiLCJ0YWIiLCJmaWx0ZXIiLCJ0IiwidHlwZSIsInVybCIsImluZGV4T2YiLCJnZXRBY3RpdmVUYWIiLCJjbGllbnQiLCJjb25maWciLCJ2aWV3cG9ydFNpemUiLCJlbXVsYXRlZERldmljZVBpeGVsUmF0aW8iLCJFbXVsYXRpb24iLCJzZXREZXZpY2VNZXRyaWNzT3ZlcnJpZGUiLCJ3aWR0aCIsImhlaWdodCIsImRldmljZVNjYWxlRmFjdG9yIiwibW9iaWxlIiwiZml0V2luZG93Iiwic2V0VmlzaWJsZVNpemUiLCJzZXRFbXVsYXRpb25Cb3VuZHMiLCJydW50aW1lSW5mbyIsInVzZXJBZ2VudCIsIk5ldHdvcmsiLCJzZXRVc2VyQWdlbnRPdmVycmlkZSIsInRvdWNoIiwidG91Y2hDb25maWciLCJlbmFibGVkIiwiY29uZmlndXJhdGlvbiIsIm1heFRvdWNoUG9pbnRzIiwic2V0RW1pdFRvdWNoRXZlbnRzRm9yTW91c2UiLCJzZXRUb3VjaEVtdWxhdGlvbkVuYWJsZWQiLCJyZXNpemVXaW5kb3ciLCJzZXRFbXVsYXRpb24iLCJ0YXJnZXQiLCJlIiwiUGFnZSIsImVuYWJsZSIsIlJ1bnRpbWUiLCJkZXZpY2VQaXhlbFJhdGlvUXVlcnlSZXN1bHQiLCJldmFsdWF0ZSIsImV4cHJlc3Npb24iLCJvcmlnaW5hbERldmljZVBpeGVsUmF0aW8iLCJyZXN1bHQiLCJ2YWx1ZSIsInNjYWxlRmFjdG9yIiwiZW11bGF0aW9uIiwiY3JlYXRlQ2xpZW50IiwiY2xvc2VUYWIiLCJpZCIsIndpbmRvd0RpbWVuc2lvbnNRdWVyeVJlc3VsdCIsIkdFVF9XSU5ET1dfRElNRU5TSU9OU19JTkZPX1NDUklQVCIsInJldHVybkJ5VmFsdWUiLCJ3aW5kb3dEaW1lbnNpb25zIiwib3V0ZXJXaWR0aCIsIm91dGVySGVpZ2h0IiwidXBkYXRlTW9iaWxlVmlld3BvcnRTaXplIiwicGF0aCIsImdldExheW91dE1ldHJpY3MiLCJ2aXN1YWxWaWV3cG9ydCIsImNsaXBSZWdpb24iLCJ4IiwicGFnZVgiLCJ5IiwicGFnZVkiLCJjbGllbnRXaWR0aCIsImNsaWVudEhlaWdodCIsInNjYWxlIiwic2NyZWVuc2hvdCIsImNhcHR1cmVTY3JlZW5zaG90IiwiZnJvbVN1cmZhY2UiLCJjbGlwIiwiZGF0YSIsImVuY29kaW5nIiwidGFrZVNjcmVlbnNob3QiLCJuZXdEaW1lbnNpb25zIiwicHJvdmlkZXJNZXRob2RzIiwiY3VycmVudFdpZHRoIiwiY3VycmVudEhlaWdodCIsIm5ld1dpZHRoIiwibmV3SGVpZ2h0IiwiaGVhZGxlc3MiLCJyZXNpemVMb2NhbEJyb3dzZXJXaW5kb3ciLCJpc0hlYWRsZXNzVGFiIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OytDQUtBLFdBQTZCQSxPQUE3QixFQUFzQ0MsU0FBdEMsRUFBaUQ7QUFDN0MsY0FBTUMsT0FBTyxNQUFNQyxnQ0FBYUMsUUFBYixDQUFzQixFQUFFQyxNQUFNTCxPQUFSLEVBQXRCLENBQW5CO0FBQ0EsY0FBTU0sTUFBT0osS0FBS0ssTUFBTCxDQUFZO0FBQUEsbUJBQUtDLEVBQUVDLElBQUYsS0FBVyxNQUFYLElBQXFCRCxFQUFFRSxHQUFGLENBQU1DLE9BQU4sQ0FBY1YsU0FBZCxJQUEyQixDQUFDLENBQXREO0FBQUEsU0FBWixFQUFxRSxDQUFyRSxDQUFiOztBQUVBLGVBQU9LLEdBQVA7QUFDSCxLOztvQkFMY00sWTs7Ozs7O2dEQU9mLFdBQW1DLEVBQUVDLE1BQUYsRUFBVUMsTUFBVixFQUFrQkMsWUFBbEIsRUFBZ0NDLHdCQUFoQyxFQUFuQyxFQUErRjtBQUMzRixjQUFNSCxPQUFPSSxTQUFQLENBQWlCQyx3QkFBakIsQ0FBMEM7QUFDNUNDLG1CQUFtQkosYUFBYUksS0FEWTtBQUU1Q0Msb0JBQW1CTCxhQUFhSyxN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OlsiaW1wb3J0IHJlbW90ZUNocm9tZSBmcm9tICdjaHJvbWUtcmVtb3RlLWludGVyZmFjZSc7XG5pbXBvcnQgeyB3cml0ZUZpbGUgfSBmcm9tICcuLi8uLi8uLi8uLi91dGlscy9wcm9taXNpZmllZC1mdW5jdGlvbnMnO1xuaW1wb3J0IHsgR0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUIH0gZnJvbSAnLi4vLi4vdXRpbHMvY2xpZW50LWZ1bmN0aW9ucyc7XG5cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QWN0aXZlVGFiIChjZHBQb3J0LCBicm93c2VySWQpIHtcbiAgICBjb25zdCB0YWJzID0gYXdhaXQgcmVtb3RlQ2hyb21lLmxpc3RUYWJzKHsgcG9ydDogY2RwUG9ydCB9KTtcbiAgICBjb25zdCB0YWIgID0gdGFicy5maWx0ZXIodCA9PiB0LnR5cGUgPT09ICdwYWdlJyAmJiB0LnVybC5pbmRleE9mKGJyb3dzZXJJZCkgPiAtMSlbMF07XG5cbiAgICByZXR1cm4gdGFiO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXRFbXVsYXRpb25Cb3VuZHMgKHsgY2xpZW50LCBjb25maWcsIHZpZXdwb3J0U2l6ZSwgZW11bGF0ZWREZXZpY2VQaXhlbFJhdGlvIH0pIHtcbiAgICBhd2FpdCBjbGllbnQuRW11bGF0aW9uLnNldERldmljZU1ldHJpY3NPdmVycmlkZSh7XG4gICAgICAgIHdpZHRoOiAgICAgICAgICAgICB2aWV3cG9ydFNpemUud2lkdGgsXG4gICAgICAgIGhlaWdodDogICAgICAgICAgICB2aWV3cG9ydFNpemUuaGVpZ2h0LFxuICAgICAgICBkZXZpY2VTY2FsZUZhY3RvcjogZW11bGF0ZWREZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgICBtb2JpbGU6ICAgICAgICAgICAgY29uZmlnLm1vYmlsZSxcbiAgICAgICAgZml0V2luZG93OiAgICAgICAgIGZhbHNlXG4gICAgfSk7XG5cbiAgICBhd2FpdCBjbGllbnQuRW11bGF0aW9uLnNldFZpc2libGVTaXplKHsgd2lkdGg6IHZpZXdwb3J0U2l6ZS53aWR0aCwgaGVpZ2h0OiB2aWV3cG9ydFNpemUuaGVpZ2h0IH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXRFbXVsYXRpb24gKHJ1bnRpbWVJbmZvKSB7XG4gICAgY29uc3QgeyBjbGllbnQsIGNvbmZpZyB9ID0gcnVudGltZUluZm87XG5cbiAgICBpZiAoY29uZmlnLnVzZXJBZ2VudCAhPT0gdm9pZCAwKVxuICAgICAgICBhd2FpdCBjbGllbnQuTmV0d29yay5zZXRVc2VyQWdlbnRPdmVycmlkZSh7IHVzZXJBZ2VudDogY29uZmlnLnVzZXJBZ2VudCB9KTtcblxuICAgIGlmIChjb25maWcudG91Y2ggIT09IHZvaWQgMCkge1xuICAgICAgICBjb25zdCB0b3VjaENvbmZpZyA9IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6ICAgICAgICBjb25maWcudG91Y2gsXG4gICAgICAgICAgICBjb25maWd1cmF0aW9uOiAgY29uZmlnLm1vYmlsZSA/ICdtb2JpbGUnIDogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgbWF4VG91Y2hQb2ludHM6IDFcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoY2xpZW50LkVtdWxhdGlvbi5zZXRFbWl0VG91Y2hFdmVudHNGb3JNb3VzZSlcbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5FbXVsYXRpb24uc2V0RW1pdFRvdWNoRXZlbnRzRm9yTW91c2UodG91Y2hDb25maWcpO1xuXG4gICAgICAgIGlmIChjbGllbnQuRW11bGF0aW9uLnNldFRvdWNoRW11bGF0aW9uRW5hYmxlZClcbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5FbXVsYXRpb24uc2V0VG91Y2hFbXVsYXRpb25FbmFibGVkKHRvdWNoQ29uZmlnKTtcbiAgICB9XG5cbiAgICBhd2FpdCByZXNpemVXaW5kb3coeyB3aWR0aDogY29uZmlnLndpZHRoLCBoZWlnaHQ6IGNvbmZpZy5oZWlnaHQgfSwgcnVudGltZUluZm8pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlQ2xpZW50IChydW50aW1lSW5mbykge1xuICAgIGNvbnN0IHsgYnJvd3NlcklkLCBjb25maWcsIGNkcFBvcnQgfSA9IHJ1bnRpbWVJbmZvO1xuXG4gICAgbGV0IHRhYiAgICA9IG51bGw7XG4gICAgbGV0IGNsaWVudCA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgICB0YWIgPSBhd2FpdCBnZXRBY3RpdmVUYWIoY2RwUG9ydCwgYnJvd3NlcklkKTtcblxuICAgICAgICBpZiAoIXRhYilcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjbGllbnQgPSBhd2FpdCByZW1vdGVDaHJvbWUoeyB0YXJnZXQ6IHRhYiwgcG9ydDogY2RwUG9ydCB9KTtcbiAgICB9XG4gICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHJ1bnRpbWVJbmZvLnRhYiAgICA9IHRhYjtcbiAgICBydW50aW1lSW5mby5jbGllbnQgPSBjbGllbnQ7XG5cbiAgICBhd2FpdCBjbGllbnQuUGFnZS5lbmFibGUoKTtcbiAgICBhd2FpdCBjbGllbnQuTmV0d29yay5lbmFibGUoKTtcbiAgICBhd2FpdCBjbGllbnQuUnVudGltZS5lbmFibGUoKTtcblxuICAgIGNvbnN0IGRldmljZVBpeGVsUmF0aW9RdWVyeVJlc3VsdCA9IGF3YWl0IGNsaWVudC5SdW50aW1lLmV2YWx1YXRlKHsgZXhwcmVzc2lvbjogJ3dpbmRvdy5kZXZpY2VQaXhlbFJhdGlvJyB9KTtcblxuICAgIHJ1bnRpbWVJbmZvLm9yaWdpbmFsRGV2aWNlUGl4ZWxSYXRpbyA9IGRldmljZVBpeGVsUmF0aW9RdWVyeVJlc3VsdC5yZXN1bHQudmFsdWU7XG4gICAgcnVudGltZUluZm8uZW11bGF0ZWREZXZpY2VQaXhlbFJhdGlvID0gY29uZmlnLnNjYWxlRmFjdG9yIHx8IHJ1bnRpbWVJbmZvLm9yaWdpbmFsRGV2aWNlUGl4ZWxSYXRpbztcblxuICAgIGlmIChjb25maWcuZW11bGF0aW9uKVxuICAgICAgICBhd2FpdCBzZXRFbXVsYXRpb24ocnVudGltZUluZm8pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNIZWFkbGVzc1RhYiAoeyB0YWIsIGNvbmZpZyB9KSB7XG4gICAgcmV0dXJuIHRhYiAmJiBjb25maWcuaGVhZGxlc3M7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZVRhYiAoeyB0YWIsIGNkcFBvcnQgfSkge1xuICAgIGF3YWl0IHJlbW90ZUNocm9tZS5jbG9zZVRhYih7IGlkOiB0YWIuaWQsIHBvcnQ6IGNkcFBvcnQgfSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB1cGRhdGVNb2JpbGVWaWV3cG9ydFNpemUgKHJ1bnRpbWVJbmZvKSB7XG4gICAgY29uc3Qgd2luZG93RGltZW5zaW9uc1F1ZXJ5UmVzdWx0ID0gYXdhaXQgcnVudGltZUluZm8uY2xpZW50LlJ1bnRpbWUuZXZhbHVhdGUoe1xuICAgICAgICBleHByZXNzaW9uOiAgICBgKCR7R0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUfSkoKWAsXG4gICAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICB9KTtcblxuICAgIGNvbnN0IHdpbmRvd0RpbWVuc2lvbnMgPSB3aW5kb3dEaW1lbnNpb25zUXVlcnlSZXN1bHQucmVzdWx0LnZhbHVlO1xuXG4gICAgcnVudGltZUluZm8udmlld3BvcnRTaXplLndpZHRoICA9IHdpbmRvd0RpbWVuc2lvbnMub3V0ZXJXaWR0aDtcbiAgICBydW50aW1lSW5mby52aWV3cG9ydFNpemUuaGVpZ2h0ID0gd2luZG93RGltZW5zaW9ucy5vdXRlckhlaWdodDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRha2VTY3JlZW5zaG90IChwYXRoLCB7IGNsaWVudCB9KSB7XG4gICAgY29uc3QgeyB2aXN1YWxWaWV3cG9ydCB9ID0gYXdhaXQgY2xpZW50LlBhZ2UuZ2V0TGF5b3V0TWV0cmljcygpO1xuXG4gICAgY29uc3QgY2xpcFJlZ2lvbiA9IHtcbiAgICAgICAgeDogICAgICB2aXN1YWxWaWV3cG9ydC5wYWdlWCxcbiAgICAgICAgeTogICAgICB2aXN1YWxWaWV3cG9ydC5wYWdlWSxcbiAgICAgICAgd2lkdGg6ICB2aXN1YWxWaWV3cG9ydC5jbGllbnRXaWR0aCxcbiAgICAgICAgaGVpZ2h0OiB2aXN1YWxWaWV3cG9ydC5jbGllbnRIZWlnaHQsXG4gICAgICAgIHNjYWxlOiAgdmlzdWFsVmlld3BvcnQuc2NhbGVcbiAgICB9O1xuXG4gICAgY29uc3Qgc2NyZWVuc2hvdCA9IGF3YWl0IGNsaWVudC5QYWdlLmNhcHR1cmVTY3JlZW5zaG90KHsgZnJvbVN1cmZhY2U6IHRydWUsIGNsaXA6IGNsaXBSZWdpb24gfSk7XG5cbiAgICBhd2FpdCB3cml0ZUZpbGUocGF0aCwgc2NyZWVuc2hvdC5kYXRhLCB7IGVuY29kaW5nOiAnYmFzZTY0JyB9KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc2l6ZVdpbmRvdyAobmV3RGltZW5zaW9ucywgcnVudGltZUluZm8pIHtcbiAgICBjb25zdCB7IGJyb3dzZXJJZCwgY29uZmlnLCB2aWV3cG9ydFNpemUsIHByb3ZpZGVyTWV0aG9kcyB9ID0gcnVudGltZUluZm87XG5cbiAgICBjb25zdCBjdXJyZW50V2lkdGggID0gdmlld3BvcnRTaXplLndpZHRoO1xuICAgIGNvbnN0IGN1cnJlbnRIZWlnaHQgPSB2aWV3cG9ydFNpemUuaGVpZ2h0O1xuICAgIGNvbnN0IG5ld1dpZHRoICAgICAgPSBuZXdEaW1lbnNpb25zLndpZHRoIHx8IGN1cnJlbnRXaWR0aDtcbiAgICBjb25zdCBuZXdIZWlnaHQgICAgID0gbmV3RGltZW5zaW9ucy5oZWlnaHQgfHwgY3VycmVudEhlaWdodDtcblxuICAgIGlmICghY29uZmlnLmhlYWRsZXNzKVxuICAgICAgICBhd2FpdCBwcm92aWRlck1ldGhvZHMucmVzaXplTG9jYWxCcm93c2VyV2luZG93KGJyb3dzZXJJZCwgbmV3V2lkdGgsIG5ld0hlaWdodCwgY3VycmVudFdpZHRoLCBjdXJyZW50SGVpZ2h0KTtcblxuICAgIHZpZXdwb3J0U2l6ZS53aWR0aCAgPSBuZXdXaWR0aDtcbiAgICB2aWV3cG9ydFNpemUuaGVpZ2h0ID0gbmV3SGVpZ2h0O1xuXG4gICAgaWYgKGNvbmZpZy5lbXVsYXRpb24pXG4gICAgICAgIGF3YWl0IHNldEVtdWxhdGlvbkJvdW5kcyhydW50aW1lSW5mbyk7XG59XG4iXX0= diff --git a/lib/browser/provider/built-in/chrome/config.js b/lib/browser/provider/built-in/chrome/config.js new file mode 100644 index 00000000..955adc0b --- /dev/null +++ b/lib/browser/provider/built-in/chrome/config.js @@ -0,0 +1,141 @@ +'use strict'; + +exports.__esModule = true; + +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + +var _isNan = require('babel-runtime/core-js/number/is-nan'); + +var _isNan2 = _interopRequireDefault(_isNan); + +exports.default = function (configString) { + if (!configCache[configString]) configCache[configString] = getNewConfig(configString); + + return configCache[configString]; +}; + +var _chromeEmulatedDevicesList = require('chrome-emulated-devices-list'); + +var _chromeEmulatedDevicesList2 = _interopRequireDefault(_chromeEmulatedDevicesList); + +var _lodash = require('lodash'); + +var _argumentParsing = require('../../utils/argument-parsing'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const HEADLESS_DEFAULT_WIDTH = 1280; +const HEADLESS_DEFAULT_HEIGHT = 800; + +const AVAILABLE_MODES = ['userProfile', 'headless', 'emulation']; + +const configCache = {}; + +function hasCustomProfile(userArgs) { + return !!userArgs.match(/--user-data-dir=/); +} + +function parseModes(modesStr, userArgs) { + const parsed = (0, _argumentParsing.splitEscaped)(modesStr, ':'); + const path = (0, _argumentParsing.getPathFromParsedModes)(parsed, AVAILABLE_MODES); + const detectedModes = (0, _argumentParsing.getModes)(parsed, AVAILABLE_MODES); + let optionsString = ''; + + if (parsed.length) optionsString = parsed.shift(); + + while (parsed.length) optionsString += ':' + parsed.shift(); + + const modes = { + path: path, + userProfile: detectedModes.userProfile || hasCustomProfile(userArgs), + headless: detectedModes.headless, + emulation: detectedModes.emulation || detectedModes.headless + }; + + return { modes, optionsString }; +} + +function simplifyDeviceName(deviceName) { + return deviceName.replace(/\s/g, '').toLowerCase(); +} + +function findDevice(deviceName) { + const simpleName = simplifyDeviceName(deviceName); + + return _chromeEmulatedDevicesList2.default.filter(device => simplifyDeviceName(device.title).indexOf(simpleName) >= 0)[0]; +} + +function getDeviceBasedOptions(deviceName, orientation) { + if (!deviceName) return {}; + + const deviceData = findDevice(deviceName); + + if (!deviceData) return {}; + + const mobile = deviceData.capabilities.indexOf('mobile') >= 0; + + if (!orientation) orientation = mobile ? 'vertical' : 'horizontal'; + + return { + mobile: mobile, + orientation: orientation, + touch: deviceData.capabilities.indexOf('touch') >= 0, + width: deviceData.screen[orientation].width, + height: deviceData.screen[orientation].height, + scaleFactor: deviceData.screen['device-pixel-ratio'], + userAgent: deviceData['user-agent'] + }; +} + +function parseOptions(str, modes) { + const parsed = (0, _argumentParsing.splitEscaped)(str, ';'); + + const baseOptions = { + width: modes.headless ? HEADLESS_DEFAULT_WIDTH : 0, + height: modes.headless ? HEADLESS_DEFAULT_HEIGHT : 0, + scaleFactor: 0, + mobile: false, + cdpPort: (0, _argumentParsing.findMatch)(parsed, /^cdpPort=(.*)/) + }; + + const deviceName = (0, _argumentParsing.findMatch)(parsed, /^device=(.*)/); + const orientation = (0, _argumentParsing.findMatch)(parsed, /^orientation=(.*)/); + const deviceBasedOptions = getDeviceBasedOptions(deviceName, orientation); + + let specifiedDeviceOptions = { + orientation: orientation, + touch: (0, _argumentParsing.hasMatch)(parsed, /^touch=/) ? (0, _argumentParsing.isMatchTrue)(parsed, /^touch=(.*)/) : void 0, + mobile: (0, _argumentParsing.isMatchTrue)(parsed, /^mobile=(.*)/), + width: Number((0, _argumentParsing.findMatch)(parsed, /^width=(.*)/) || NaN), + height: Number((0, _argumentParsing.findMatch)(parsed, /^height=(.*)/) || NaN), + scaleFactor: Number((0, _argumentParsing.findMatch)(parsed, /^scaleFactor=(.*)/) || NaN), + userAgent: (0, _argumentParsing.findMatch)(parsed, /^userAgent=(.*)/) + }; + + specifiedDeviceOptions = (0, _lodash.pickBy)(specifiedDeviceOptions, optionValue => { + return optionValue !== void 0 && optionValue !== '' && !(0, _isNan2.default)(optionValue); + }); + + return (0, _assign2.default)(baseOptions, deviceBasedOptions, specifiedDeviceOptions); +} + +function getNewConfig(configString) { + var _parseConfig = (0, _argumentParsing.parseConfig)(configString); + + const userArgs = _parseConfig.userArgs, + modesString = _parseConfig.modesString; + + var _parseModes = parseModes(modesString, userArgs); + + const modes = _parseModes.modes, + optionsString = _parseModes.optionsString; + + const options = parseOptions(optionsString, modes); + + return (0, _assign2.default)({ userArgs }, modes, options); +} + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2Nocm9tZS9jb25maWcuanMiXSwibmFtZXMiOlsiY29uZmlnU3RyaW5nIiwiY29uZmlnQ2FjaGUiLCJnZXROZXdDb25maWciLCJIRUFETEVTU19ERUZBVUxUX1dJRFRIIiwiSEVBRExFU1NfREVGQVVMVF9IRUlHSFQiLCJBVkFJTEFCTEVfTU9ERVMiLCJoYXNDdXN0b21Qcm9maWxlIiwidXNlckFyZ3MiLCJtYXRjaCIsInBhcnNlTW9kZXMiLCJtb2Rlc1N0ciIsInBhcnNlZCIsInBhdGgiLCJkZXRlY3RlZE1vZGVzIiwib3B0aW9uc1N0cmluZyIsImxlbmd0aCIsInNoaWZ0IiwibW9kZXMiLCJ1c2VyUHJvZmlsZSIsImhlYWRsZXNzIiwiZW11bGF0aW9uIiwic2ltcGxpZnlEZXZpY2VOYW1lIiwiZGV2aWNlTmFtZSIsInJlcGxhY2UiLCJ0b0xvd2VyQ2FzZSIsImZpbmREZXZpY2UiLCJzaW1wbGVOYW1lIiwiZW11bGF0ZWREZXZpY2VzIiwiZmlsdGVyIiwiZGV2aWNlIiwidGl0bGUiLCJpbmRleE9mIiwiZ2V0RGV2aWNlQmFzZWRPcHRpb25zIiwib3JpZW50YXRpb24iLCJkZXZpY2VEYXRhIiwibW9iaWxlIiwiY2FwYWJpbGl0aWVzIiwidG91Y2giLCJ3aWR0aCIsInNjcmVlbiIsImhlaWdodCIsInNjYWxlRmFjdG9yIiwidXNlckFnZW50IiwicGFyc2VPcHRpb25zIiwic3RyIiwiYmFzZU9wdGlvbnMiLCJjZHBQb3J0IiwiZGV2aWNlQmFzZWRPcHRpb25zIiwic3BlY2lmaWVkRGV2aWNlT3B0aW9ucyIsIk51bWJlciIsIk5hTiIsIm9wdGlvblZhbHVlIiwibW9kZXNTdHJpbmciLCJvcHRpb25zIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7a0JBb0hlLFVBQVVBLFlBQVYsRUFBd0I7QUFDbkMsUUFBSSxDQUFDQyxZQUFZRCxZQUFaLENBQUwsRUFDSUMsWUFBWUQsWUFBWixJQUE0QkUsYUFBYUYsWUFBYixDQUE1Qjs7QUFFSixXQUFPQyxZQUFZRCxZQUFaLENBQVA7QUFDSCxDOztBQXpIRDs7OztBQUNBOztBQUNBOzs7O0FBS0EsTUFBTUcseUJBQTBCLElBQWhDO0FBQ0EsTUFBTUMsMEJBQTBCLEdBQWhDOztBQUVBLE1BQU1DLGtCQUFrQixDQUFDLGFBQUQsRUFBZ0IsVUFBaEIsRUFBNEIsV0FBNUIsQ0FBeEI7O0FBRUEsTUFBTUosY0FBYyxFQUFwQjs7QUFFQSxTQUFTSyxnQkFBVCxDQUEyQkMsUUFBM0IsRUFBcUM7QUFDakMsV0FBTyxDQUFDLENBQUNBLFNBQVNDLEtBQVQsQ0FBZSxrQkFBZixDQUFUO0FBQ0g7O0FBRUQsU0FBU0MsVUFBVCxDQUFxQkMsUUFBckIsRUFBK0JILFFBQS9CLEVBQXlDO0FBQ3JDLFVBQU1JLFNBQWdCLG1DQUFhRCxRQUFiLEVBQXVCLEdBQXZCLENBQXRCO0FBQ0EsVUFBTUUsT0FBZ0IsNkNBQXVCRCxNQUF2QixFQUErQk4sZUFBL0IsQ0FBdEI7QUFDQSxVQUFNUSxnQkFBZ0IsK0JBQVNGLE1BQVQsRUFBaUJOLGVBQWpCLENBQXRCO0FBQ0EsUUFBSVMsZ0JBQWdCLEVBQXBCOztBQUVBLFFBQUlILE9BQU9JLE1BQVgsRUFDSUQsZ0JBQWdCSCxPQUFPSyxLQUFQLEVBQWhCOztBQUVKLFdBQU9MLE9BQU9JLE1BQWQsRUFDSUQsaUJBQWlCLE1BQU1ILE9BQU9LLEtBQVAsRUFBdkI7O0FBRUosVUFBTUMsUUFBUTtBQUNWTCxjQUFhQSxJQURIO0FBRVZNLHFCQUFhTCxjQUFjSyxXQUFkLElBQTZCWixpQkFBaUJDLFFBQWpCLENBRmhDO0FBR1ZZLGtCQUFhTixjQUFjTSxRQUhqQjtBQUlWQyxtQkFBYVAsY0FBY08sU0FBZCxJQUEyQlAsY0FBY007QUFKNUMsS0FBZDs7QUFPQSxXQUFPLEVBQUVGLEtBQUYsRUFBU0gsYUFBVCxFQUFQO0FBQ0g7O0FBRUQsU0FBU08sa0JBQVQsQ0FBNkJDLFVBQTdCLEVBQXlDO0FBQ3JDLFdBQU9BLFdBQVdDLE9BQVgsQ0FBbUIsS0FBbkIsRUFBMEIsRUFBMUIsRUFBOEJDLFdBQTlCLEVBQVA7QUFDSDs7QUFFRCxTQUFTQyxVQUFULENBQXFCSCxVQUFyQixFQUFpQztBQUM3QixVQUFNSSxhQUFhTCxtQkFBbUJDLFVBQW5CLENBQW5COztBQUVBLFdBQU9LLG9DQUFnQkMsTUFBaEIsQ0FBdUJDLFVBQVVSLG1CQUFtQlEsT0FBT0MsS0FBMUIsRUFBaUNDLE9BQWpDLENBQXlDTCxVQUF6QyxLQUF3RCxDQUF6RixFQUE0RixDQUE1RixDQUFQO0FBQ0g7O0FBRUQsU0FBU00scUJBQVQsQ0FBZ0NWLFVBQWhDLEVBQTRDVyxXQUE1QyxFQUF5RDtBQUNyRCxRQUFJLENBQUNYLFVBQUwsRUFDSSxPQUFPLEVBQVA7O0FBRUosVUFBTVksYUFBYVQsV0FBV0gsVUFBWCxDQUFuQjs7QUFFQSxRQUFJLENBQUNZLFVBQUwsRUFDSSxPQUFPLEVBQVA7O0FBRUosVUFBTUMsU0FBU0QsV0FBV0UsWUFBWCxDQUF3QkwsT0FBeEIsQ0FBZ0MsUUFBaEMsS0FBNkMsQ0FBNUQ7O0FBRUEsUUFBSSxDQUFDRSxXQUFMLEVBQ0lBLGNBQWNFLFNBQVMsVUFBVCxHQUFzQixZQUFwQzs7QUFFSixXQUFPO0FBQ0hBLGdCQUFhQSxNQURWO0FBRUhGLHFCQUFhQSxXQUZWO0FBR0hJLGVBQWFILFdBQVdFLFlBQVgsQ0FBd0JMLE9BQXhCLENBQWdDLE9BQWhDLEtBQTRDLENBSHREO0FBSUhPLGVBQWFKLFdBQVdLLE1BQVgsQ0FBa0JOLFdBQWxCLEVBQStCSyxLQUp6QztBQUtIRSxnQkFBYU4sV0FBV0ssTUFBWCxDQUFrQk4sV0FBbEIsRUFBK0JPLE1BTHpDO0FBTUhDLHFCQUFhUCxXQUFXSyxNQUFYLENBQWtCLG9CQUFsQixDQU5WO0FBT0hHLG1CQUFhUixXQUFXLFlBQVg7QUFQVixLQUFQO0FBU0g7O0FBRUQsU0FBU1MsWUFBVCxDQUF1QkMsR0FBdkIsRUFBNEIzQixLQUE1QixFQUFtQztBQUMvQixVQUFNTixTQUFTLG1DQUFhaUMsR0FBYixFQUFrQixHQUFsQixDQUFmOztBQUVBLFVBQU1DLGNBQWM7QUFDaEJQLGVBQWFyQixNQUFNRSxRQUFOLEdBQWlCaEIsc0JBQWpCLEdBQTBDLENBRHZDO0FBRWhCcUMsZ0JBQWF2QixNQUFNRSxRQUFOLEdBQWlCZix1QkFBakIsR0FBMkMsQ0FGeEM7QUFHaEJxQyxxQkFBYSxDQUhHO0FBSWhCTixnQkFBYSxLQUpHO0FBS2hCVyxpQkFBYSxnQ0FBVW5DLE1BQVYsRUFBa0IsZUFBbEI7QUFMRyxLQUFwQjs7QUFRQSxVQUFNVyxhQUFxQixnQ0FBVVgsTUFBVixFQUFrQixjQUFsQixDQUEzQjtBQUNBLFVBQU1zQixjQUFxQixnQ0FBVXRCLE1BQVYsRUFBa0IsbUJBQWxCLENBQTNCO0FBQ0EsVUFBTW9DLHFCQUFxQmYsc0JBQXNCVixVQUF0QixFQUFrQ1csV0FBbEMsQ0FBM0I7O0FBRUEsUUFBSWUseUJBQXlCO0FBQ3pCZixxQkFBYUEsV0FEWTtBQUV6QkksZUFBYSwrQkFBUzFCLE1BQVQsRUFBaUIsU0FBakIsSUFBOEIsa0NBQVlBLE1BQVosRUFBb0IsYUFBcEIsQ0FBOUIsR0FBbUUsS0FBSyxDQUY1RDtBQUd6QndCLGdCQUFhLGtDQUFZeEIsTUFBWixFQUFvQixjQUFwQixDQUhZO0FBSXpCMkIsZUFBYVcsT0FBTyxnQ0FBVXRDLE1BQVYsRUFBa0IsYUFBbEIsS0FBb0N1QyxHQUEzQyxDQUpZO0FBS3pCVixnQkFBYVMsT0FBTyxnQ0FBVXRDLE1BQVYsRUFBa0IsY0FBbEIsS0FBcUN1QyxHQUE1QyxDQUxZO0FBTXpCVCxxQkFBYVEsT0FBTyxnQ0FBVXRDLE1BQVYsRUFBa0IsbUJBQWxCLEtBQTBDdUMsR0FBakQsQ0FOWTtBQU96QlIsbUJBQWEsZ0NBQVUvQixNQUFWLEVBQWtCLGlCQUFsQjtBQVBZLEtBQTdCOztBQVVBcUMsNkJBQXlCLG9CQUFpQkEsc0JBQWpCLEVBQXlDRyxlQUFlO0FBQzdFLGVBQU9BLGdCQUFnQixLQUFLLENBQXJCLElBQTBCQSxnQkFBZ0IsRUFBMUMsSUFBZ0QsQ0FBQyxxQkFBYUEsV0FBYixDQUF4RDtBQUNILEtBRndCLENBQXpCOztBQUlBLFdBQU8sc0JBQWNOLFdBQWQsRUFBMkJFLGtCQUEzQixFQUErQ0Msc0JBQS9DLENBQVA7QUFDSDs7QUFHRCxTQUFTOUMsWUFBVCxDQUF1QkYsWUFBdkIsRUFBcUM7QUFBQSx1QkFDQyxrQ0FBWUEsWUFBWixDQUREOztBQUFBLFVBQ3pCTyxRQUR5QixnQkFDekJBLFFBRHlCO0FBQUEsVUFDZjZDLFdBRGUsZ0JBQ2ZBLFdBRGU7O0FBQUEsc0JBRUMzQyxXQUFXMkMsV0FBWCxFQUF3QjdDLFFBQXhCLENBRkQ7O0FBQUEsVUFFekJVLEtBRnlCLGVBRXpCQSxLQUZ5QjtBQUFBLFVBRWxCSCxhQUZrQixlQUVsQkEsYUFGa0I7O0FBR2pDLFVBQU11QyxVQUE0QlYsYUFBYTdCLGFBQWIsRUFBNEJHLEtBQTVCLENBQWxDOztBQUVBLFdBQU8sc0JBQWMsRUFBRVYsUUFBRixFQUFkLEVBQTRCVSxLQUE1QixFQUFtQ29DLE9BQW5DLENBQVA7QUFDSCIsImZpbGUiOiJicm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2Nocm9tZS9jb25maWcuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZW11bGF0ZWREZXZpY2VzIGZyb20gJ2Nocm9tZS1lbXVsYXRlZC1kZXZpY2VzLWxpc3QnO1xuaW1wb3J0IHsgcGlja0J5IGFzIGZpbHRlclByb3BlcnRpZXMgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHtcbiAgICBoYXNNYXRjaCwgZmluZE1hdGNoLCBpc01hdGNoVHJ1ZSwgZ2V0TW9kZXMsIHNwbGl0RXNjYXBlZCwgZ2V0UGF0aEZyb21QYXJzZWRNb2RlcywgcGFyc2VDb25maWdcbn0gZnJvbSAnLi4vLi4vdXRpbHMvYXJndW1lbnQtcGFyc2luZyc7XG5cblxuY29uc3QgSEVBRExFU1NfREVGQVVMVF9XSURUSCAgPSAxMjgwO1xuY29uc3QgSEVBRExFU1NfREVGQVVMVF9IRUlHSFQgPSA4MDA7XG5cbmNvbnN0IEFWQUlMQUJMRV9NT0RFUyA9IFsndXNlclByb2ZpbGUnLCAnaGVhZGxlc3MnLCAnZW11bGF0aW9uJ107XG5cbmNvbnN0IGNvbmZpZ0NhY2hlID0ge307XG5cbmZ1bmN0aW9uIGhhc0N1c3RvbVByb2ZpbGUgKHVzZXJBcmdzKSB7XG4gICAgcmV0dXJuICEhdXNlckFyZ3MubWF0Y2goLy0tdXNlci1kYXRhLWRpcj0vKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VNb2RlcyAobW9kZXNTdHIsIHVzZXJBcmdzKSB7XG4gICAgY29uc3QgcGFyc2VkICAgICAgICA9IHNwbGl0RXNjYXBlZChtb2Rlc1N0ciwgJzonKTtcbiAgICBjb25zdCBwYXRoICAgICAgICAgID0gZ2V0UGF0aEZyb21QYXJzZWRNb2RlcyhwYXJzZWQsIEFWQUlMQUJMRV9NT0RFUyk7XG4gICAgY29uc3QgZGV0ZWN0ZWRNb2RlcyA9IGdldE1vZGVzKHBhcnNlZCwgQVZBSUxBQkxFX01PREVTKTtcbiAgICBsZXQgb3B0aW9uc1N0cmluZyA9ICcnO1xuXG4gICAgaWYgKHBhcnNlZC5sZW5ndGgpXG4gICAgICAgIG9wdGlvbnNTdHJpbmcgPSBwYXJzZWQuc2hpZnQoKTtcblxuICAgIHdoaWxlIChwYXJzZWQubGVuZ3RoKVxuICAgICAgICBvcHRpb25zU3RyaW5nICs9ICc6JyArIHBhcnNlZC5zaGlmdCgpO1xuXG4gICAgY29uc3QgbW9kZXMgPSB7XG4gICAgICAgIHBhdGg6ICAgICAgICBwYXRoLFxuICAgICAgICB1c2VyUHJvZmlsZTogZGV0ZWN0ZWRNb2Rlcy51c2VyUHJvZmlsZSB8fCBoYXNDdXN0b21Qcm9maWxlKHVzZXJBcmdzKSxcbiAgICAgICAgaGVhZGxlc3M6ICAgIGRldGVjdGVkTW9kZXMuaGVhZGxlc3MsXG4gICAgICAgIGVtdWxhdGlvbjogICBkZXRlY3RlZE1vZGVzLmVtdWxhdGlvbiB8fCBkZXRlY3RlZE1vZGVzLmhlYWRsZXNzXG4gICAgfTtcblxuICAgIHJldHVybiB7IG1vZGVzLCBvcHRpb25zU3RyaW5nIH07XG59XG5cbmZ1bmN0aW9uIHNpbXBsaWZ5RGV2aWNlTmFtZSAoZGV2aWNlTmFtZSkge1xuICAgIHJldHVybiBkZXZpY2VOYW1lLnJlcGxhY2UoL1xccy9nLCAnJykudG9Mb3dlckNhc2UoKTtcbn1cblxuZnVuY3Rpb24gZmluZERldmljZSAoZGV2aWNlTmFtZSkge1xuICAgIGNvbnN0IHNpbXBsZU5hbWUgPSBzaW1wbGlmeURldmljZU5hbWUoZGV2aWNlTmFtZSk7XG5cbiAgICByZXR1cm4gZW11bGF0ZWREZXZpY2VzLmZpbHRlcihkZXZpY2UgPT4gc2ltcGxpZnlEZXZpY2VOYW1lKGRldmljZS50aXRsZSkuaW5kZXhPZihzaW1wbGVOYW1lKSA+PSAwKVswXTtcbn1cblxuZnVuY3Rpb24gZ2V0RGV2aWNlQmFzZWRPcHRpb25zIChkZXZpY2VOYW1lLCBvcmllbnRhdGlvbikge1xuICAgIGlmICghZGV2aWNlTmFtZSlcbiAgICAgICAgcmV0dXJuIHt9O1xuXG4gICAgY29uc3QgZGV2aWNlRGF0YSA9IGZpbmREZXZpY2UoZGV2aWNlTmFtZSk7XG5cbiAgICBpZiAoIWRldmljZURhdGEpXG4gICAgICAgIHJldHVybiB7fTtcblxuICAgIGNvbnN0IG1vYmlsZSA9IGRldmljZURhdGEuY2FwYWJpbGl0aWVzLmluZGV4T2YoJ21vYmlsZScpID49IDA7XG5cbiAgICBpZiAoIW9yaWVudGF0aW9uKVxuICAgICAgICBvcmllbnRhdGlvbiA9IG1vYmlsZSA/ICd2ZXJ0aWNhbCcgOiAnaG9yaXpvbnRhbCc7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBtb2JpbGU6ICAgICAgbW9iaWxlLFxuICAgICAgICBvcmllbnRhdGlvbjogb3JpZW50YXRpb24sXG4gICAgICAgIHRvdWNoOiAgICAgICBkZXZpY2VEYXRhLmNhcGFiaWxpdGllcy5pbmRleE9mKCd0b3VjaCcpID49IDAsXG4gICAgICAgIHdpZHRoOiAgICAgICBkZXZpY2VEYXRhLnNjcmVlbltvcmllbnRhdGlvbl0ud2lkdGgsXG4gICAgICAgIGhlaWdodDogICAgICBkZXZpY2VEYXRhLnNjcmVlbltvcmllbnRhdGlvbl0uaGVpZ2h0LFxuICAgICAgICBzY2FsZUZhY3RvcjogZGV2aWNlRGF0YS5zY3JlZW5bJ2RldmljZS1waXhlbC1yYXRpbyddLFxuICAgICAgICB1c2VyQWdlbnQ6ICAgZGV2aWNlRGF0YVsndXNlci1hZ2VudCddLFxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHBhcnNlT3B0aW9ucyAoc3RyLCBtb2Rlcykge1xuICAgIGNvbnN0IHBhcnNlZCA9IHNwbGl0RXNjYXBlZChzdHIsICc7Jyk7XG5cbiAgICBjb25zdCBiYXNlT3B0aW9ucyA9IHtcbiAgICAgICAgd2lkdGg6ICAgICAgIG1vZGVzLmhlYWRsZXNzID8gSEVBRExFU1NfREVGQVVMVF9XSURUSCA6IDAsXG4gICAgICAgIGhlaWdodDogICAgICBtb2Rlcy5oZWFkbGVzcyA/IEhFQURMRVNTX0RFRkFVTFRfSEVJR0hUIDogMCxcbiAgICAgICAgc2NhbGVGYWN0b3I6IDAsXG4gICAgICAgIG1vYmlsZTogICAgICBmYWxzZSxcbiAgICAgICAgY2RwUG9ydDogICAgIGZpbmRNYXRjaChwYXJzZWQsIC9eY2RwUG9ydD0oLiopLylcbiAgICB9O1xuXG4gICAgY29uc3QgZGV2aWNlTmFtZSAgICAgICAgID0gZmluZE1hdGNoKHBhcnNlZCwgL15kZXZpY2U9KC4qKS8pO1xuICAgIGNvbnN0IG9yaWVudGF0aW9uICAgICAgICA9IGZpbmRNYXRjaChwYXJzZWQsIC9eb3JpZW50YXRpb249KC4qKS8pO1xuICAgIGNvbnN0IGRldmljZUJhc2VkT3B0aW9ucyA9IGdldERldmljZUJhc2VkT3B0aW9ucyhkZXZpY2VOYW1lLCBvcmllbnRhdGlvbik7XG5cbiAgICBsZXQgc3BlY2lmaWVkRGV2aWNlT3B0aW9ucyA9IHtcbiAgICAgICAgb3JpZW50YXRpb246IG9yaWVudGF0aW9uLFxuICAgICAgICB0b3VjaDogICAgICAgaGFzTWF0Y2gocGFyc2VkLCAvXnRvdWNoPS8pID8gaXNNYXRjaFRydWUocGFyc2VkLCAvXnRvdWNoPSguKikvKSA6IHZvaWQgMCxcbiAgICAgICAgbW9iaWxlOiAgICAgIGlzTWF0Y2hUcnVlKHBhcnNlZCwgL15tb2JpbGU9KC4qKS8pLFxuICAgICAgICB3aWR0aDogICAgICAgTnVtYmVyKGZpbmRNYXRjaChwYXJzZWQsIC9ed2lkdGg9KC4qKS8pIHx8IE5hTiksXG4gICAgICAgIGhlaWdodDogICAgICBOdW1iZXIoZmluZE1hdGNoKHBhcnNlZCwgL15oZWlnaHQ9KC4qKS8pIHx8IE5hTiksXG4gICAgICAgIHNjYWxlRmFjdG9yOiBOdW1iZXIoZmluZE1hdGNoKHBhcnNlZCwgL15zY2FsZUZhY3Rvcj0oLiopLykgfHwgTmFOKSxcbiAgICAgICAgdXNlckFnZW50OiAgIGZpbmRNYXRjaChwYXJzZWQsIC9edXNlckFnZW50PSguKikvKVxuICAgIH07XG5cbiAgICBzcGVjaWZpZWREZXZpY2VPcHRpb25zID0gZmlsdGVyUHJvcGVydGllcyhzcGVjaWZpZWREZXZpY2VPcHRpb25zLCBvcHRpb25WYWx1ZSA9PiB7XG4gICAgICAgIHJldHVybiBvcHRpb25WYWx1ZSAhPT0gdm9pZCAwICYmIG9wdGlvblZhbHVlICE9PSAnJyAmJiAhTnVtYmVyLmlzTmFOKG9wdGlvblZhbHVlKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKGJhc2VPcHRpb25zLCBkZXZpY2VCYXNlZE9wdGlvbnMsIHNwZWNpZmllZERldmljZU9wdGlvbnMpO1xufVxuXG5cbmZ1bmN0aW9uIGdldE5ld0NvbmZpZyAoY29uZmlnU3RyaW5nKSB7XG4gICAgY29uc3QgeyB1c2VyQXJncywgbW9kZXNTdHJpbmcgfSA9IHBhcnNlQ29uZmlnKGNvbmZpZ1N0cmluZyk7XG4gICAgY29uc3QgeyBtb2Rlcywgb3B0aW9uc1N0cmluZyB9ICA9IHBhcnNlTW9kZXMobW9kZXNTdHJpbmcsIHVzZXJBcmdzKTtcbiAgICBjb25zdCBvcHRpb25zICAgICAgICAgICAgICAgICAgID0gcGFyc2VPcHRpb25zKG9wdGlvbnNTdHJpbmcsIG1vZGVzKTtcblxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHsgdXNlckFyZ3MgfSwgbW9kZXMsIG9wdGlvbnMpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoY29uZmlnU3RyaW5nKSB7XG4gICAgaWYgKCFjb25maWdDYWNoZVtjb25maWdTdHJpbmddKVxuICAgICAgICBjb25maWdDYWNoZVtjb25maWdTdHJpbmddID0gZ2V0TmV3Q29uZmlnKGNvbmZpZ1N0cmluZyk7XG5cbiAgICByZXR1cm4gY29uZmlnQ2FjaGVbY29uZmlnU3RyaW5nXTtcbn1cbiJdfQ== diff --git a/lib/browser/provider/built-in/chrome/create-temp-profile.js b/lib/browser/provider/built-in/chrome/create-temp-profile.js new file mode 100644 index 00000000..129a74f7 --- /dev/null +++ b/lib/browser/provider/built-in/chrome/create-temp-profile.js @@ -0,0 +1,75 @@ +'use strict'; + +exports.__esModule = true; + +var _stringify = require('babel-runtime/core-js/json/stringify'); + +var _stringify2 = _interopRequireDefault(_stringify); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _path = require('path'); + +var _path2 = _interopRequireDefault(_path); + +var _makeDir = require('make-dir'); + +var _makeDir2 = _interopRequireDefault(_makeDir); + +var _tempDirectory = require('../../../../utils/temp-directory'); + +var _tempDirectory2 = _interopRequireDefault(_tempDirectory); + +var _promisifiedFunctions = require('../../../../utils/promisified-functions'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (proxyHostName) { + const tempDir = yield _tempDirectory2.default.createDirectory('chrome-profile'); + const profileDirName = _path2.default.join(tempDir.path, 'Default'); + + yield (0, _makeDir2.default)(profileDirName); + + const preferences = { + 'credentials_enable_service': false, + + 'devtools': { + 'preferences': { + 'currentDockState': '"undocked"', + 'lastDockState': '"bottom"' + } + }, + + 'profile': { + 'content_settings': { + 'exceptions': { + 'automatic_downloads': { + [proxyHostName]: { setting: 1 } + } + } + }, + + 'password_manager_enabled': false + }, + + 'translate': { + 'enabled': false + } + }; + + yield (0, _promisifiedFunctions.writeFile)(_path2.default.join(profileDirName, 'Preferences'), (0, _stringify2.default)(preferences)); + yield (0, _promisifiedFunctions.writeFile)(_path2.default.join(tempDir.path, 'First Run'), ''); + + return tempDir; + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; +})(); + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2Nocm9tZS9jcmVhdGUtdGVtcC1wcm9maWxlLmpzIl0sIm5hbWVzIjpbInByb3h5SG9zdE5hbWUiLCJ0ZW1wRGlyIiwiVGVtcERpcmVjdG9yeSIsImNyZWF0ZURpcmVjdG9yeSIsInByb2ZpbGVEaXJOYW1lIiwicGF0aCIsImpvaW4iLCJwcmVmZXJlbmNlcyIsInNldHRpbmciXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7OzsrQ0FHZSxXQUFnQkEsYUFBaEIsRUFBK0I7QUFDMUMsY0FBTUMsVUFBaUIsTUFBTUMsd0JBQWNDLGVBQWQsQ0FBOEIsZ0JBQTlCLENBQTdCO0FBQ0EsY0FBTUMsaUJBQWlCQyxlQUFLQyxJQUFMLENBQVVMLFFBQVFJLElBQWxCLEVBQXdCLFNBQXhCLENBQXZCOztBQUVBLGNBQU0sdUJBQVFELGNBQVIsQ0FBTjs7QUFFQSxjQUFNRyxjQUFjO0FBQ2hCLDBDQUE4QixLQURkOztBQUdoQix3QkFBWTtBQUNSLCtCQUFlO0FBQ1gsd0NBQW9CLFlBRFQ7QUFFWCxxQ0FBb0I7QUFGVDtBQURQLGFBSEk7O0FBVWhCLHVCQUFXO0FBQ1Asb0NBQW9CO0FBQ2hCLGtDQUFjO0FBQ1YsK0NBQXVCO0FBQ25CLDZCQUFDUCxhQUFELEdBQWlCLEVBQUVRLFNBQVMsQ0FBWDtBQURFO0FBRGI7QUFERSxpQkFEYjs7QUFTUCw0Q0FBNEI7QUFUckIsYUFWSzs7QUFzQmhCLHlCQUFhO0FBQ1QsMkJBQVc7QUFERjtBQXRCRyxTQUFwQjs7QUEyQkEsY0FBTSxxQ0FBVUgsZUFBS0MsSUFBTCxDQUFVRixjQUFWLEVBQTBCLGFBQTFCLENBQVYsRUFBb0QseUJBQWVHLFdBQWYsQ0FBcEQsQ0FBTjtBQUNBLGNBQU0scUNBQVVGLGVBQUtDLElBQUwsQ0FBVUwsUUFBUUksSUFBbEIsRUFBd0IsV0FBeEIsQ0FBVixFQUFnRCxFQUFoRCxDQUFOOztBQUVBLGVBQU9KLE9BQVA7QUFDSCxLIiwiZmlsZSI6ImJyb3dzZXIvcHJvdmlkZXIvYnVpbHQtaW4vY2hyb21lL2NyZWF0ZS10ZW1wLXByb2ZpbGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBtYWtlRGlyIGZyb20gJ21ha2UtZGlyJztcbmltcG9ydCBUZW1wRGlyZWN0b3J5IGZyb20gJy4uLy4uLy4uLy4uL3V0aWxzL3RlbXAtZGlyZWN0b3J5JztcbmltcG9ydCB7IHdyaXRlRmlsZSB9IGZyb20gJy4uLy4uLy4uLy4uL3V0aWxzL3Byb21pc2lmaWVkLWZ1bmN0aW9ucyc7XG5cblxuZXhwb3J0IGRlZmF1bHQgYXN5bmMgZnVuY3Rpb24gKHByb3h5SG9zdE5hbWUpIHtcbiAgICBjb25zdCB0ZW1wRGlyICAgICAgICA9IGF3YWl0IFRlbXBEaXJlY3RvcnkuY3JlYXRlRGlyZWN0b3J5KCdjaHJvbWUtcHJvZmlsZScpO1xuICAgIGNvbnN0IHByb2ZpbGVEaXJOYW1lID0gcGF0aC5qb2luKHRlbXBEaXIucGF0aCwgJ0RlZmF1bHQnKTtcblxuICAgIGF3YWl0IG1ha2VEaXIocHJvZmlsZURpck5hbWUpO1xuXG4gICAgY29uc3QgcHJlZmVyZW5jZXMgPSB7XG4gICAgICAgICdjcmVkZW50aWFsc19lbmFibGVfc2VydmljZSc6IGZhbHNlLFxuXG4gICAgICAgICdkZXZ0b29scyc6IHtcbiAgICAgICAgICAgICdwcmVmZXJlbmNlcyc6IHtcbiAgICAgICAgICAgICAgICAnY3VycmVudERvY2tTdGF0ZSc6ICdcInVuZG9ja2VkXCInLFxuICAgICAgICAgICAgICAgICdsYXN0RG9ja1N0YXRlJzogICAgJ1wiYm90dG9tXCInXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgJ3Byb2ZpbGUnOiB7XG4gICAgICAgICAgICAnY29udGVudF9zZXR0aW5ncyc6IHtcbiAgICAgICAgICAgICAgICAnZXhjZXB0aW9ucyc6IHtcbiAgICAgICAgICAgICAgICAgICAgJ2F1dG9tYXRpY19kb3dubG9hZHMnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBbcHJveHlIb3N0TmFtZV06IHsgc2V0dGluZzogMSB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAncGFzc3dvcmRfbWFuYWdlcl9lbmFibGVkJzogZmFsc2VcbiAgICAgICAgfSxcblxuICAgICAgICAndHJhbnNsYXRlJzoge1xuICAgICAgICAgICAgJ2VuYWJsZWQnOiBmYWxzZVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIGF3YWl0IHdyaXRlRmlsZShwYXRoLmpvaW4ocHJvZmlsZURpck5hbWUsICdQcmVmZXJlbmNlcycpLCBKU09OLnN0cmluZ2lmeShwcmVmZXJlbmNlcykpO1xuICAgIGF3YWl0IHdyaXRlRmlsZShwYXRoLmpvaW4odGVtcERpci5wYXRoLCAnRmlyc3QgUnVuJyksICcnKTtcblxuICAgIHJldHVybiB0ZW1wRGlyO1xufVxuIl19 diff --git a/lib/browser/provider/built-in/chrome/index.js b/lib/browser/provider/built-in/chrome/index.js new file mode 100644 index 00000000..0c8995b1 --- /dev/null +++ b/lib/browser/provider/built-in/chrome/index.js @@ -0,0 +1,150 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _osFamily = require('os-family'); + +var _osFamily2 = _interopRequireDefault(_osFamily); + +var _url = require('url'); + +var _runtimeInfo = require('./runtime-info'); + +var _runtimeInfo2 = _interopRequireDefault(_runtimeInfo); + +var _localChrome = require('./local-chrome'); + +var _cdp = require('./cdp'); + +var cdp = _interopRequireWildcard(_cdp); + +var _getMaximizedHeadlessWindowSize = require('../../utils/get-maximized-headless-window-size'); + +var _getMaximizedHeadlessWindowSize2 = _interopRequireDefault(_getMaximizedHeadlessWindowSize); + +var _clientFunctions = require('../../utils/client-functions'); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + openedBrowsers: {}, + + isMultiBrowser: false, + + openBrowser(browserId, pageUrl, configString) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + const runtimeInfo = yield (0, _runtimeInfo2.default)((0, _url.parse)(pageUrl).hostname, configString); + const browserName = _this.providerName.replace(':', ''); + + runtimeInfo.browserId = browserId; + runtimeInfo.browserName = browserName; + + runtimeInfo.providerMethods = { + resizeLocalBrowserWindow: function resizeLocalBrowserWindow(...args) { + return _this.resizeLocalBrowserWindow(...args); + } + }; + + yield (0, _localChrome.start)(pageUrl, runtimeInfo); + + yield _this.waitForConnectionReady(browserId); + + runtimeInfo.viewportSize = yield _this.runInitScript(browserId, _clientFunctions.GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + + yield cdp.createClient(runtimeInfo); + + _this.openedBrowsers[browserId] = runtimeInfo; + })(); + }, + + closeBrowser(browserId) { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const runtimeInfo = _this2.openedBrowsers[browserId]; + + if (cdp.isHeadlessTab(runtimeInfo)) yield cdp.closeTab(runtimeInfo);else yield _this2.closeLocalBrowser(browserId); + + if (_osFamily2.default.mac || runtimeInfo.config.headless) yield (0, _localChrome.stop)(runtimeInfo); + + if (runtimeInfo.tempProfileDir) yield runtimeInfo.tempProfileDir.dispose(); + + delete _this2.openedBrowsers[browserId]; + })(); + }, + + isLocalBrowser() { + return (0, _asyncToGenerator3.default)(function* () { + return true; + })(); + }, + + isHeadlessBrowser(browserId) { + return this.openedBrowsers[browserId].config.headless; + }, + + takeScreenshot(browserId, path) { + var _this3 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const runtimeInfo = _this3.openedBrowsers[browserId]; + + yield cdp.takeScreenshot(path, runtimeInfo); + })(); + }, + + resizeWindow(browserId, width, height, currentWidth, currentHeight) { + var _this4 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const runtimeInfo = _this4.openedBrowsers[browserId]; + + if (runtimeInfo.config.mobile) yield cdp.updateMobileViewportSize(runtimeInfo);else { + runtimeInfo.viewportSize.width = currentWidth; + runtimeInfo.viewportSize.height = currentHeight; + } + + yield cdp.resizeWindow({ width, height }, runtimeInfo); + })(); + }, + + maximizeWindow(browserId) { + var _this5 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const maximumSize = (0, _getMaximizedHeadlessWindowSize2.default)(); + + yield _this5.resizeWindow(browserId, maximumSize.width, maximumSize.height, maximumSize.width, maximumSize.height); + })(); + }, + + hasCustomActionForBrowser(browserId) { + var _this6 = this; + + return (0, _asyncToGenerator3.default)(function* () { + var _openedBrowsers$brows = _this6.openedBrowsers[browserId]; + const config = _openedBrowsers$brows.config, + client = _openedBrowsers$brows.client; + + + return { + hasCloseBrowser: true, + hasResizeWindow: !!client && (config.emulation || config.headless), + hasMaximizeWindow: !!client && config.headless, + hasTakeScreenshot: !!client, + hasChromelessScreenshots: !!client, + hasCanResizeWindowToDimensions: false + }; + })(); + } +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2Nocm9tZS9pbmRleC5qcyJdLCJuYW1lcyI6WyJjZHAiLCJvcGVuZWRCcm93c2VycyIsImlzTXVsdGlCcm93c2VyIiwib3BlbkJyb3dzZXIiLCJicm93c2VySWQiLCJwYWdlVXJsIiwiY29uZmlnU3RyaW5nIiwicnVudGltZUluZm8iLCJob3N0bmFtZSIsImJyb3dzZXJOYW1lIiwicHJvdmlkZXJOYW1lIiwicmVwbGFjZSIsInByb3ZpZGVyTWV0aG9kcyIsInJlc2l6ZUxvY2FsQnJvd3NlcldpbmRvdyIsImFyZ3MiLCJ3YWl0Rm9yQ29ubmVjdGlvblJlYWR5Iiwidmlld3BvcnRTaXplIiwicnVuSW5pdFNjcmlwdCIsIkdFVF9XSU5ET1dfRElNRU5TSU9OU19JTkZPX1NDUklQVCIsImNyZWF0ZUNsaWVudCIsImNsb3NlQnJvd3NlciIsImlzSGVhZGxlc3NUYWIiLCJjbG9zZVRhYiIsImNsb3NlTG9jYWxCcm93c2VyIiwiT1MiLCJtYWMiLCJjb25maWciLCJoZWFkbGVzcyIsInRlbXBQcm9maWxlRGlyIiwiZGlzcG9zZSIsImlzTG9jYWxCcm93c2VyIiwiaXNIZWFkbGVzc0Jyb3dzZXIiLCJ0YWtlU2NyZWVuc2hvdCIsInBhdGgiLCJyZXNpemVXaW5kb3ciLCJ3aWR0aCIsImhlaWdodCIsImN1cnJlbnRXaWR0aCIsImN1cnJlbnRIZWlnaHQiLCJtb2JpbGUiLCJ1cGRhdGVNb2JpbGVWaWV3cG9ydFNpemUiLCJtYXhpbWl6ZVdpbmRvdyIsIm1heGltdW1TaXplIiwiaGFzQ3VzdG9tQWN0aW9uRm9yQnJvd3NlciIsImNsaWVudCIsImhhc0Nsb3NlQnJvd3NlciIsImhhc1Jlc2l6ZVdpbmRvdyIsImVtdWxhdGlvbiIsImhhc01heGltaXplV2luZG93IiwiaGFzVGFrZVNjcmVlbnNob3QiLCJoYXNDaHJvbWVsZXNzU2NyZWVuc2hvdHMiLCJoYXNDYW5SZXNpemVXaW5kb3dUb0RpbWVu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IjpbImltcG9ydCBPUyBmcm9tICdvcy1mYW1pbHknO1xuaW1wb3J0IHsgcGFyc2UgYXMgcGFyc2VVcmwgfSBmcm9tICd1cmwnO1xuaW1wb3J0IGdldFJ1bnRpbWVJbmZvIGZyb20gJy4vcnVudGltZS1pbmZvJztcbmltcG9ydCB7IHN0YXJ0IGFzIHN0YXJ0TG9jYWxDaHJvbWUsIHN0b3AgYXMgc3RvcExvY2FsQ2hyb21lIH0gZnJvbSAnLi9sb2NhbC1jaHJvbWUnO1xuaW1wb3J0ICogYXMgY2RwIGZyb20gJy4vY2RwJztcbmltcG9ydCBnZXRNYXhpbWl6ZWRIZWFkbGVzc1dpbmRvd1NpemUgZnJvbSAnLi4vLi4vdXRpbHMvZ2V0LW1heGltaXplZC1oZWFkbGVzcy13aW5kb3ctc2l6ZSc7XG5pbXBvcnQgeyBHRVRfV0lORE9XX0RJTUVOU0lPTlNfSU5GT19TQ1JJUFQgfSBmcm9tICcuLi8uLi91dGlscy9jbGllbnQtZnVuY3Rpb25zJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgb3BlbmVkQnJvd3NlcnM6IHt9LFxuXG4gICAgaXNNdWx0aUJyb3dzZXI6IGZhbHNlLFxuXG4gICAgYXN5bmMgb3BlbkJyb3dzZXIgKGJyb3dzZXJJZCwgcGFnZVVybCwgY29uZmlnU3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVJbmZvID0gYXdhaXQgZ2V0UnVudGltZUluZm8ocGFyc2VVcmwocGFnZVVybCkuaG9zdG5hbWUsIGNvbmZpZ1N0cmluZyk7XG4gICAgICAgIGNvbnN0IGJyb3dzZXJOYW1lID0gdGhpcy5wcm92aWRlck5hbWUucmVwbGFjZSgnOicsICcnKTtcblxuICAgICAgICBydW50aW1lSW5mby5icm93c2VySWQgICA9IGJyb3dzZXJJZDtcbiAgICAgICAgcnVudGltZUluZm8uYnJvd3Nlck5hbWUgPSBicm93c2VyTmFtZTtcblxuICAgICAgICBydW50aW1lSW5mby5wcm92aWRlck1ldGhvZHMgPSB7XG4gICAgICAgICAgICByZXNpemVMb2NhbEJyb3dzZXJXaW5kb3c6ICguLi5hcmdzKSA9PiB0aGlzLnJlc2l6ZUxvY2FsQnJvd3NlcldpbmRvdyguLi5hcmdzKVxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IHN0YXJ0TG9jYWxDaHJvbWUocGFnZVVybCwgcnVudGltZUluZm8pO1xuXG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvckNvbm5lY3Rpb25SZWFkeShicm93c2VySWQpO1xuXG4gICAgICAgIHJ1bnRpbWVJbmZvLnZpZXdwb3J0U2l6ZSA9IGF3YWl0IHRoaXMucnVuSW5pdFNjcmlwdChicm93c2VySWQsIEdFVF9XSU5ET1dfRElNRU5TSU9OU19JTkZPX1NDUklQVCk7XG5cbiAgICAgICAgYXdhaXQgY2RwLmNyZWF0ZUNsaWVudChydW50aW1lSW5mbyk7XG5cbiAgICAgICAgdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdID0gcnVudGltZUluZm87XG4gICAgfSxcblxuICAgIGFzeW5jIGNsb3NlQnJvd3NlciAoYnJvd3NlcklkKSB7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVJbmZvID0gdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdO1xuXG4gICAgICAgIGlmIChjZHAuaXNIZWFkbGVzc1RhYihydW50aW1lSW5mbykpXG4gICAgICAgICAgICBhd2FpdCBjZHAuY2xvc2VUYWIocnVudGltZUluZm8pO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNsb3NlTG9jYWxCcm93c2VyKGJyb3dzZXJJZCk7XG5cbiAgICAgICAgaWYgKE9TLm1hYyB8fCBydW50aW1lSW5mby5jb25maWcuaGVhZGxlc3MpXG4gICAgICAgICAgICBhd2FpdCBzdG9wTG9jYWxDaHJvbWUocnVudGltZUluZm8pO1xuXG4gICAgICAgIGlmIChydW50aW1lSW5mby50ZW1wUHJvZmlsZURpcilcbiAgICAgICAgICAgIGF3YWl0IHJ1bnRpbWVJbmZvLnRlbXBQcm9maWxlRGlyLmRpc3Bvc2UoKTtcblxuICAgICAgICBkZWxldGUgdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdO1xuICAgIH0sXG5cbiAgICBhc3luYyBpc0xvY2FsQnJvd3NlciAoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICBpc0hlYWRsZXNzQnJvd3NlciAoYnJvd3NlcklkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZW5lZEJyb3dzZXJzW2Jyb3dzZXJJZF0uY29uZmlnLmhlYWRsZXNzO1xuICAgIH0sXG5cbiAgICBhc3luYyB0YWtlU2NyZWVuc2hvdCAoYnJvd3NlcklkLCBwYXRoKSB7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVJbmZvID0gdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdO1xuXG4gICAgICAgIGF3YWl0IGNkcC50YWtlU2NyZWVuc2hvdChwYXRoLCBydW50aW1lSW5mbyk7XG4gICAgfSxcblxuICAgIGFzeW5jIHJlc2l6ZVdpbmRvdyAoYnJvd3NlcklkLCB3aWR0aCwgaGVpZ2h0LCBjdXJyZW50V2lkdGgsIGN1cnJlbnRIZWlnaHQpIHtcbiAgICAgICAgY29uc3QgcnVudGltZUluZm8gPSB0aGlzLm9wZW5lZEJyb3dzZXJzW2Jyb3dzZXJJZF07XG5cbiAgICAgICAgaWYgKHJ1bnRpbWVJbmZvLmNvbmZpZy5tb2JpbGUpXG4gICAgICAgICAgICBhd2FpdCBjZHAudXBkYXRlTW9iaWxlVmlld3BvcnRTaXplKHJ1bnRpbWVJbmZvKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBydW50aW1lSW5mby52aWV3cG9ydFNpemUud2lkdGggID0gY3VycmVudFdpZHRoO1xuICAgICAgICAgICAgcnVudGltZUluZm8udmlld3BvcnRTaXplLmhlaWdodCA9IGN1cnJlbnRIZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCBjZHAucmVzaXplV2luZG93KHsgd2lkdGgsIGhlaWdodCB9LCBydW50aW1lSW5mbyk7XG4gICAgfSxcblxuICAgIGFzeW5jIG1heGltaXplV2luZG93IChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgbWF4aW11bVNpemUgPSBnZXRNYXhpbWl6ZWRIZWFkbGVzc1dpbmRvd1NpemUoKTtcblxuICAgICAgICBhd2FpdCB0aGlzLnJlc2l6ZVdpbmRvdyhicm93c2VySWQsIG1heGltdW1TaXplLndpZHRoLCBtYXhpbXVtU2l6ZS5oZWlnaHQsIG1heGltdW1TaXplLndpZHRoLCBtYXhpbXVtU2l6ZS5oZWlnaHQpO1xuICAgIH0sXG5cbiAgICBhc3luYyBoYXNDdXN0b21BY3Rpb25Gb3JCcm93c2VyIChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgeyBjb25maWcsIGNsaWVudCB9ID0gdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoYXNDbG9zZUJyb3dzZXI6ICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBoYXNSZXNpemVXaW5kb3c6ICAgICAgICAgICAgICAgICEhY2xpZW50ICYmIChjb25maWcuZW11bGF0aW9uIHx8IGNvbmZpZy5oZWFkbGVzcyksXG4gICAgICAgICAgICBoYXNNYXhpbWl6ZVdpbmRvdzogICAgICAgICAgICAgICEhY2xpZW50ICYmIGNvbmZpZy5oZWFkbGVzcyxcbiAgICAgICAgICAgIGhhc1Rha2VTY3JlZW5zaG90OiAgICAgICAgICAgICAgISFjbGllbnQsXG4gICAgICAgICAgICBoYXNDaHJvbWVsZXNzU2NyZWVuc2hvdHM6ICAgICAgICEhY2xpZW50LFxuICAgICAgICAgICAgaGFzQ2FuUmVzaXplV2luZG93VG9EaW1lbnNpb25zOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH1cbn07XG4iXX0= diff --git a/lib/browser/provider/built-in/chrome/local-chrome.js b/lib/browser/provider/built-in/chrome/local-chrome.js new file mode 100644 index 00000000..6d9cc2ab --- /dev/null +++ b/lib/browser/provider/built-in/chrome/local-chrome.js @@ -0,0 +1,57 @@ +'use strict'; + +exports.__esModule = true; +exports.stop = exports.start = undefined; + +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +let start = exports.start = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (pageUrl, { browserName, config, cdpPort, tempProfileDir }) { + const chromeInfo = yield _testcafeBrowserTools2.default.getBrowserInfo(config.path || browserName); + const chromeOpenParameters = (0, _assign2.default)({}, chromeInfo); + + chromeOpenParameters.cmd = buildChromeArgs(config, cdpPort, chromeOpenParameters.cmd, tempProfileDir); + + yield browserStarter.startBrowser(chromeOpenParameters, pageUrl); + }); + + return function start(_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); + +let stop = exports.stop = (() => { + var _ref2 = (0, _asyncToGenerator3.default)(function* ({ browserId }) { + // NOTE: Chrome on Linux closes only after the second SIGTERM signall + if (!(yield (0, _process.killBrowserProcess)(browserId))) yield (0, _process.killBrowserProcess)(browserId); + }); + + return function stop(_x3) { + return _ref2.apply(this, arguments); + }; +})(); + +var _testcafeBrowserTools = require('testcafe-browser-tools'); + +var _testcafeBrowserTools2 = _interopRequireDefault(_testcafeBrowserTools); + +var _process = require('../../../../utils/process'); + +var _browserStarter = require('../../utils/browser-starter'); + +var _browserStarter2 = _interopRequireDefault(_browserStarter); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const browserStarter = new _browserStarter2.default(); + +function buildChromeArgs(config, cdpPort, platformArgs, profileDir) { + return [].concat(cdpPort ? [`--remote-debugging-port=${cdpPort}`] : [], !config.userProfile ? [`--user-data-dir=${profileDir.path}`] : [], config.headless ? ['--headless'] : [], config.userArgs ? [config.userArgs] : [], platformArgs ? [platformArgs] : []).join(' '); +} +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2Nocm9tZS9sb2NhbC1jaHJvbWUuanMiXSwibmFtZXMiOlsicGFnZVVybCIsImJyb3dzZXJOYW1lIiwiY29uZmlnIiwiY2RwUG9ydCIsInRlbXBQcm9maWxlRGlyIiwiY2hyb21lSW5mbyIsImJyb3dzZXJUb29scyIsImdldEJyb3dzZXJJbmZvIiwicGF0aCIsImNocm9tZU9wZW5QYXJhbWV0ZXJzIiwiY21kIiwiYnVpbGRDaHJvbWVBcmdzIiwiYnJvd3NlclN0YXJ0ZXIiLCJzdGFydEJyb3dzZXIiLCJzdGFydCIsImJyb3dzZXJJZCIsInN0b3AiLCJCcm93c2VyU3RhcnRlciIsInBsYXRmb3JtQXJncyIsInByb2ZpbGVEaXIiLCJjb25jYXQiLCJ1c2VyUHJvZmlsZSIsImhlYWRsZXNzIiwidXNlckFyZ3MiLCJqb2luIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OzsrQ0FtQk8sV0FBc0JBLE9BQXRCLEVBQStCLEVBQUVDLFdBQUYsRUFBZUMsTUFBZixFQUF1QkMsT0FBdkIsRUFBZ0NDLGNBQWhDLEVBQS9CLEVBQWlGO0FBQ3BGLGNBQU1DLGFBQXVCLE1BQU1DLCtCQUFhQyxjQUFiLENBQTRCTCxPQUFPTSxJQUFQLElBQWVQLFdBQTNDLENBQW5DO0FBQ0EsY0FBTVEsdUJBQXVCLHNCQUFjLEVBQWQsRUFBa0JKLFVBQWxCLENBQTdCOztBQUVBSSw2QkFBcUJDLEdBQXJCLEdBQTJCQyxnQkFBZ0JULE1BQWhCLEVBQXdCQyxPQUF4QixFQUFpQ00scUJBQXFCQyxHQUF0RCxFQUEyRE4sY0FBM0QsQ0FBM0I7O0FBRUEsY0FBTVEsZUFBZUMsWUFBZixDQUE0Qkosb0JBQTVCLEVBQWtEVCxPQUFsRCxDQUFOO0FBQ0gsSzs7b0JBUHFCYyxLOzs7Ozs7Z0RBU2YsV0FBcUIsRUFBRUMsU0FBRixFQUFyQixFQUFvQztBQUN2QztBQUNBLFlBQUksRUFBQyxNQUFNLGlDQUFtQkEsU0FBbkIsQ0FBUCxDQUFKLEVBQ0ksTUFBTSxpQ0FBbUJBLFNBQW5CLENBQU47QUFDUCxLOztvQkFKcUJDLEk7Ozs7O0FBNUJ0Qjs7OztBQUNBOztBQUNBOzs7Ozs7QUFHQSxNQUFNSixpQkFBaUIsSUFBSUssd0JBQUosRUFBdkI7O0FBRUEsU0FBU04sZUFBVCxDQUEwQlQsTUFBMUIsRUFBa0NDLE9BQWxDLEVBQTJDZSxZQUEzQyxFQUF5REMsVUFBekQsRUFBcUU7QUFDakUsV0FBTyxHQUNGQyxNQURFLENBRUNqQixVQUFVLENBQUUsMkJBQTBCQSxPQUFRLEVBQXBDLENBQVYsR0FBbUQsRUFGcEQsRUFHQyxDQUFDRCxPQUFPbUIsV0FBUixHQUFzQixDQUFFLG1CQUFrQkYsV0FBV1gsSUFBSyxFQUFwQyxDQUF0QixHQUErRCxFQUhoRSxFQUlDTixPQUFPb0IsUUFBUCxHQUFrQixDQUFDLFlBQUQsQ0FBbEIsR0FBbUMsRUFKcEMsRUFLQ3BCLE9BQU9xQixRQUFQLEdBQWtCLENBQUNyQixPQUFPcUIsUUFBUixDQUFsQixHQUFzQyxFQUx2QyxFQU1DTCxlQUFlLENBQUNBLFlBQUQsQ0FBZixHQUFnQyxFQU5qQyxFQVFGTSxJQVJFLENBUUcsR0FSSCxDQUFQO0FBU0giLCJmaWxlIjoiYnJvd3Nlci9wcm92aWRlci9idWlsdC1pbi9jaHJvbWUvbG9jYWwtY2hyb21lLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGJyb3dzZXJUb29scyBmcm9tICd0ZXN0Y2FmZS1icm93c2VyLXRvb2xzJztcbmltcG9ydCB7IGtpbGxCcm93c2VyUHJvY2VzcyB9IGZyb20gJy4uLy4uLy4uLy4uL3V0aWxzL3Byb2Nlc3MnO1xuaW1wb3J0IEJyb3dzZXJTdGFydGVyIGZyb20gJy4uLy4uL3V0aWxzL2Jyb3dzZXItc3RhcnRlcic7XG5cblxuY29uc3QgYnJvd3NlclN0YXJ0ZXIgPSBuZXcgQnJvd3NlclN0YXJ0ZXIoKTtcblxuZnVuY3Rpb24gYnVpbGRDaHJvbWVBcmdzIChjb25maWcsIGNkcFBvcnQsIHBsYXRmb3JtQXJncywgcHJvZmlsZURpcikge1xuICAgIHJldHVybiBbXVxuICAgICAgICAuY29uY2F0KFxuICAgICAgICAgICAgY2RwUG9ydCA/IFtgLS1yZW1vdGUtZGVidWdnaW5nLXBvcnQ9JHtjZHBQb3J0fWBdIDogW10sXG4gICAgICAgICAgICAhY29uZmlnLnVzZXJQcm9maWxlID8gW2AtLXVzZXItZGF0YS1kaXI9JHtwcm9maWxlRGlyLnBhdGh9YF0gOiBbXSxcbiAgICAgICAgICAgIGNvbmZpZy5oZWFkbGVzcyA/IFsnLS1oZWFkbGVzcyddIDogW10sXG4gICAgICAgICAgICBjb25maWcudXNlckFyZ3MgPyBbY29uZmlnLnVzZXJBcmdzXSA6IFtdLFxuICAgICAgICAgICAgcGxhdGZvcm1BcmdzID8gW3BsYXRmb3JtQXJnc10gOiBbXVxuICAgICAgICApXG4gICAgICAgIC5qb2luKCcgJyk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFydCAocGFnZVVybCwgeyBicm93c2VyTmFtZSwgY29uZmlnLCBjZHBQb3J0LCB0ZW1wUHJvZmlsZURpciB9KSB7XG4gICAgY29uc3QgY2hyb21lSW5mbyAgICAgICAgICAgPSBhd2FpdCBicm93c2VyVG9vbHMuZ2V0QnJvd3NlckluZm8oY29uZmlnLnBhdGggfHwgYnJvd3Nlck5hbWUpO1xuICAgIGNvbnN0IGNocm9tZU9wZW5QYXJhbWV0ZXJzID0gT2JqZWN0LmFzc2lnbih7fSwgY2hyb21lSW5mbyk7XG5cbiAgICBjaHJvbWVPcGVuUGFyYW1ldGVycy5jbWQgPSBidWlsZENocm9tZUFyZ3MoY29uZmlnLCBjZHBQb3J0LCBjaHJvbWVPcGVuUGFyYW1ldGVycy5jbWQsIHRlbXBQcm9maWxlRGlyKTtcblxuICAgIGF3YWl0IGJyb3dzZXJTdGFydGVyLnN0YXJ0QnJvd3NlcihjaHJvbWVPcGVuUGFyYW1ldGVycywgcGFnZVVybCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdG9wICh7IGJyb3dzZXJJZCB9KSB7XG4gICAgLy8gTk9URTogQ2hyb21lIG9uIExpbnV4IGNsb3NlcyBvbmx5IGFmdGVyIHRoZSBzZWNvbmQgU0lHVEVSTSBzaWduYWxsXG4gICAgaWYgKCFhd2FpdCBraWxsQnJvd3NlclByb2Nlc3MoYnJvd3NlcklkKSlcbiAgICAgICAgYXdhaXQga2lsbEJyb3dzZXJQcm9jZXNzKGJyb3dzZXJJZCk7XG59XG4iXX0= diff --git a/lib/browser/provider/built-in/chrome/runtime-info.js b/lib/browser/provider/built-in/chrome/runtime-info.js new file mode 100644 index 00000000..53fd467b --- /dev/null +++ b/lib/browser/provider/built-in/chrome/runtime-info.js @@ -0,0 +1,36 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _endpointUtils = require('endpoint-utils'); + +var _config = require('./config'); + +var _config2 = _interopRequireDefault(_config); + +var _createTempProfile = require('./create-temp-profile'); + +var _createTempProfile2 = _interopRequireDefault(_createTempProfile); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (proxyHostName, configString) { + const config = (0, _config2.default)(configString); + const tempProfileDir = !config.userProfile ? yield (0, _createTempProfile2.default)(proxyHostName, config) : null; + const cdpPort = config.cdpPort || (!config.userProfile ? yield (0, _endpointUtils.getFreePort)() : null); + + return { config, cdpPort, tempProfileDir }; + }); + + return function (_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2Nocm9tZS9ydW50aW1lLWluZm8uanMiXSwibmFtZXMiOlsicHJveHlIb3N0TmFtZSIsImNvbmZpZ1N0cmluZyIsImNvbmZpZyIsInRlbXBQcm9maWxlRGlyIiwidXNlclByb2ZpbGUiLCJjZHBQb3J0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBOztBQUNBOzs7O0FBQ0E7Ozs7Ozs7K0NBR2UsV0FBZ0JBLGFBQWhCLEVBQStCQyxZQUEvQixFQUE2QztBQUN4RCxjQUFNQyxTQUFpQixzQkFBVUQsWUFBVixDQUF2QjtBQUNBLGNBQU1FLGlCQUFpQixDQUFDRCxPQUFPRSxXQUFSLEdBQXNCLE1BQU0saUNBQWtCSixhQUFsQixFQUFpQ0UsTUFBakMsQ0FBNUIsR0FBdUUsSUFBOUY7QUFDQSxjQUFNRyxVQUFpQkgsT0FBT0csT0FBUCxLQUFtQixDQUFDSCxPQUFPRSxXQUFSLEdBQXNCLE1BQU0saUNBQTVCLEdBQTRDLElBQS9ELENBQXZCOztBQUVBLGVBQU8sRUFBRUYsTUFBRixFQUFVRyxPQUFWLEVBQW1CRixjQUFuQixFQUFQO0FBQ0gsSyIsImZpbGUiOiJicm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2Nocm9tZS9ydW50aW1lLWluZm8uanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRGcmVlUG9ydCB9IGZyb20gJ2VuZHBvaW50LXV0aWxzJztcbmltcG9ydCBnZXRDb25maWcgZnJvbSAnLi9jb25maWcnO1xuaW1wb3J0IGNyZWF0ZVRlbXBQcm9maWxlIGZyb20gJy4vY3JlYXRlLXRlbXAtcHJvZmlsZSc7XG5cblxuZXhwb3J0IGRlZmF1bHQgYXN5bmMgZnVuY3Rpb24gKHByb3h5SG9zdE5hbWUsIGNvbmZpZ1N0cmluZykge1xuICAgIGNvbnN0IGNvbmZpZyAgICAgICAgID0gZ2V0Q29uZmlnKGNvbmZpZ1N0cmluZyk7XG4gICAgY29uc3QgdGVtcFByb2ZpbGVEaXIgPSAhY29uZmlnLnVzZXJQcm9maWxlID8gYXdhaXQgY3JlYXRlVGVtcFByb2ZpbGUocHJveHlIb3N0TmFtZSwgY29uZmlnKSA6IG51bGw7XG4gICAgY29uc3QgY2RwUG9ydCAgICAgICAgPSBjb25maWcuY2RwUG9ydCB8fCAoIWNvbmZpZy51c2VyUHJvZmlsZSA/IGF3YWl0IGdldEZyZWVQb3J0KCkgOiBudWxsKTtcblxuICAgIHJldHVybiB7IGNvbmZpZywgY2RwUG9ydCwgdGVtcFByb2ZpbGVEaXIgfTtcbn1cbiJdfQ== diff --git a/lib/browser/provider/built-in/firefox/config.js b/lib/browser/provider/built-in/firefox/config.js new file mode 100644 index 00000000..91047693 --- /dev/null +++ b/lib/browser/provider/built-in/firefox/config.js @@ -0,0 +1,55 @@ +'use strict'; + +exports.__esModule = true; + +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + +exports.default = function (configString) { + if (!configCache[configString]) configCache[configString] = getNewConfig(configString); + + return configCache[configString]; +}; + +var _argumentParsing = require('../../utils/argument-parsing'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const AVAILABLE_MODES = ['userProfile', 'headless']; + +const configCache = {}; + +function hasCustomProfile(userArgs) { + return !!(userArgs.match(/-P\s/) || userArgs.match(/-profile\s/)); +} + +function parseModes(modesStr, userArgs) { + const parsed = (0, _argumentParsing.splitEscaped)(modesStr, ':'); + const path = (0, _argumentParsing.getPathFromParsedModes)(parsed, AVAILABLE_MODES); + const detectedModes = (0, _argumentParsing.getModes)(parsed, AVAILABLE_MODES); + const optionsString = parsed.filter(item => !!item).join(':'); + const options = parsed.length ? (0, _argumentParsing.splitEscaped)(optionsString, ';') : []; + + return { + path: path, + userProfile: detectedModes.userProfile || hasCustomProfile(userArgs), + headless: detectedModes.headless, + marionettePort: (0, _argumentParsing.findMatch)(options, /^marionettePort=(.*)/), + disableMultiprocessing: (0, _argumentParsing.isMatchTrue)(options, /^disableMultiprocessing=(.*)/) + }; +} + +function getNewConfig(configString) { + var _parseConfig = (0, _argumentParsing.parseConfig)(configString); + + const userArgs = _parseConfig.userArgs, + modesString = _parseConfig.modesString; + + const modes = parseModes(modesString, userArgs); + + return (0, _assign2.default)({ userArgs }, modes); +} + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvY29uZmlnLmpzIl0sIm5hbWVzIjpbImNvbmZpZ1N0cmluZyIsImNvbmZpZ0NhY2hlIiwiZ2V0TmV3Q29uZmlnIiwiQVZBSUxBQkxFX01PREVTIiwiaGFzQ3VzdG9tUHJvZmlsZSIsInVzZXJBcmdzIiwibWF0Y2giLCJwYXJzZU1vZGVzIiwibW9kZXNTdHIiLCJwYXJzZWQiLCJwYXRoIiwiZGV0ZWN0ZWRNb2RlcyIsIm9wdGlvbnNTdHJpbmciLCJmaWx0ZXIiLCJpdGVtIiwiam9pbiIsIm9wdGlvbnMiLCJsZW5ndGgiLCJ1c2VyUHJvZmlsZSIsImhlYWRsZXNzIiwibWFyaW9uZXR0ZVBvcnQiLCJkaXNhYmxlTXVsdGlwcm9jZXNzaW5nIiwibW9kZXNTdHJpbmciLCJtb2RlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7a0JBbUNlLFVBQVVBLFlBQVYsRUFBd0I7QUFDbkMsUUFBSSxDQUFDQyxZQUFZRCxZQUFaLENBQUwsRUFDSUMsWUFBWUQsWUFBWixJQUE0QkUsYUFBYUYsWUFBYixDQUE1Qjs7QUFFSixXQUFPQyxZQUFZRCxZQUFaLENBQVA7QUFDSCxDOztBQXhDRDs7OztBQUdBLE1BQU1HLGtCQUFrQixDQUFDLGFBQUQsRUFBZ0IsVUFBaEIsQ0FBeEI7O0FBRUEsTUFBTUYsY0FBYyxFQUFwQjs7QUFFQSxTQUFTRyxnQkFBVCxDQUEyQkMsUUFBM0IsRUFBcUM7QUFDakMsV0FBTyxDQUFDLEVBQUVBLFNBQVNDLEtBQVQsQ0FBZSxNQUFmLEtBQTBCRCxTQUFTQyxLQUFULENBQWUsWUFBZixDQUE1QixDQUFSO0FBQ0g7O0FBRUQsU0FBU0MsVUFBVCxDQUFxQkMsUUFBckIsRUFBK0JILFFBQS9CLEVBQXlDO0FBQ3JDLFVBQU1JLFNBQWdCLG1DQUFhRCxRQUFiLEVBQXVCLEdBQXZCLENBQXRCO0FBQ0EsVUFBTUUsT0FBZ0IsNkNBQXVCRCxNQUF2QixFQUErQk4sZUFBL0IsQ0FBdEI7QUFDQSxVQUFNUSxnQkFBZ0IsK0JBQVNGLE1BQVQsRUFBaUJOLGVBQWpCLENBQXRCO0FBQ0EsVUFBTVMsZ0JBQWdCSCxPQUFPSSxNQUFQLENBQWNDLFFBQVEsQ0FBQyxDQUFDQSxJQUF4QixFQUE4QkMsSUFBOUIsQ0FBbUMsR0FBbkMsQ0FBdEI7QUFDQSxVQUFNQyxVQUFnQlAsT0FBT1EsTUFBUCxHQUFnQixtQ0FBYUwsYUFBYixFQUE0QixHQUE1QixDQUFoQixHQUFtRCxFQUF6RTs7QUFFQSxXQUFPO0FBQ0hGLGNBQXdCQSxJQURyQjtBQUVIUSxxQkFBd0JQLGNBQWNPLFdBQWQsSUFBNkJkLGlCQUFpQkMsUUFBakIsQ0FGbEQ7QUFHSGMsa0JBQXdCUixjQUFjUSxRQUhuQztBQUlIQyx3QkFBd0IsZ0NBQVVKLE9BQVYsRUFBbUIsc0JBQW5CLENBSnJCO0FBS0hLLGdDQUF3QixrQ0FBWUwsT0FBWixFQUFxQiw4QkFBckI7QUFMckIsS0FBUDtBQU9IOztBQUdELFNBQVNkLFlBQVQsQ0FBdUJGLFlBQXZCLEVBQXFDO0FBQUEsdUJBQ0Msa0NBQVlBLFlBQVosQ0FERDs7QUFBQSxVQUN6QkssUUFEeUIsZ0JBQ3pCQSxRQUR5QjtBQUFBLFVBQ2ZpQixXQURlLGdCQUNmQSxXQURlOztBQUVqQyxVQUFNQyxRQUE0QmhCLFdBQVdlLFdBQVgsRUFBd0JqQixRQUF4QixDQUFsQzs7QUFFQSxXQUFPLHNCQUFjLEVBQUVBLFFBQUYsRUFBZCxFQUE0QmtCLEtBQTVCLENBQVA7QUFDSCIsImZpbGUiOiJicm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvY29uZmlnLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZmluZE1hdGNoLCBpc01hdGNoVHJ1ZSwgc3BsaXRFc2NhcGVkLCBwYXJzZUNvbmZpZywgZ2V0TW9kZXMsIGdldFBhdGhGcm9tUGFyc2VkTW9kZXMgfSBmcm9tICcuLi8uLi91dGlscy9hcmd1bWVudC1wYXJzaW5nJztcblxuXG5jb25zdCBBVkFJTEFCTEVfTU9ERVMgPSBbJ3VzZXJQcm9maWxlJywgJ2hlYWRsZXNzJ107XG5cbmNvbnN0IGNvbmZpZ0NhY2hlID0ge307XG5cbmZ1bmN0aW9uIGhhc0N1c3RvbVByb2ZpbGUgKHVzZXJBcmdzKSB7XG4gICAgcmV0dXJuICEhKHVzZXJBcmdzLm1hdGNoKC8tUFxccy8pIHx8IHVzZXJBcmdzLm1hdGNoKC8tcHJvZmlsZVxccy8pKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VNb2RlcyAobW9kZXNTdHIsIHVzZXJBcmdzKSB7XG4gICAgY29uc3QgcGFyc2VkICAgICAgICA9IHNwbGl0RXNjYXBlZChtb2Rlc1N0ciwgJzonKTtcbiAgICBjb25zdCBwYXRoICAgICAgICAgID0gZ2V0UGF0aEZyb21QYXJzZWRNb2RlcyhwYXJzZWQsIEFWQUlMQUJMRV9NT0RFUyk7XG4gICAgY29uc3QgZGV0ZWN0ZWRNb2RlcyA9IGdldE1vZGVzKHBhcnNlZCwgQVZBSUxBQkxFX01PREVTKTtcbiAgICBjb25zdCBvcHRpb25zU3RyaW5nID0gcGFyc2VkLmZpbHRlcihpdGVtID0+ICEhaXRlbSkuam9pbignOicpO1xuICAgIGNvbnN0IG9wdGlvbnMgICAgICAgPSBwYXJzZWQubGVuZ3RoID8gc3BsaXRFc2NhcGVkKG9wdGlvbnNTdHJpbmcsICc7JykgOiBbXTtcblxuICAgIHJldHVybiB7XG4gICAgICAgIHBhdGg6ICAgICAgICAgICAgICAgICAgIHBhdGgsXG4gICAgICAgIHVzZXJQcm9maWxlOiAgICAgICAgICAgIGRldGVjdGVkTW9kZXMudXNlclByb2ZpbGUgfHwgaGFzQ3VzdG9tUHJvZmlsZSh1c2VyQXJncyksXG4gICAgICAgIGhlYWRsZXNzOiAgICAgICAgICAgICAgIGRldGVjdGVkTW9kZXMuaGVhZGxlc3MsXG4gICAgICAgIG1hcmlvbmV0dGVQb3J0OiAgICAgICAgIGZpbmRNYXRjaChvcHRpb25zLCAvXm1hcmlvbmV0dGVQb3J0PSguKikvKSxcbiAgICAgICAgZGlzYWJsZU11bHRpcHJvY2Vzc2luZzogaXNNYXRjaFRydWUob3B0aW9ucywgL15kaXNhYmxlTXVsdGlwcm9jZXNzaW5nPSguKikvKVxuICAgIH07XG59XG5cblxuZnVuY3Rpb24gZ2V0TmV3Q29uZmlnIChjb25maWdTdHJpbmcpIHtcbiAgICBjb25zdCB7IHVzZXJBcmdzLCBtb2Rlc1N0cmluZyB9ID0gcGFyc2VDb25maWcoY29uZmlnU3RyaW5nKTtcbiAgICBjb25zdCBtb2RlcyAgICAgICAgICAgICAgICAgICAgID0gcGFyc2VNb2Rlcyhtb2Rlc1N0cmluZywgdXNlckFyZ3MpO1xuXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oeyB1c2VyQXJncyB9LCBtb2Rlcyk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChjb25maWdTdHJpbmcpIHtcbiAgICBpZiAoIWNvbmZpZ0NhY2hlW2NvbmZpZ1N0cmluZ10pXG4gICAgICAgIGNvbmZpZ0NhY2hlW2NvbmZpZ1N0cmluZ10gPSBnZXROZXdDb25maWcoY29uZmlnU3RyaW5nKTtcblxuICAgIHJldHVybiBjb25maWdDYWNoZVtjb25maWdTdHJpbmddO1xufVxuIl19 diff --git a/lib/browser/provider/built-in/firefox/create-temp-profile.js b/lib/browser/provider/built-in/firefox/create-temp-profile.js new file mode 100644 index 00000000..678dbf53 --- /dev/null +++ b/lib/browser/provider/built-in/firefox/create-temp-profile.js @@ -0,0 +1,58 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +let generatePreferences = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (profileDir, { marionettePort, config }) { + const prefsFileName = _path2.default.join(profileDir, 'user.js'); + + let prefs = ['user_pref("browser.link.open_newwindow.override.external", 2);', 'user_pref("app.update.enabled", false);', 'user_pref("app.update.auto", false);', 'user_pref("app.update.mode", 0);', 'user_pref("app.update.service.enabled", false);', 'user_pref("browser.shell.checkDefaultBrowser", false);', 'user_pref("browser.usedOnWindows10", true);', 'user_pref("browser.rights.3.shown", true);', 'user_pref("browser.startup.homepage_override.mstone","ignore");', 'user_pref("browser.tabs.warnOnCloseOtherTabs", false);', 'user_pref("browser.tabs.warnOnClose", false);', 'user_pref("browser.sessionstore.resume_from_crash", false);', 'user_pref("toolkit.telemetry.reportingpolicy.firstRun", false);', 'user_pref("toolkit.telemetry.enabled", false);', 'user_pref("toolkit.telemetry.rejected", true);', 'user_pref("datareporting.healthreport.uploadEnabled", false);', 'user_pref("datareporting.healthreport.service.enabled", false);', 'user_pref("datareporting.healthreport.service.firstRun", false);', 'user_pref("datareporting.policy.dataSubmissionEnabled", false);', 'user_pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);', 'user_pref("app.shield.optoutstudies.enabled", false);', 'user_pref("extensions.shield-recipe-client.enabled", false);', 'user_pref("extensions.shield-recipe-client.first_run", false);', 'user_pref("extensions.shield-recipe-client.startupExperimentPrefs.browser.newtabpage.activity-stream.enabled", false);', 'user_pref("devtools.toolbox.host", "window");', 'user_pref("devtools.toolbox.previousHost", "bottom");', 'user_pref("signon.rememberSignons", false);']; + + if (marionettePort) { + prefs = prefs.concat([`user_pref("marionette.port", ${marionettePort});`, 'user_pref("marionette.enabled", true);']); + } + + if (config.disableMultiprocessing) { + prefs = prefs.concat(['user_pref("browser.tabs.remote.autostart", false);', 'user_pref("browser.tabs.remote.autostart.2", false);']); + } + + yield (0, _promisifiedFunctions.writeFile)(prefsFileName, prefs.join('\n')); + }); + + return function generatePreferences(_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); + +var _path = require('path'); + +var _path2 = _interopRequireDefault(_path); + +var _tempDirectory = require('../../../../utils/temp-directory'); + +var _tempDirectory2 = _interopRequireDefault(_tempDirectory); + +var _promisifiedFunctions = require('../../../../utils/promisified-functions'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = (() => { + var _ref2 = (0, _asyncToGenerator3.default)(function* (runtimeInfo) { + const tmpDir = yield _tempDirectory2.default.createDirectory('firefox-profile'); + + yield generatePreferences(tmpDir.path, runtimeInfo); + + return tmpDir; + }); + + return function (_x3) { + return _ref2.apply(this, arguments); + }; +})(); + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvY3JlYXRlLXRlbXAtcHJvZmlsZS5qcyJdLCJuYW1lcyI6WyJwcm9maWxlRGlyIiwibWFyaW9uZXR0ZVBvcnQiLCJjb25maWciLCJwcmVmc0ZpbGVOYW1lIiwicGF0aCIsImpvaW4iLCJwcmVmcyIsImNvbmNhdCIsImRpc2FibGVNdWx0aXByb2Nlc3NpbmciLCJnZW5lcmF0ZVByZWZlcmVuY2VzIiwicnVudGltZUluZm8iLCJ0bXBEaXIiLCJUZW1wRGlyZWN0b3J5IiwiY3JlYXRlRGlyZWN0b3J5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7K0NBS0EsV0FBb0NBLFVBQXBDLEVBQWdELEVBQUVDLGNBQUYsRUFBa0JDLE1BQWxCLEVBQWhELEVBQTRFO0FBQ3hFLGNBQU1DLGdCQUFnQkMsZUFBS0MsSUFBTCxDQUFVTCxVQUFWLEVBQXNCLFNBQXRCLENBQXRCOztBQUVBLFlBQUlNLFFBQVEsQ0FDUixnRUFEUSxFQUVSLHlDQUZRLEVBR1Isc0NBSFEsRUFJUixrQ0FKUSxFQUtSLGlEQUxRLEVBTVIsd0RBTlEsRUFPUiw2Q0FQUSxFQVFSLDRDQVJRLEVBU1IsaUVBVFEsRUFVUix3REFWUSxFQVdSLCtDQVhRLEVBWVIsNkRBWlEsRUFhUixpRUFiUSxFQWNSLGdEQWRRLEVBZVIsZ0RBZlEsRUFnQlIsK0RBaEJRLEVBaUJSLGlFQWpCUSxFQWtCUixrRUFsQlEsRUFtQlIsaUVBbkJRLEVBb0JSLGlGQXBCUSxFQXFCUix1REFyQlEsRUFzQlIsOERBdEJRLEVBdUJSLGdFQXZCUSxFQXdCUix3SEF4QlEsRUF5QlIsK0NBekJRLEVBMEJSLHVEQTFCUSxFQTJCUiw2Q0EzQlEsQ0FBWjs7QUE4QkEsWUFBSUwsY0FBSixFQUFvQjtBQUNoQkssb0JBQVFBLE1BQU1DLE1BQU4sQ0FBYSxDQUNoQixnQ0FBK0JOLGNBQWUsSUFEOUIsRUFFakIsd0NBRmlCLENBQWIsQ0FBUjtBQUlIOztBQUVELFlBQUlDLE9BQU9NLHNCQUFYLEVBQW1DO0FBQy9CRixvQkFBUUEsTUFBTUMsTUFBTixDQUFhLENBQ2pCLG9EQURpQixFQUVqQixzREFGaUIsQ0FBYixDQUFSO0FBSUg7O0FBRUQsY0FBTSxxQ0FBVUosYUFBVixFQUF5QkcsTUFBTUQsSUFBTixDQUFXLElBQVgsQ0FBekIsQ0FBTjtBQUNILEs7O29CQWhEY0ksbUI7Ozs7O0FBTGY7Ozs7QUFDQTs7OztBQUNBOzs7OztnREFxRGUsV0FBZ0JDLFdBQWhCLEVBQTZCO0FBQ3hDLGNBQU1DLFNBQVMsTUFBTUMsd0JBQWNDLGVBQWQsQ0FBOEIsaUJBQTlCLENBQXJCOztBQUVBLGNBQU1KLG9CQUFvQkUsT0FBT1AsSUFBM0IsRUFBaUNNLFdBQWpDLENBQU47O0FBRUEsZUFBT0MsTUFBUDtBQUNILEsiLCJmaWxlIjoiYnJvd3Nlci9wcm92aWRlci9idWlsdC1pbi9maXJlZm94L2NyZWF0ZS10ZW1wLXByb2ZpbGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBUZW1wRGlyZWN0b3J5IGZyb20gJy4uLy4uLy4uLy4uL3V0aWxzL3RlbXAtZGlyZWN0b3J5JztcbmltcG9ydCB7IHdyaXRlRmlsZSB9IGZyb20gJy4uLy4uLy4uLy4uL3V0aWxzL3Byb21pc2lmaWVkLWZ1bmN0aW9ucyc7XG5cblxuYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVQcmVmZXJlbmNlcyAocHJvZmlsZURpciwgeyBtYXJpb25ldHRlUG9ydCwgY29uZmlnIH0pIHtcbiAgICBjb25zdCBwcmVmc0ZpbGVOYW1lID0gcGF0aC5qb2luKHByb2ZpbGVEaXIsICd1c2VyLmpzJyk7XG5cbiAgICBsZXQgcHJlZnMgPSBbXG4gICAgICAgICd1c2VyX3ByZWYoXCJicm93c2VyLmxpbmsub3Blbl9uZXd3aW5kb3cub3ZlcnJpZGUuZXh0ZXJuYWxcIiwgMik7JyxcbiAgICAgICAgJ3VzZXJfcHJlZihcImFwcC51cGRhdGUuZW5hYmxlZFwiLCBmYWxzZSk7JyxcbiAgICAgICAgJ3VzZXJfcHJlZihcImFwcC51cGRhdGUuYXV0b1wiLCBmYWxzZSk7JyxcbiAgICAgICAgJ3VzZXJfcHJlZihcImFwcC51cGRhdGUubW9kZVwiLCAwKTsnLFxuICAgICAgICAndXNlcl9wcmVmKFwiYXBwLnVwZGF0ZS5zZXJ2aWNlLmVuYWJsZWRcIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJicm93c2VyLnNoZWxsLmNoZWNrRGVmYXVsdEJyb3dzZXJcIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJicm93c2VyLnVzZWRPbldpbmRvd3MxMFwiLCB0cnVlKTsnLFxuICAgICAgICAndXNlcl9wcmVmKFwiYnJvd3Nlci5yaWdodHMuMy5zaG93blwiLCB0cnVlKTsnLFxuICAgICAgICAndXNlcl9wcmVmKFwiYnJvd3Nlci5zdGFydHVwLmhvbWVwYWdlX292ZXJyaWRlLm1zdG9uZVwiLFwiaWdub3JlXCIpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJicm93c2VyLnRhYnMud2Fybk9uQ2xvc2VPdGhlclRhYnNcIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJicm93c2VyLnRhYnMud2Fybk9uQ2xvc2VcIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJicm93c2VyLnNlc3Npb25zdG9yZS5yZXN1bWVfZnJvbV9jcmFzaFwiLCBmYWxzZSk7JyxcbiAgICAgICAgJ3VzZXJfcHJlZihcInRvb2xraXQudGVsZW1ldHJ5LnJlcG9ydGluZ3BvbGljeS5maXJzdFJ1blwiLCBmYWxzZSk7JyxcbiAgICAgICAgJ3VzZXJfcHJlZihcInRvb2xraXQudGVsZW1ldHJ5LmVuYWJsZWRcIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJ0b29sa2l0LnRlbGVtZXRyeS5yZWplY3RlZFwiLCB0cnVlKTsnLFxuICAgICAgICAndXNlcl9wcmVmKFwiZGF0YXJlcG9ydGluZy5oZWFsdGhyZXBvcnQudXBsb2FkRW5hYmxlZFwiLCBmYWxzZSk7JyxcbiAgICAgICAgJ3VzZXJfcHJlZihcImRhdGFyZXBvcnRpbmcuaGVhbHRocmVwb3J0LnNlcnZpY2UuZW5hYmxlZFwiLCBmYWxzZSk7JyxcbiAgICAgICAgJ3VzZXJfcHJlZihcImRhdGFyZXBvcnRpbmcuaGVhbHRocmVwb3J0LnNlcnZpY2UuZmlyc3RSdW5cIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJkYXRhcmVwb3J0aW5nLnBvbGljeS5kYXRhU3VibWlzc2lvbkVuYWJsZWRcIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJkYXRhcmVwb3J0aW5nLnBvbGljeS5kYXRhU3VibWlzc2lvblBvbGljeUJ5cGFzc05vdGlmaWNhdGlvblwiLCB0cnVlKTsnLFxuICAgICAgICAndXNlcl9wcmVmKFwiYXBwLnNoaWVsZC5vcHRvdXRzdHVkaWVzLmVuYWJsZWRcIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJleHRlbnNpb25zLnNoaWVsZC1yZWNpcGUtY2xpZW50LmVuYWJsZWRcIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJleHRlbnNpb25zLnNoaWVsZC1yZWNpcGUtY2xpZW50LmZpcnN0X3J1blwiLCBmYWxzZSk7JyxcbiAgICAgICAgJ3VzZXJfcHJlZihcImV4dGVuc2lvbnMuc2hpZWxkLXJlY2lwZS1jbGllbnQuc3RhcnR1cEV4cGVyaW1lbnRQcmVmcy5icm93c2VyLm5ld3RhYnBhZ2UuYWN0aXZpdHktc3RyZWFtLmVuYWJsZWRcIiwgZmFsc2UpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJkZXZ0b29scy50b29sYm94Lmhvc3RcIiwgXCJ3aW5kb3dcIik7JyxcbiAgICAgICAgJ3VzZXJfcHJlZihcImRldnRvb2xzLnRvb2xib3gucHJldmlvdXNIb3N0XCIsIFwiYm90dG9tXCIpOycsXG4gICAgICAgICd1c2VyX3ByZWYoXCJzaWdub24ucmVtZW1iZXJTaWdub25zXCIsIGZhbHNlKTsnXG4gICAgXTtcblxuICAgIGlmIChtYXJpb25ldHRlUG9ydCkge1xuICAgICAgICBwcmVmcyA9IHByZWZzLmNvbmNhdChbXG4gICAgICAgICAgICBgdXNlcl9wcmVmKFwibWFyaW9uZXR0ZS5wb3J0XCIsICR7bWFyaW9uZXR0ZVBvcnR9KTtgLFxuICAgICAgICAgICAgJ3VzZXJfcHJlZihcIm1hcmlvbmV0dGUuZW5hYmxlZFwiLCB0cnVlKTsnXG4gICAgICAgIF0pO1xuICAgIH1cblxuICAgIGlmIChjb25maWcuZGlzYWJsZU11bHRpcHJvY2Vzc2luZykge1xuICAgICAgICBwcmVmcyA9IHByZWZzLmNvbmNhdChbXG4gICAgICAgICAgICAndXNlcl9wcmVmKFwiYnJvd3Nlci50YWJzLnJlbW90ZS5hdXRvc3RhcnRcIiwgZmFsc2UpOycsXG4gICAgICAgICAgICAndXNlcl9wcmVmKFwiYnJvd3Nlci50YWJzLnJlbW90ZS5hdXRvc3RhcnQuMlwiLCBmYWxzZSk7JyxcbiAgICAgICAgXSk7XG4gICAgfVxuXG4gICAgYXdhaXQgd3JpdGVGaWxlKHByZWZzRmlsZU5hbWUsIHByZWZzLmpvaW4oJ1xcbicpKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgYXN5bmMgZnVuY3Rpb24gKHJ1bnRpbWVJbmZvKSB7XG4gICAgY29uc3QgdG1wRGlyID0gYXdhaXQgVGVtcERpcmVjdG9yeS5jcmVhdGVEaXJlY3RvcnkoJ2ZpcmVmb3gtcHJvZmlsZScpO1xuXG4gICAgYXdhaXQgZ2VuZXJhdGVQcmVmZXJlbmNlcyh0bXBEaXIucGF0aCwgcnVudGltZUluZm8pO1xuXG4gICAgcmV0dXJuIHRtcERpcjtcbn1cbiJdfQ== diff --git a/lib/browser/provider/built-in/firefox/index.js b/lib/browser/provider/built-in/firefox/index.js new file mode 100644 index 00000000..634efab9 --- /dev/null +++ b/lib/browser/provider/built-in/firefox/index.js @@ -0,0 +1,150 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _osFamily = require('os-family'); + +var _osFamily2 = _interopRequireDefault(_osFamily); + +var _runtimeInfo = require('./runtime-info'); + +var _runtimeInfo2 = _interopRequireDefault(_runtimeInfo); + +var _localFirefox = require('./local-firefox'); + +var _marionetteClient = require('./marionette-client'); + +var _marionetteClient2 = _interopRequireDefault(_marionetteClient); + +var _getMaximizedHeadlessWindowSize = require('../../utils/get-maximized-headless-window-size'); + +var _getMaximizedHeadlessWindowSize2 = _interopRequireDefault(_getMaximizedHeadlessWindowSize); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + openedBrowsers: {}, + + isMultiBrowser: false, + + _createMarionetteClient(runtimeInfo) { + return (0, _asyncToGenerator3.default)(function* () { + try { + const marionetteClient = new _marionetteClient2.default(runtimeInfo.marionettePort); + + yield marionetteClient.connect(); + + return marionetteClient; + } catch (e) { + return null; + } + })(); + }, + + openBrowser(browserId, pageUrl, configString) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + const runtimeInfo = yield (0, _runtimeInfo2.default)(configString); + const browserName = _this.providerName.replace(':', ''); + + runtimeInfo.browserId = browserId; + runtimeInfo.browserName = browserName; + + yield (0, _localFirefox.start)(pageUrl, runtimeInfo); + + yield _this.waitForConnectionReady(runtimeInfo.browserId); + + if (runtimeInfo.marionettePort) runtimeInfo.marionetteClient = yield _this._createMarionetteClient(runtimeInfo); + + _this.openedBrowsers[browserId] = runtimeInfo; + })(); + }, + + closeBrowser(browserId) { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const runtimeInfo = _this2.openedBrowsers[browserId]; + const config = runtimeInfo.config, + marionetteClient = runtimeInfo.marionetteClient; + + + if (config.headless) yield marionetteClient.quit();else yield _this2.closeLocalBrowser(browserId); + + if (_osFamily2.default.mac && !config.headless) yield (0, _localFirefox.stop)(runtimeInfo); + + if (runtimeInfo.tempProfileDir) yield runtimeInfo.tempProfileDir.dispose(); + + delete _this2.openedBrowsers[browserId]; + })(); + }, + + isLocalBrowser() { + return (0, _asyncToGenerator3.default)(function* () { + return true; + })(); + }, + + isHeadlessBrowser(browserId) { + return this.openedBrowsers[browserId].config.headless; + }, + + takeScreenshot(browserId, path) { + var _this3 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const marionetteClient = _this3.openedBrowsers[browserId].marionetteClient; + + + yield marionetteClient.takeScreenshot(path); + })(); + }, + + resizeWindow(browserId, width, height) { + var _this4 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const marionetteClient = _this4.openedBrowsers[browserId].marionetteClient; + + + yield marionetteClient.setWindowSize(width, height); + })(); + }, + + maximizeWindow(browserId) { + var _this5 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const maximumSize = (0, _getMaximizedHeadlessWindowSize2.default)(); + + yield _this5.resizeWindow(browserId, maximumSize.width, maximumSize.height); + })(); + }, + + hasCustomActionForBrowser(browserId) { + var _this6 = this; + + return (0, _asyncToGenerator3.default)(function* () { + var _openedBrowsers$brows = _this6.openedBrowsers[browserId]; + const config = _openedBrowsers$brows.config, + marionetteClient = _openedBrowsers$brows.marionetteClient; + + + return { + hasCloseBrowser: true, + hasTakeScreenshot: !!marionetteClient, + hasChromelessScreenshots: !!marionetteClient, + hasResizeWindow: !!marionetteClient && config.headless, + hasMaximizeWindow: !!marionetteClient && config.headless, + hasCanResizeWindowToDimensions: false + }; + })(); + } +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvaW5kZXguanMiXSwibmFtZXMiOlsib3BlbmVkQnJvd3NlcnMiLCJpc011bHRpQnJvd3NlciIsIl9jcmVhdGVNYXJpb25ldHRlQ2xpZW50IiwicnVudGltZUluZm8iLCJtYXJpb25ldHRlQ2xpZW50IiwiTWFyaW9uZXR0ZUNsaWVudCIsIm1hcmlvbmV0dGVQb3J0IiwiY29ubmVjdCIsImUiLCJvcGVuQnJvd3NlciIsImJyb3dzZXJJZCIsInBhZ2VVcmwiLCJjb25maWdTdHJpbmciLCJicm93c2VyTmFtZSIsInByb3ZpZGVyTmFtZSIsInJlcGxhY2UiLCJ3YWl0Rm9yQ29ubmVjdGlvblJlYWR5IiwiY2xvc2VCcm93c2VyIiwiY29uZmlnIiwiaGVhZGxlc3MiLCJxdWl0IiwiY2xvc2VMb2NhbEJyb3dzZXIiLCJPUyIsIm1hYyIsInRlbXBQcm9maWxlRGlyIiwiZGlzcG9zZSIsImlzTG9jYWxCcm93c2VyIiwiaXNIZWFkbGVzc0Jyb3dzZXIiLCJ0YWtlU2NyZWVuc2hvdCIsInBhdGgiLCJyZXNpemVXaW5kb3ciLCJ3aWR0aCIsImhlaWdodCIsInNldFdpbmRvd1NpemUiLCJtYXhpbWl6ZVdpbmRvdyIsIm1heGltdW1TaXplIiwiaGFzQ3VzdG9tQWN0aW9uRm9yQnJvd3NlciIsImhhc0Nsb3NlQnJvd3NlciIsImhhc1Rha2VTY3JlZW5zaG90IiwiaGFzQ2hyb21lbGVzc1NjcmVlbnNob3RzIiwiaGFzUmVzaXplV2luZG93IiwiaGFzTWF4aW1pemVXaW5kb3ciLCJoYXNDYW5SZXNpemVXaW5kb3dUb0RpbWVuc2lvbnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7OztrQkFHZTtBQUNYQSxvQkFBZ0IsRUFETDs7QUFHWEMsb0JBQWdCLEtBSEw7O0FBS0xDLDJCQUFOLENBQStCQyxXQUEvQixFQUE0QztBQUFB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Q0FBcEI7O0FBRUEsa0JBQU0sT0FBS0wsWUFBTCxDQUFrQnBCLFNBQWxCLEVBQTZCeUIsWUFBWUosS0FBekMsRUFBZ0RJLFlBQVlILE1BQTVELENBQU47QUFINkI7QUFJaEMsS0E3RVU7O0FBK0VMSSw2QkFBTixDQUFpQzFCLFNBQWpDLEVBQTRDO0FBQUE7O0FBQUE7QUFBQSx3Q0FDSCxPQUFLVixjQUFMLENBQW9CVSxTQUFwQixDQURHO0FBQUEsa0JBQ2hDUSxNQURnQyx5QkFDaENBLE1BRGdDO0FBQUEsa0JBQ3hCZCxnQkFEd0IseUJBQ3hCQSxnQkFEd0I7OztBQUd4QyxtQkFBTztBQUNIaUMsaUNBQWdDLElBRDdCO0FBRUhDLG1DQUFnQyxDQUFDLENBQUNsQyxnQkFGL0I7QUFHSG1DLDBDQUFnQyxDQUFDLENBQUNuQyxnQkFIL0I7QUFJSG9DLGlDQUFnQyxDQUFDLENBQUNwQyxnQkFBRixJQUFzQmMsT0FBT0MsUUFKMUQ7QUFLSHNCLG1DQUFnQyxDQUFDLENBQUNyQyxnQkFBRixJQUFzQmMsT0FBT0MsUUFMMUQ7QUFNSHVCLGdEQUFnQztBQU43QixhQUFQO0FBSHdDO0FBVzNDO0FBMUZVLEMiLCJmaWxlIjoiYnJvd3Nlci9wcm92aWRlci9idWlsdC1pbi9maXJlZm94L2luZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IE9TIGZyb20gJ29zLWZhbWlseSc7XG5pbXBvcnQgZ2V0UnVudGltZUluZm8gZnJvbSAnLi9ydW50aW1lLWluZm8nO1xuaW1wb3J0IHsgc3RhcnQgYXMgc3RhcnRMb2NhbEZpcmVmb3gsIHN0b3AgYXMgc3RvcExvY2FsRmlyZWZveCB9IGZyb20gJy4vbG9jYWwtZmlyZWZveCc7XG5pbXBvcnQgTWFyaW9uZXR0ZUNsaWVudCBmcm9tICcuL21hcmlvbmV0dGUtY2xpZW50JztcbmltcG9ydCBnZXRNYXhpbWl6ZWRIZWFkbGVzc1dpbmRvd1NpemUgZnJvbSAnLi4vLi4vdXRpbHMvZ2V0LW1heGltaXplZC1oZWFkbGVzcy13aW5kb3ctc2l6ZSc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIG9wZW5lZEJyb3dzZXJzOiB7fSxcblxuICAgIGlzTXVsdGlCcm93c2VyOiBmYWxzZSxcblxuICAgIGFzeW5jIF9jcmVhdGVNYXJpb25ldHRlQ2xpZW50IChydW50aW1lSW5mbykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgbWFyaW9uZXR0ZUNsaWVudCA9IG5ldyBNYXJpb25ldHRlQ2xpZW50KHJ1bnRpbWVJbmZvLm1hcmlvbmV0dGVQb3J0KTtcblxuICAgICAgICAgICAgYXdhaXQgbWFyaW9uZXR0ZUNsaWVudC5jb25uZWN0KCk7XG5cbiAgICAgICAgICAgIHJldHVybiBtYXJpb25ldHRlQ2xpZW50O1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBhc3luYyBvcGVuQnJvd3NlciAoYnJvd3NlcklkLCBwYWdlVXJsLCBjb25maWdTdHJpbmcpIHtcbiAgICAgICAgY29uc3QgcnVudGltZUluZm8gPSBhd2FpdCBnZXRSdW50aW1lSW5mbyhjb25maWdTdHJpbmcpO1xuICAgICAgICBjb25zdCBicm93c2VyTmFtZSA9IHRoaXMucHJvdmlkZXJOYW1lLnJlcGxhY2UoJzonLCAnJyk7XG5cbiAgICAgICAgcnVudGltZUluZm8uYnJvd3NlcklkICAgPSBicm93c2VySWQ7XG4gICAgICAgIHJ1bnRpbWVJbmZvLmJyb3dzZXJOYW1lID0gYnJvd3Nlck5hbWU7XG5cbiAgICAgICAgYXdhaXQgc3RhcnRMb2NhbEZpcmVmb3gocGFnZVVybCwgcnVudGltZUluZm8pO1xuXG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvckNvbm5lY3Rpb25SZWFkeShydW50aW1lSW5mby5icm93c2VySWQpO1xuXG4gICAgICAgIGlmIChydW50aW1lSW5mby5tYXJpb25ldHRlUG9ydClcbiAgICAgICAgICAgIHJ1bnRpbWVJbmZvLm1hcmlvbmV0dGVDbGllbnQgPSBhd2FpdCB0aGlzLl9jcmVhdGVNYXJpb25ldHRlQ2xpZW50KHJ1bnRpbWVJbmZvKTtcblxuICAgICAgICB0aGlzLm9wZW5lZEJyb3dzZXJzW2Jyb3dzZXJJZF0gPSBydW50aW1lSW5mbztcbiAgICB9LFxuXG4gICAgYXN5bmMgY2xvc2VCcm93c2VyIChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgcnVudGltZUluZm8gPSB0aGlzLm9wZW5lZEJyb3dzZXJzW2Jyb3dzZXJJZF07XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBtYXJpb25ldHRlQ2xpZW50IH0gPSBydW50aW1lSW5mbztcblxuICAgICAgICBpZiAoY29uZmlnLmhlYWRsZXNzKVxuICAgICAgICAgICAgYXdhaXQgbWFyaW9uZXR0ZUNsaWVudC5xdWl0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2xvc2VMb2NhbEJyb3dzZXIoYnJvd3NlcklkKTtcblxuICAgICAgICBpZiAoT1MubWFjICYmICFjb25maWcuaGVhZGxlc3MpXG4gICAgICAgICAgICBhd2FpdCBzdG9wTG9jYWxGaXJlZm94KHJ1bnRpbWVJbmZvKTtcblxuICAgICAgICBpZiAocnVudGltZUluZm8udGVtcFByb2ZpbGVEaXIpXG4gICAgICAgICAgICBhd2FpdCBydW50aW1lSW5mby50ZW1wUHJvZmlsZURpci5kaXNwb3NlKCk7XG5cbiAgICAgICAgZGVsZXRlIHRoaXMub3BlbmVkQnJvd3NlcnNbYnJvd3NlcklkXTtcbiAgICB9LFxuXG4gICAgYXN5bmMgaXNMb2NhbEJyb3dzZXIgKCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuXG4gICAgaXNIZWFkbGVzc0Jyb3dzZXIgKGJyb3dzZXJJZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdLmNvbmZpZy5oZWFkbGVzcztcbiAgICB9LFxuXG4gICAgYXN5bmMgdGFrZVNjcmVlbnNob3QgKGJyb3dzZXJJZCwgcGF0aCkge1xuICAgICAgICBjb25zdCB7IG1hcmlvbmV0dGVDbGllbnQgfSA9IHRoaXMub3BlbmVkQnJvd3NlcnNbYnJvd3NlcklkXTtcblxuICAgICAgICBhd2FpdCBtYXJpb25ldHRlQ2xpZW50LnRha2VTY3JlZW5zaG90KHBhdGgpO1xuICAgIH0sXG5cbiAgICBhc3luYyByZXNpemVXaW5kb3cgKGJyb3dzZXJJZCwgd2lkdGgsIGhlaWdodCkge1xuICAgICAgICBjb25zdCB7IG1hcmlvbmV0dGVDbGllbnQgfSA9IHRoaXMub3BlbmVkQnJvd3NlcnNbYnJvd3NlcklkXTtcblxuICAgICAgICBhd2FpdCBtYXJpb25ldHRlQ2xpZW50LnNldFdpbmRvd1NpemUod2lkdGgsIGhlaWdodCk7XG4gICAgfSxcblxuICAgIGFzeW5jIG1heGltaXplV2luZG93IChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgbWF4aW11bVNpemUgPSBnZXRNYXhpbWl6ZWRIZWFkbGVzc1dpbmRvd1NpemUoKTtcblxuICAgICAgICBhd2FpdCB0aGlzLnJlc2l6ZVdpbmRvdyhicm93c2VySWQsIG1heGltdW1TaXplLndpZHRoLCBtYXhpbXVtU2l6ZS5oZWlnaHQpO1xuICAgIH0sXG5cbiAgICBhc3luYyBoYXNDdXN0b21BY3Rpb25Gb3JCcm93c2VyIChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgeyBjb25maWcsIG1hcmlvbmV0dGVDbGllbnQgfSA9IHRoaXMub3BlbmVkQnJvd3NlcnNbYnJvd3NlcklkXTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaGFzQ2xvc2VCcm93c2VyOiAgICAgICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgaGFzVGFrZVNjcmVlbnNob3Q6ICAgICAgICAgICAgICAhIW1hcmlvbmV0dGVDbGllbnQsXG4gICAgICAgICAgICBoYXNDaHJvbWVsZXNzU2NyZWVuc2hvdHM6ICAgICAgICEhbWFyaW9uZXR0ZUNsaWVudCxcbiAgICAgICAgICAgIGhhc1Jlc2l6ZVdpbmRvdzogICAgICAgICAgICAgICAgISFtYXJpb25ldHRlQ2xpZW50ICYmIGNvbmZpZy5oZWFkbGVzcyxcbiAgICAgICAgICAgIGhhc01heGltaXplV2luZG93OiAgICAgICAgICAgICAgISFtYXJpb25ldHRlQ2xpZW50ICYmIGNvbmZpZy5oZWFkbGVzcyxcbiAgICAgICAgICAgIGhhc0NhblJlc2l6ZVdpbmRvd1RvRGltZW5zaW9uczogZmFsc2VcbiAgICAgICAgfTtcbiAgICB9XG59O1xuIl19 diff --git a/lib/browser/provider/built-in/firefox/local-firefox.js b/lib/browser/provider/built-in/firefox/local-firefox.js new file mode 100644 index 00000000..e99fc7fa --- /dev/null +++ b/lib/browser/provider/built-in/firefox/local-firefox.js @@ -0,0 +1,72 @@ +'use strict'; + +exports.__esModule = true; +exports.stop = exports.start = undefined; + +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +let start = exports.start = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (pageUrl, runtimeInfo) { + const browserName = runtimeInfo.browserName, + config = runtimeInfo.config; + + + const firefoxInfo = yield _testcafeBrowserTools2.default.getBrowserInfo(config.path || browserName); + const firefoxOpenParameters = (0, _assign2.default)({}, firefoxInfo); + + if (_osFamily2.default.mac && !config.userProfile) correctOpenParametersForMac(firefoxOpenParameters); + + firefoxOpenParameters.cmd = buildFirefoxArgs(config, firefoxOpenParameters.cmd, runtimeInfo, runtimeInfo.newInstance); + + yield browserStarter.startBrowser(firefoxOpenParameters, pageUrl); + }); + + return function start(_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); + +let stop = exports.stop = (() => { + var _ref2 = (0, _asyncToGenerator3.default)(function* ({ browserId }) { + yield (0, _process.killBrowserProcess)(browserId); + }); + + return function stop(_x3) { + return _ref2.apply(this, arguments); + }; +})(); + +var _osFamily = require('os-family'); + +var _osFamily2 = _interopRequireDefault(_osFamily); + +var _testcafeBrowserTools = require('testcafe-browser-tools'); + +var _testcafeBrowserTools2 = _interopRequireDefault(_testcafeBrowserTools); + +var _process = require('../../../../utils/process'); + +var _browserStarter = require('../../utils/browser-starter'); + +var _browserStarter2 = _interopRequireDefault(_browserStarter); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const browserStarter = new _browserStarter2.default(); + +function correctOpenParametersForMac(parameters) { + parameters.macOpenCmdTemplate = parameters.macOpenCmdTemplate.replace('open', 'open -n').replace(' {{{pageUrl}}}', ''); + + parameters.macOpenCmdTemplate += ' {{{pageUrl}}}'; +} + +function buildFirefoxArgs(config, platformArgs, { marionettePort, tempProfileDir }) { + return [].concat(marionettePort ? ['-marionette'] : [], !config.userProfile ? ['-no-remote', '-new-instance', `-profile "${tempProfileDir.path}"`] : [], config.headless ? ['-headless'] : [], config.userArgs ? [config.userArgs] : [], platformArgs ? [platformArgs] : []).join(' '); +} +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvbG9jYWwtZmlyZWZveC5qcyJdLCJuYW1lcyI6WyJwYWdlVXJsIiwicnVudGltZUluZm8iLCJicm93c2VyTmFtZSIsImNvbmZpZyIsImZpcmVmb3hJbmZvIiwiYnJvd3NlclRvb2xzIiwiZ2V0QnJvd3NlckluZm8iLCJwYXRoIiwiZmlyZWZveE9wZW5QYXJhbWV0ZXJzIiwiT1MiLCJtYWMiLCJ1c2VyUHJvZmlsZSIsImNvcnJlY3RPcGVuUGFyYW1ldGVyc0Zvck1hYyIsImNtZCIsImJ1aWxkRmlyZWZveEFyZ3MiLCJuZXdJbnN0YW5jZSIsImJyb3dzZXJTdGFydGVyIiwic3RhcnRCcm93c2VyIiwic3RhcnQiLCJicm93c2VySWQiLCJzdG9wIiwiQnJvd3NlclN0YXJ0ZXIiLCJwYXJhbWV0ZXJzIiwibWFjT3BlbkNtZFRlbXBsYXRlIiwicmVwbGFjZSIsInBsYXRmb3JtQXJncyIsIm1hcmlvbmV0dGVQb3J0IiwidGVtcFByb2ZpbGVEaXIiLCJjb25jYXQiLCJoZWFkbGVzcyIsInVzZXJBcmdzIiwiam9pbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7K0NBNEJPLFdBQXNCQSxPQUF0QixFQUErQkMsV0FBL0IsRUFBNEM7QUFBQSxjQUN2Q0MsV0FEdUMsR0FDZkQsV0FEZSxDQUN2Q0MsV0FEdUM7QUFBQSxjQUMxQkMsTUFEMEIsR0FDZkYsV0FEZSxDQUMxQkUsTUFEMEI7OztBQUcvQyxjQUFNQyxjQUF3QixNQUFNQywrQkFBYUMsY0FBYixDQUE0QkgsT0FBT0ksSUFBUCxJQUFlTCxXQUEzQyxDQUFwQztBQUNBLGNBQU1NLHdCQUF3QixzQkFBYyxFQUFkLEVBQWtCSixXQUFsQixDQUE5Qjs7QUFFQSxZQUFJSyxtQkFBR0MsR0FBSCxJQUFVLENBQUNQLE9BQU9RLFdBQXRCLEVBQ0lDLDRCQUE0QkoscUJBQTVCOztBQUVKQSw4QkFBc0JLLEdBQXRCLEdBQTRCQyxpQkFBaUJYLE1BQWpCLEVBQXlCSyxzQkFBc0JLLEdBQS9DLEVBQW9EWixXQUFwRCxFQUFpRUEsWUFBWWMsV0FBN0UsQ0FBNUI7O0FBRUEsY0FBTUMsZUFBZUMsWUFBZixDQUE0QlQscUJBQTVCLEVBQW1EUixPQUFuRCxDQUFOO0FBQ0gsSzs7b0JBWnFCa0IsSzs7Ozs7O2dEQWNmLFdBQXFCLEVBQUVDLFNBQUYsRUFBckIsRUFBb0M7QUFDdkMsY0FBTSxpQ0FBbUJBLFNBQW5CLENBQU47QUFDSCxLOztvQkFGcUJDLEk7Ozs7O0FBMUN0Qjs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7OztBQUdBLE1BQU1KLGlCQUFpQixJQUFJSyx3QkFBSixFQUF2Qjs7QUFFQSxTQUFTVCwyQkFBVCxDQUFzQ1UsVUFBdEMsRUFBa0Q7QUFDOUNBLGVBQVdDLGtCQUFYLEdBQWdDRCxXQUFXQyxrQkFBWCxDQUMzQkMsT0FEMkIsQ0FDbkIsTUFEbUIsRUFDWCxTQURXLEVBRTNCQSxPQUYyQixDQUVuQixnQkFGbUIsRUFFRCxFQUZDLENBQWhDOztBQUlBRixlQUFXQyxrQkFBWCxJQUFpQyxnQkFBakM7QUFDSDs7QUFFRCxTQUFTVCxnQkFBVCxDQUEyQlgsTUFBM0IsRUFBbUNzQixZQUFuQyxFQUFpRCxFQUFFQyxjQUFGLEVBQWtCQyxjQUFsQixFQUFqRCxFQUFxRjtBQUNqRixXQUFPLEdBQ0ZDLE1BREUsQ0FFQ0YsaUJBQWlCLENBQUMsYUFBRCxDQUFqQixHQUFtQyxFQUZwQyxFQUdDLENBQUN2QixPQUFPUSxXQUFSLEdBQXNCLENBQUMsWUFBRCxFQUFlLGVBQWYsRUFBaUMsYUFBWWdCLGVBQWVwQixJQUFLLEdBQWpFLENBQXRCLEdBQTZGLEVBSDlGLEVBSUNKLE9BQU8wQixRQUFQLEdBQWtCLENBQUMsV0FBRCxDQUFsQixHQUFrQyxFQUpuQyxFQUtDMUIsT0FBTzJCLFFBQVAsR0FBa0IsQ0FBQzNCLE9BQU8yQixRQUFSLENBQWxCLEdBQXNDLEVBTHZDLEVBTUNMLGVBQWUsQ0FBQ0EsWUFBRCxDQUFmLEdBQWdDLEVBTmpDLEVBUUZNLElBUkUsQ0FRRyxHQVJILENBQVA7QUFTSCIsImZpbGUiOiJicm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvbG9jYWwtZmlyZWZveC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBPUyBmcm9tICdvcy1mYW1pbHknO1xuaW1wb3J0IGJyb3dzZXJUb29scyBmcm9tICd0ZXN0Y2FmZS1icm93c2VyLXRvb2xzJztcbmltcG9ydCB7IGtpbGxCcm93c2VyUHJvY2VzcyB9IGZyb20gJy4uLy4uLy4uLy4uL3V0aWxzL3Byb2Nlc3MnO1xuaW1wb3J0IEJyb3dzZXJTdGFydGVyIGZyb20gJy4uLy4uL3V0aWxzL2Jyb3dzZXItc3RhcnRlcic7XG5cblxuY29uc3QgYnJvd3NlclN0YXJ0ZXIgPSBuZXcgQnJvd3NlclN0YXJ0ZXIoKTtcblxuZnVuY3Rpb24gY29ycmVjdE9wZW5QYXJhbWV0ZXJzRm9yTWFjIChwYXJhbWV0ZXJzKSB7XG4gICAgcGFyYW1ldGVycy5tYWNPcGVuQ21kVGVtcGxhdGUgPSBwYXJhbWV0ZXJzLm1hY09wZW5DbWRUZW1wbGF0ZVxuICAgICAgICAucmVwbGFjZSgnb3BlbicsICdvcGVuIC1uJylcbiAgICAgICAgLnJlcGxhY2UoJyB7e3twYWdlVXJsfX19JywgJycpO1xuXG4gICAgcGFyYW1ldGVycy5tYWNPcGVuQ21kVGVtcGxhdGUgKz0gJyB7e3twYWdlVXJsfX19Jztcbn1cblxuZnVuY3Rpb24gYnVpbGRGaXJlZm94QXJncyAoY29uZmlnLCBwbGF0Zm9ybUFyZ3MsIHsgbWFyaW9uZXR0ZVBvcnQsIHRlbXBQcm9maWxlRGlyIH0pIHtcbiAgICByZXR1cm4gW11cbiAgICAgICAgLmNvbmNhdChcbiAgICAgICAgICAgIG1hcmlvbmV0dGVQb3J0ID8gWyctbWFyaW9uZXR0ZSddIDogW10sXG4gICAgICAgICAgICAhY29uZmlnLnVzZXJQcm9maWxlID8gWyctbm8tcmVtb3RlJywgJy1uZXctaW5zdGFuY2UnLCBgLXByb2ZpbGUgXCIke3RlbXBQcm9maWxlRGlyLnBhdGh9XCJgXSA6IFtdLFxuICAgICAgICAgICAgY29uZmlnLmhlYWRsZXNzID8gWyctaGVhZGxlc3MnXSA6IFtdLFxuICAgICAgICAgICAgY29uZmlnLnVzZXJBcmdzID8gW2NvbmZpZy51c2VyQXJnc10gOiBbXSxcbiAgICAgICAgICAgIHBsYXRmb3JtQXJncyA/IFtwbGF0Zm9ybUFyZ3NdIDogW11cbiAgICAgICAgKVxuICAgICAgICAuam9pbignICcpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnQgKHBhZ2VVcmwsIHJ1bnRpbWVJbmZvKSB7XG4gICAgY29uc3QgeyBicm93c2VyTmFtZSwgY29uZmlnIH0gPSBydW50aW1lSW5mbztcblxuICAgIGNvbnN0IGZpcmVmb3hJbmZvICAgICAgICAgICA9IGF3YWl0IGJyb3dzZXJUb29scy5nZXRCcm93c2VySW5mbyhjb25maWcucGF0aCB8fCBicm93c2VyTmFtZSk7XG4gICAgY29uc3QgZmlyZWZveE9wZW5QYXJhbWV0ZXJzID0gT2JqZWN0LmFzc2lnbih7fSwgZmlyZWZveEluZm8pO1xuXG4gICAgaWYgKE9TLm1hYyAmJiAhY29uZmlnLnVzZXJQcm9maWxlKVxuICAgICAgICBjb3JyZWN0T3BlblBhcmFtZXRlcnNGb3JNYWMoZmlyZWZveE9wZW5QYXJhbWV0ZXJzKTtcblxuICAgIGZpcmVmb3hPcGVuUGFyYW1ldGVycy5jbWQgPSBidWlsZEZpcmVmb3hBcmdzKGNvbmZpZywgZmlyZWZveE9wZW5QYXJhbWV0ZXJzLmNtZCwgcnVudGltZUluZm8sIHJ1bnRpbWVJbmZvLm5ld0luc3RhbmNlKTtcblxuICAgIGF3YWl0IGJyb3dzZXJTdGFydGVyLnN0YXJ0QnJvd3NlcihmaXJlZm94T3BlblBhcmFtZXRlcnMsIHBhZ2VVcmwpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RvcCAoeyBicm93c2VySWQgfSkge1xuICAgIGF3YWl0IGtpbGxCcm93c2VyUHJvY2Vzcyhicm93c2VySWQpO1xufVxuIl19 diff --git a/lib/browser/provider/built-in/firefox/marionette-client/commands.js b/lib/browser/provider/built-in/firefox/marionette-client/commands.js new file mode 100644 index 00000000..61e6fc39 --- /dev/null +++ b/lib/browser/provider/built-in/firefox/marionette-client/commands.js @@ -0,0 +1,13 @@ +'use strict'; + +exports.__esModule = true; +exports.default = { + newSession: 'WebDriver:NewSession', + executeScript: 'WebDriver:ExecuteScript', + takeScreenshot: 'WebDriver:TakeScreenshot', + getWindowRect: 'WebDriver:GetWindowRect', + setWindowRect: 'WebDriver:SetWindowRect', + quit: 'Marionette:Quit' +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvbWFyaW9uZXR0ZS1jbGllbnQvY29tbWFuZHMuanMiXSwibmFtZXMiOlsibmV3U2Vzc2lvbiIsImV4ZWN1dGVTY3JpcHQiLCJ0YWtlU2NyZWVuc2hvdCIsImdldFdpbmRvd1JlY3QiLCJzZXRXaW5kb3dSZWN0IiwicXVpdCJdLCJtYXBwaW5ncyI6Ijs7O2tCQUFlO0FBQ1hBLGdCQUFnQixzQkFETDtBQUVYQyxtQkFBZ0IseUJBRkw7QUFHWEMsb0JBQWdCLDBCQUhMO0FBSVhDLG1CQUFnQix5QkFKTDtBQUtYQyxtQkFBZ0IseUJBTEw7QUFNWEMsVUFBZ0I7QUFOTCxDIiwiZmlsZSI6ImJyb3dzZXIvcHJvdmlkZXIvYnVpbHQtaW4vZmlyZWZveC9tYXJpb25ldHRlLWNsaWVudC9jb21tYW5kcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IHtcbiAgICBuZXdTZXNzaW9uOiAgICAgJ1dlYkRyaXZlcjpOZXdTZXNzaW9uJyxcbiAgICBleGVjdXRlU2NyaXB0OiAgJ1dlYkRyaXZlcjpFeGVjdXRlU2NyaXB0JyxcbiAgICB0YWtlU2NyZWVuc2hvdDogJ1dlYkRyaXZlcjpUYWtlU2NyZWVuc2hvdCcsXG4gICAgZ2V0V2luZG93UmVjdDogICdXZWJEcml2ZXI6R2V0V2luZG93UmVjdCcsXG4gICAgc2V0V2luZG93UmVjdDogICdXZWJEcml2ZXI6U2V0V2luZG93UmVjdCcsXG4gICAgcXVpdDogICAgICAgICAgICdNYXJpb25ldHRlOlF1aXQnXG59O1xuIl19 diff --git a/lib/browser/provider/built-in/firefox/marionette-client/index.js b/lib/browser/provider/built-in/firefox/marionette-client/index.js new file mode 100644 index 00000000..0cdc7455 --- /dev/null +++ b/lib/browser/provider/built-in/firefox/marionette-client/index.js @@ -0,0 +1,268 @@ +'use strict'; + +var _stringify = require('babel-runtime/core-js/json/stringify'); + +var _stringify2 = _interopRequireDefault(_stringify); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _pinkie = require('pinkie'); + +var _pinkie2 = _interopRequireDefault(_pinkie); + +var _net = require('net'); + +var _promisifyEvent = require('promisify-event'); + +var _promisifyEvent2 = _interopRequireDefault(_promisifyEvent); + +var _events = require('events'); + +var _events2 = _interopRequireDefault(_events); + +var _promisifiedFunctions = require('../../../../../utils/promisified-functions'); + +var _delay = require('../../../../../utils/delay'); + +var _delay2 = _interopRequireDefault(_delay); + +var _clientFunctions = require('../../../utils/client-functions'); + +var _commands = require('./commands'); + +var _commands2 = _interopRequireDefault(_commands); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const CONNECTION_TIMEOUT = 30000; +const CONNECTION_RETRY_DELAY = 300; +const MAX_RESIZE_RETRY_COUNT = 2; +const HEADER_SEPARATOR = ':'; + +module.exports = class MarionetteClient { + constructor(port = 2828, host = '127.0.0.1') { + this.currentPacketNumber = 1; + this.events = new _events2.default(); + this.port = port; + this.host = host; + this.socket = new _net.Socket(); + this.buffer = Buffer.alloc(0); + this.getPacketPromise = _pinkie2.default.resolve(); + this.sendPacketPromise = _pinkie2.default.resolve(); + + this.protocolInfo = { + applicationType: '', + marionetteProtocol: '' + }; + + this.sessionInfo = null; + } + + _attemptToConnect(port, host) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this.socket.connect(port, host); + + const connectionPromise = _pinkie2.default.race([(0, _promisifyEvent2.default)(_this.socket, 'connect'), (0, _promisifyEvent2.default)(_this.socket, 'error')]); + + return yield connectionPromise.then(function () { + return true; + }).catch(function () { + _this.socket.removeAllListeners('connect'); + return (0, _delay2.default)(CONNECTION_RETRY_DELAY); + }); + })(); + } + + _connectSocket(port, host) { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const connectionStartTime = Date.now(); + + let connected = yield _this2._attemptToConnect(port, host); + + while (!connected && Date.now() - connectionStartTime < CONNECTION_TIMEOUT) connected = yield _this2._attemptToConnect(port, host); + + if (!connected) throw new Error('Unable to connect'); + + _this2.socket.on('data', function (data) { + return _this2._handleNewData(data); + }); + })(); + } + + _writeSocket(message) { + var _this3 = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (!_this3.socket.write(message)) yield (0, _promisifyEvent2.default)(_this3.socket, 'drain'); + })(); + } + + _handleNewData(data) { + if (!data) return; + + this.buffer = Buffer.concat([this.buffer, data]); + + this.events.emit('new-data'); + } + + _getPacket() { + var _this4 = this; + + this.getPacketPromise = this.getPacketPromise.then((0, _asyncToGenerator3.default)(function* () { + let headerEndIndex = _this4.buffer.indexOf(HEADER_SEPARATOR); + + while (headerEndIndex < 0) { + yield (0, _promisifyEvent2.default)(_this4.events, 'new-data'); + + headerEndIndex = _this4.buffer.indexOf(HEADER_SEPARATOR); + } + + const packet = { + length: NaN, + body: null + }; + + packet.length = parseInt(_this4.buffer.toString('utf8', 0, headerEndIndex), 10) || 0; + + const bodyStartIndex = headerEndIndex + HEADER_SEPARATOR.length; + const bodyEndIndex = bodyStartIndex + packet.length; + + if (packet.length) { + while (_this4.buffer.length < bodyEndIndex) yield (0, _promisifyEvent2.default)(_this4.events, 'new-data'); + + packet.body = JSON.parse(_this4.buffer.toString('utf8', bodyStartIndex, bodyEndIndex)); + } + + _this4.buffer = _this4.buffer.slice(bodyEndIndex); + + return packet; + })); + + return this.getPacketPromise; + } + + _sendPacket(payload) { + var _this5 = this; + + this.sendPacketPromise = this.sendPacketPromise.then((0, _asyncToGenerator3.default)(function* () { + const body = [0, _this5.currentPacketNumber++, payload.command, payload.parameters]; + const serialized = (0, _stringify2.default)(body); + const message = Buffer.byteLength(serialized, 'utf8') + HEADER_SEPARATOR + serialized; + + _this5._writeSocket(message); + })); + + return this.sendPacketPromise; + } + + _throwMarionetteError(error) { + throw new Error(`${error.error}${error.message ? ': ' + error.message : ''}`); + } + + _getResponse(packet) { + var _this6 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const packetNumber = _this6.currentPacketNumber; + + yield _this6._sendPacket(packet); + + let responsePacket = yield _this6._getPacket(); + + while (!responsePacket.body || responsePacket.body[1] !== packetNumber) responsePacket = yield _this6._getPacket(); + + if (responsePacket.body[2]) _this6._throwMarionetteError(responsePacket.body[2]); + + return responsePacket.body[3]; + })(); + } + + connect() { + var _this7 = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _this7._connectSocket(_this7.port, _this7.host); + + const infoPacket = yield _this7._getPacket(); + + _this7.protocolInfo = { + applicationType: infoPacket.body.applicationType, + marionetteProtocol: infoPacket.body.marionetteProtocol + }; + + _this7.sessionInfo = yield _this7._getResponse({ command: _commands2.default.newSession }); + })(); + } + + dispose() { + this.socket.end(); + this.buffer = null; + } + + executeScript(code) { + var _this8 = this; + + return (0, _asyncToGenerator3.default)(function* () { + return yield _this8._getResponse({ + command: _commands2.default.executeScript, + parameters: { script: `return (${code})()` } + }); + })(); + } + + takeScreenshot(path) { + var _this9 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const screenshot = yield _this9._getResponse({ command: _commands2.default.takeScreenshot }); + + yield (0, _promisifiedFunctions.writeFile)(path, screenshot.value, { encoding: 'base64' }); + })(); + } + + setWindowSize(width, height) { + var _this10 = this; + + return (0, _asyncToGenerator3.default)(function* () { + var _ref3 = yield _this10.executeScript(_clientFunctions.GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + + let pageRect = _ref3.value; + + let attemptCounter = 0; + + while (attemptCounter++ < MAX_RESIZE_RETRY_COUNT && (pageRect.width !== width || pageRect.height !== height)) { + const currentRect = yield _this10._getResponse({ command: _commands2.default.getWindowRect }); + + yield _this10._getResponse({ + command: _commands2.default.setWindowRect, + + parameters: { + x: currentRect.x, + y: currentRect.y, + width: width + (currentRect.width - pageRect.width), + height: height + (currentRect.height - pageRect.height) + } + }); + + var _ref4 = yield _this10.executeScript(_clientFunctions.GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + + pageRect = _ref4.value; + } + })(); + } + + quit() { + var _this11 = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _this11._getResponse({ command: _commands2.default.quit }); + })(); + } +}; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvbWFyaW9uZXR0ZS1jbGllbnQvaW5kZXguanMiXSwibmFtZXMiOlsiQ09OTkVDVElPTl9USU1FT1VUIiwiQ09OTkVDVElPTl9SRVRSWV9ERUxBWSIsIk1BWF9SRVNJWkVfUkVUUllfQ09VTlQiLCJIRUFERVJfU0VQQVJBVE9SIiwibW9kdWxlIiwiZXhwb3J0cyIsIk1hcmlvbmV0dGVDbGllbnQiLCJjb25zdHJ1Y3RvciIsInBvcnQiLCJob3N0IiwiY3VycmVudFBhY2tldE51bWJlciIsImV2ZW50cyIsIkV2ZW50RW1pdHRlciIsInNvY2tldCIsIlNvY2tldCIsImJ1ZmZlciIsIkJ1ZmZlciIsImFsbG9jIiwiZ2V0UGFja2V0UHJvbWlzZSIsIlByb21pc2UiLCJyZXNvbHZlIiwic2VuZFBhY2tldFByb21pc2UiLCJwcm90b2NvbEluZm8iLCJhcHBsaWNhdGlvblR5cGUiLCJtYXJpb25ldHRlUHJvdG9jb2wiLCJzZXNzaW9uSW5mbyIsIl9hdHRlbXB0VG9Db25uZWN0IiwiY29ubmVjdCIsImNvbm5lY3Rpb25Qcm9taXNlIiwicmFjZSIsInRoZW4iLCJjYXRjaCIsInJlbW92ZUFsbExpc3RlbmVycyIsIl9jb25uZWN0U29ja2V0IiwiY29ubmVjdGlvblN0YXJ0VGltZSIsIkRhdGUiLCJub3ciLCJjb25uZWN0ZWQiLCJFcnJvciIsIm9uIiwiX2hhbmRsZU5ld0RhdGEiLCJkYXRhIiwiX3dyaXRlU29ja2V0IiwibWVzc2FnZSIsIndyaXRlIiwiY29uY2F0IiwiZW1pdCIsIl9nZXRQYWNrZXQiLCJoZWFkZXJFbmRJbmRleCIsImluZGV4T2YiLCJwYWNrZXQiLCJsZW5ndGgiLCJOYU4iLCJib2R5IiwicGFyc2VJbnQiLCJ0b1N0cmluZyIsImJvZHlTdGFydEluZGV4IiwiYm9keUVuZEluZGV4IiwiSlNPTiIsInBhcnNlIiwic2xpY2UiLCJfc2VuZFBhY2tldCIsInBheWxvYWQiLCJjb21tYW5kIiwicGFyYW1ldGVycyIsInNlcmlhbGl6ZWQiLCJieXRlTGVuZ3RoIiwiX3Rocm93TWFyaW9uZXR0ZUVycm9yIiwiZXJyb3IiLCJfZ2V0UmVzcG9uc2UiLCJwYWNrZXROdW1iZXIiLCJyZXNwb25zZVBhY2tldCIsImluZm9QYWNrZXQiLCJDT01NQU5EUyIsIm5ld1Nlc3Npb24iLCJkaXNwb3NlIiwiZW5kIiwiZXhlY3V0ZVNjcmlwdCIsImNvZGUiLCJzY3JpcHQiLCJ0YWtlU2NyZWVuc2hvdCIsInBhdGgiLCJzY3JlZW5zaG90IiwidmFsdWUiLCJlbmNvZGluZyIsInNldFdpbmRvd1NpemUiLCJ3aWR0aCIsImhlaWdodCIsIkdFVF9XSU5ET1dfRElNRU5TSU9OU19JTkZPX1NDUklQVCIsInBhZ2VSZWN0IiwiYXR0ZW1wdENvdW50ZXIiLCJjdXJyZW50UmVjdCIsImdldFdpbmRvd1JlY3QiLCJzZXRXaW5kb3dSZWN0IiwieCIsInkiLCJxdWl0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUE7Ozs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7Ozs7O0FBR0EsTUFBTUEscUJBQXlCLEtBQS9CO0FBQ0EsTUFBTUMseUJBQXlCLEdBQS9CO0FBQ0EsTUFBTUMseUJBQXlCLENBQS9CO0FBQ0EsTUFBTUMsbUJBQXlCLEdBQS9COztBQUVBQyxPQUFPQyxPQUFQLEdBQWlCLE1BQU1DLGdCQUFOLENBQXVCO0FBQ3BDQyxnQkFBYUMsT0FBTyxJQUFwQixFQUEwQkMsT0FBTyxXQUFqQyxFQUE4QztBQUMxQyxhQUFLQyxtQkFBTCxHQUEyQixDQUEzQjtBQUNBLGFBQUtDLE1BQUwsR0FBMkIsSUFBSUMsZ0JBQUosRUFBM0I7QUFDQSxhQUFLSixJQUFMLEdBQTJCQSxJQUEzQjtBQUNBLGFBQUtDLElBQUwsR0FBMkJBLElBQTNCO0FBQ0EsYUFBS0ksTUFBTCxHQUEyQixJQUFJQyxXQUFKLEVBQTNCO0FBQ0EsYUFBS0MsTUFBTCxHQUEyQkMsT0FBT0Ms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LFlBQUwsQ0FBa0I7QUFDcEJOLDZCQUFTVSxtQkFBU29CLGFBREU7O0FBR3BCN0IsZ0NBQVk7QUFDUjhCLDJCQUFRSCxZQUFZRyxDQURaO0FBRVJDLDJCQUFRSixZQUFZSSxDQUZaO0FBR1JULCtCQUFRQSxTQUFTSyxZQUFZTCxLQUFaLEdBQW9CRyxTQUFTSCxLQUF0QyxDQUhBO0FBSVJDLGdDQUFRQSxVQUFVSSxZQUFZSixNQUFaLEdBQXFCRSxTQUFTRixNQUF4QztBQUpBO0FBSFEsaUJBQWxCLENBQU47O0FBSDBHLDRCQWNuRixNQUFNLFFBQUtWLGFBQUwsQ0FBbUJXLGtEQUFuQixDQWQ2RTs7QUFjaEdDLHdCQWRnRyxTQWN2R04sS0FkdUc7QUFlN0c7QUFuQitCO0FBb0JuQzs7QUFFS2EsUUFBTixHQUFjO0FBQUE7O0FBQUE7QUFDVixrQkFBTSxRQUFLM0IsWUFBTCxDQUFrQixFQUFFTixTQUFTVSxtQkFBU3VCLElBQXBCLEVBQWxCLENBQU47QUFEVTtBQUViO0FBekxtQyxDQUF4QyIsImZpbGUiOiJicm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvbWFyaW9uZXR0ZS1jbGllbnQvaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUHJvbWlzZSBmcm9tICdwaW5raWUnO1xuaW1wb3J0IHsgU29ja2V0IH0gZnJvbSAnbmV0JztcbmltcG9ydCBwcm9taXNpZnlFdmVudCBmcm9tICdwcm9taXNpZnktZXZlbnQnO1xuaW1wb3J0IEV2ZW50RW1pdHRlciBmcm9tICdldmVudHMnO1xuaW1wb3J0IHsgd3JpdGVGaWxlIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vdXRpbHMvcHJvbWlzaWZpZWQtZnVuY3Rpb25zJztcbmltcG9ydCBkZWxheSBmcm9tICcuLi8uLi8uLi8uLi8uLi91dGlscy9kZWxheSc7XG5pbXBvcnQgeyBHRVRfV0lORE9XX0RJTUVOU0lPTlNfSU5GT19TQ1JJUFQgfSBmcm9tICcuLi8uLi8uLi91dGlscy9jbGllbnQtZnVuY3Rpb25zJztcbmltcG9ydCBDT01NQU5EUyBmcm9tICcuL2NvbW1hbmRzJztcblxuXG5jb25zdCBDT05ORUNUSU9OX1RJTUVPVVQgICAgID0gMzAwMDA7XG5jb25zdCBDT05ORUNUSU9OX1JFVFJZX0RFTEFZID0gMzAwO1xuY29uc3QgTUFYX1JFU0laRV9SRVRSWV9DT1VOVCA9IDI7XG5jb25zdCBIRUFERVJfU0VQQVJBVE9SICAgICAgID0gJzonO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNsYXNzIE1hcmlvbmV0dGVDbGllbnQge1xuICAgIGNvbnN0cnVjdG9yIChwb3J0ID0gMjgyOCwgaG9zdCA9ICcxMjcuMC4wLjEnKSB7XG4gICAgICAgIHRoaXMuY3VycmVudFBhY2tldE51bWJlciA9IDE7XG4gICAgICAgIHRoaXMuZXZlbnRzICAgICAgICAgICAgICA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAgICAgdGhpcy5wb3J0ICAgICAgICAgICAgICAgID0gcG9ydDtcbiAgICAgICAgdGhpcy5ob3N0ICAgICAgICAgICAgICAgID0gaG9zdDtcbiAgICAgICAgdGhpcy5zb2NrZXQgICAgICAgICAgICAgID0gbmV3IFNvY2tldCgpO1xuICAgICAgICB0aGlzLmJ1ZmZlciAgICAgICAgICAgICAgPSBCdWZmZXIuYWxsb2MoMCk7XG4gICAgICAgIHRoaXMuZ2V0UGFja2V0UHJvbWlzZSAgICA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB0aGlzLnNlbmRQYWNrZXRQcm9taXNlICAgPSBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgICAgICB0aGlzLnByb3RvY29sSW5mbyA9IHtcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uVHlwZTogICAgJycsXG4gICAgICAgICAgICBtYXJpb25ldHRlUHJvdG9jb2w6ICcnLFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbkluZm8gPSBudWxsO1xuICAgIH1cblxuICAgIGFzeW5jIF9hdHRlbXB0VG9Db25uZWN0IChwb3J0LCBob3N0KSB7XG4gICAgICAgIHRoaXMuc29ja2V0LmNvbm5lY3QocG9ydCwgaG9zdCk7XG5cbiAgICAgICAgY29uc3QgY29ubmVjdGlvblByb21pc2UgPSBQcm9taXNlLnJhY2UoW1xuICAgICAgICAgICAgcHJvbWlzaWZ5RXZlbnQodGhpcy5zb2NrZXQsICdjb25uZWN0JyksXG4gICAgICAgICAgICBwcm9taXNpZnlFdmVudCh0aGlzLnNvY2tldCwgJ2Vycm9yJylcbiAgICAgICAgXSk7XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IGNvbm5lY3Rpb25Qcm9taXNlXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0cnVlKVxuICAgICAgICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNvY2tldC5yZW1vdmVBbGxMaXN0ZW5lcnMoJ2Nvbm5lY3QnKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVsYXkoQ09OTkVDVElPTl9SRVRSWV9ERUxBWSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBfY29ubmVjdFNvY2tldCAocG9ydCwgaG9zdCkge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9uU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICBsZXQgY29ubmVjdGVkID0gYXdhaXQgdGhpcy5fYXR0ZW1wdFRvQ29ubmVjdChwb3J0LCBob3N0KTtcblxuICAgICAgICB3aGlsZSAoIWNvbm5lY3RlZCAmJiBEYXRlLm5vdygpIC0gY29ubmVjdGlvblN0YXJ0VGltZSA8IENPTk5FQ1RJT05fVElNRU9VVClcbiAgICAgICAgICAgIGNvbm5lY3RlZCA9IGF3YWl0IHRoaXMuX2F0dGVtcHRUb0Nvbm5lY3QocG9ydCwgaG9zdCk7XG5cbiAgICAgICAgaWYgKCFjb25uZWN0ZWQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBjb25uZWN0Jyk7XG5cbiAgICAgICAgdGhpcy5zb2NrZXQub24oJ2RhdGEnLCBkYXRhID0+IHRoaXMuX2hhbmRsZU5ld0RhdGEoZGF0YSkpO1xuICAgIH1cblxuICAgIGFzeW5jIF93cml0ZVNvY2tldCAobWVzc2FnZSkge1xuICAgICAgICBpZiAoIXRoaXMuc29ja2V0LndyaXRlKG1lc3NhZ2UpKVxuICAgICAgICAgICAgYXdhaXQgcHJvbWlzaWZ5RXZlbnQodGhpcy5zb2NrZXQsICdkcmFpbicpO1xuICAgIH1cblxuICAgIF9oYW5kbGVOZXdEYXRhIChkYXRhKSB7XG4gICAgICAgIGlmICghZGF0YSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0aGlzLmJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuYnVmZmVyLCBkYXRhXSk7XG5cbiAgICAgICAgdGhpcy5ldmVudHMuZW1pdCgnbmV3LWRhdGEnKTtcbiAgICB9XG5cbiAgICBfZ2V0UGFja2V0ICgpIHtcbiAgICAgICAgdGhpcy5nZXRQYWNrZXRQcm9taXNlID0gdGhpcy5nZXRQYWNrZXRQcm9taXNlLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgbGV0IGhlYWRlckVuZEluZGV4ID0gdGhpcy5idWZmZXIuaW5kZXhPZihIRUFERVJfU0VQQVJBVE9SKTtcblxuICAgICAgICAgICAgd2hpbGUgKGhlYWRlckVuZEluZGV4IDwgMCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHByb21pc2lmeUV2ZW50KHRoaXMuZXZlbnRzLCAnbmV3LWRhdGEnKTtcblxuICAgICAgICAgICAgICAgIGhlYWRlckVuZEluZGV4ID0gdGhpcy5idWZmZXIuaW5kZXhPZihIRUFERVJfU0VQQVJBVE9SKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcGFja2V0ID0ge1xuICAgICAgICAgICAgICAgIGxlbmd0aDogTmFOLFxuICAgICAgICAgICAgICAgIGJvZHk6ICAgbnVsbFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcGFja2V0Lmxlbmd0aCA9IHBhcnNlSW50KHRoaXMuYnVmZmVyLnRvU3RyaW5nKCd1dGY4JywgMCwgaGVhZGVyRW5kSW5kZXgpLCAxMCkgfHwgMDtcblxuICAgICAgICAgICAgY29uc3QgYm9keVN0YXJ0SW5kZXggPSBoZWFkZXJFbmRJbmRleCArIEhFQURFUl9TRVBBUkFUT1IubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgYm9keUVuZEluZGV4ICAgPSBib2R5U3RhcnRJbmRleCArIHBhY2tldC5sZW5ndGg7XG5cbiAgICAgICAgICAgIGlmIChwYWNrZXQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHRoaXMuYnVmZmVyLmxlbmd0aCA8IGJvZHlFbmRJbmRleClcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgcHJvbWlzaWZ5RXZlbnQodGhpcy5ldmVudHMsICduZXctZGF0YScpO1xuXG4gICAgICAgICAgICAgICAgcGFja2V0LmJvZHkgPSBKU09OLnBhcnNlKHRoaXMuYnVmZmVyLnRvU3RyaW5nKCd1dGY4JywgYm9keVN0YXJ0SW5kZXgsIGJvZHlFbmRJbmRleCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IHRoaXMuYnVmZmVyLnNsaWNlKGJvZHlFbmRJbmRleCk7XG5cbiAgICAgICAgICAgIHJldHVybiBwYWNrZXQ7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tldFByb21pc2U7XG4gICAgfVxuXG4gICAgX3NlbmRQYWNrZXQgKHBheWxvYWQpIHtcbiAgICAgICAgdGhpcy5zZW5kUGFja2V0UHJvbWlzZSA9IHRoaXMuc2VuZFBhY2tldFByb21pc2UudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBib2R5ICAgICAgID0gWzAsIHRoaXMuY3VycmVudFBhY2tldE51bWJlcisrLCBwYXlsb2FkLmNvbW1hbmQsIHBheWxvYWQucGFyYW1ldGVyc107XG4gICAgICAgICAgICBjb25zdCBzZXJpYWxpemVkID0gSlNPTi5zdHJpbmdpZnkoYm9keSk7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlICAgID0gQnVmZmVyLmJ5dGVMZW5ndGgoc2VyaWFsaXplZCwgJ3V0ZjgnKSArIEhFQURFUl9TRVBBUkFUT1IgKyBzZXJpYWxpemVkO1xuXG4gICAgICAgICAgICB0aGlzLl93cml0ZVNvY2tldChtZXNzYWdlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZFBhY2tldFByb21pc2U7XG4gICAgfVxuXG4gICAgX3Rocm93TWFyaW9uZXR0ZUVycm9yIChlcnJvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyb3IuZXJyb3J9JHtlcnJvci5tZXNzYWdlID8gJzogJyArIGVycm9yLm1lc3NhZ2UgOiAnJ31gKTtcbiAgICB9XG5cbiAgICBhc3luYyBfZ2V0UmVzcG9uc2UgKHBhY2tldCkge1xuICAgICAgICBjb25zdCBwYWNrZXROdW1iZXIgPSB0aGlzLmN1cnJlbnRQYWNrZXROdW1iZXI7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fc2VuZFBhY2tldChwYWNrZXQpO1xuXG4gICAgICAgIGxldCByZXNwb25zZVBhY2tldCA9IGF3YWl0IHRoaXMuX2dldFBhY2tldCgpO1xuXG4gICAgICAgIHdoaWxlICghcmVzcG9uc2VQYWNrZXQuYm9keSB8fCByZXNwb25zZVBhY2tldC5ib2R5WzFdICE9PSBwYWNrZXROdW1iZXIpXG4gICAgICAgICAgICByZXNwb25zZVBhY2tldCA9IGF3YWl0IHRoaXMuX2dldFBhY2tldCgpO1xuXG4gICAgICAgIGlmIChyZXNwb25zZVBhY2tldC5ib2R5WzJdKVxuICAgICAgICAgICAgdGhpcy5fdGhyb3dNYXJpb25ldHRlRXJyb3IocmVzcG9uc2VQYWNrZXQuYm9keVsyXSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlUGFja2V0LmJvZHlbM107XG4gICAgfVxuXG4gICAgYXN5bmMgY29ubmVjdCAoKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX2Nvbm5lY3RTb2NrZXQodGhpcy5wb3J0LCB0aGlzLmhvc3QpO1xuXG4gICAgICAgIGNvbnN0IGluZm9QYWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRQYWNrZXQoKTtcblxuICAgICAgICB0aGlzLnByb3RvY29sSW5mbyA9IHtcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uVHlwZTogICAgaW5mb1BhY2tldC5ib2R5LmFwcGxpY2F0aW9uVHlwZSxcbiAgICAgICAgICAgIG1hcmlvbmV0dGVQcm90b2NvbDogaW5mb1BhY2tldC5ib2R5Lm1hcmlvbmV0dGVQcm90b2NvbFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuc2Vzc2lvbkluZm8gPSBhd2FpdCB0aGlzLl9nZXRSZXNwb25zZSh7IGNvbW1hbmQ6IENPTU1BTkRTLm5ld1Nlc3Npb24gfSk7XG4gICAgfVxuXG4gICAgZGlzcG9zZSAoKSB7XG4gICAgICAgIHRoaXMuc29ja2V0LmVuZCgpO1xuICAgICAgICB0aGlzLmJ1ZmZlciA9IG51bGw7XG4gICAgfVxuXG4gICAgYXN5bmMgZXhlY3V0ZVNjcmlwdCAoY29kZSkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fZ2V0UmVzcG9uc2Uoe1xuICAgICAgICAgICAgY29tbWFuZDogICAgQ09NTUFORFMuZXhlY3V0ZVNjcmlwdCxcbiAgICAgICAgICAgIHBhcmFtZXRlcnM6IHsgc2NyaXB0OiBgcmV0dXJuICgke2NvZGV9KSgpYCB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIHRha2VTY3JlZW5zaG90IChwYXRoKSB7XG4gICAgICAgIGNvbnN0IHNjcmVlbnNob3QgPSBhd2FpdCB0aGlzLl9nZXRSZXNwb25zZSh7IGNvbW1hbmQ6IENPTU1BTkRTLnRha2VTY3JlZW5zaG90IH0pO1xuXG4gICAgICAgIGF3YWl0IHdyaXRlRmlsZShwYXRoLCBzY3JlZW5zaG90LnZhbHVlLCB7IGVuY29kaW5nOiAnYmFzZTY0JyB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBzZXRXaW5kb3dTaXplICh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgIGxldCB7IHZhbHVlOiBwYWdlUmVjdCB9ID0gYXdhaXQgdGhpcy5leGVjdXRlU2NyaXB0KEdFVF9XSU5ET1dfRElNRU5TSU9OU19JTkZPX1NDUklQVCk7XG4gICAgICAgIGxldCBhdHRlbXB0Q291bnRlciAgICAgID0gMDtcblxuICAgICAgICB3aGlsZSAoYXR0ZW1wdENvdW50ZXIrKyA8IE1BWF9SRVNJWkVfUkVUUllfQ09VTlQgJiYgKHBhZ2VSZWN0LndpZHRoICE9PSB3aWR0aCB8fCBwYWdlUmVjdC5oZWlnaHQgIT09IGhlaWdodCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRSZWN0ID0gYXdhaXQgdGhpcy5fZ2V0UmVzcG9uc2UoeyBjb21tYW5kOiBDT01NQU5EUy5nZXRXaW5kb3dSZWN0IH0pO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9nZXRSZXNwb25zZSh7XG4gICAgICAgICAgICAgICAgY29tbWFuZDogQ09NTUFORFMuc2V0V2luZG93UmVjdCxcblxuICAgICAgICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgeDogICAgICBjdXJyZW50UmVjdC54LFxuICAgICAgICAgICAgICAgICAgICB5OiAgICAgIGN1cnJlbnRSZWN0LnksXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiAgd2lkdGggKyAoY3VycmVudFJlY3Qud2lkdGggLSBwYWdlUmVjdC53aWR0aCksXG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0ICsgKGN1cnJlbnRSZWN0LmhlaWdodCAtIHBhZ2VSZWN0LmhlaWdodClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgKHsgdmFsdWU6IHBhZ2VSZWN0IH0gPSBhd2FpdCB0aGlzLmV4ZWN1dGVTY3JpcHQoR0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBxdWl0ICgpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5fZ2V0UmVzcG9uc2UoeyBjb21tYW5kOiBDT01NQU5EUy5xdWl0IH0pO1xuICAgIH1cbn07XG5cbiJdfQ== diff --git a/lib/browser/provider/built-in/firefox/runtime-info.js b/lib/browser/provider/built-in/firefox/runtime-info.js new file mode 100644 index 00000000..45d4d24d --- /dev/null +++ b/lib/browser/provider/built-in/firefox/runtime-info.js @@ -0,0 +1,38 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _endpointUtils = require('endpoint-utils'); + +var _config = require('./config'); + +var _config2 = _interopRequireDefault(_config); + +var _createTempProfile = require('./create-temp-profile'); + +var _createTempProfile2 = _interopRequireDefault(_createTempProfile); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (configString) { + const config = (0, _config2.default)(configString); + const marionettePort = config.marionettePort || (!config.userProfile ? yield (0, _endpointUtils.getFreePort)() : null); + const runtimeInfo = { config, marionettePort }; + + runtimeInfo.tempProfileDir = !config.userProfile ? yield (0, _createTempProfile2.default)(runtimeInfo) : null; + + return runtimeInfo; + }); + + return function (_x) { + return _ref.apply(this, arguments); + }; +})(); + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2ZpcmVmb3gvcnVudGltZS1pbmZvLmpzIl0sIm5hbWVzIjpbImNvbmZpZ1N0cmluZyIsImNvbmZpZyIsIm1hcmlvbmV0dGVQb3J0IiwidXNlclByb2ZpbGUiLCJydW50aW1lSW5mbyIsInRlbXBQcm9maWxlRGlyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBOztBQUNBOzs7O0FBQ0E7Ozs7Ozs7K0NBR2UsV0FBZ0JBLFlBQWhCLEVBQThCO0FBQ3pDLGNBQU1DLFNBQWlCLHNCQUFVRCxZQUFWLENBQXZCO0FBQ0EsY0FBTUUsaUJBQWlCRCxPQUFPQyxjQUFQLEtBQTBCLENBQUNELE9BQU9FLFdBQVIsR0FBc0IsTUFBTSxpQ0FBNUIsR0FBNEMsSUFBdEUsQ0FBdkI7QUFDQSxjQUFNQyxjQUFpQixFQUFFSCxNQUFGLEVBQVVDLGNBQVYsRUFBdkI7O0FBRUFFLG9CQUFZQyxjQUFaLEdBQTZCLENBQUNKLE9BQU9FLFdBQVIsR0FBc0IsTUFBTSxpQ0FBa0JDLFdBQWxCLENBQTVCLEdBQTZELElBQTFGOztBQUVBLGVBQU9BLFdBQVA7QUFDSCxLIiwiZmlsZSI6ImJyb3dzZXIvcHJvdmlkZXIvYnVpbHQtaW4vZmlyZWZveC9ydW50aW1lLWluZm8uanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRGcmVlUG9ydCB9IGZyb20gJ2VuZHBvaW50LXV0aWxzJztcbmltcG9ydCBnZXRDb25maWcgZnJvbSAnLi9jb25maWcnO1xuaW1wb3J0IGNyZWF0ZVRlbXBQcm9maWxlIGZyb20gJy4vY3JlYXRlLXRlbXAtcHJvZmlsZSc7XG5cblxuZXhwb3J0IGRlZmF1bHQgYXN5bmMgZnVuY3Rpb24gKGNvbmZpZ1N0cmluZykge1xuICAgIGNvbnN0IGNvbmZpZyAgICAgICAgID0gZ2V0Q29uZmlnKGNvbmZpZ1N0cmluZyk7XG4gICAgY29uc3QgbWFyaW9uZXR0ZVBvcnQgPSBjb25maWcubWFyaW9uZXR0ZVBvcnQgfHwgKCFjb25maWcudXNlclByb2ZpbGUgPyBhd2FpdCBnZXRGcmVlUG9ydCgpIDogbnVsbCk7XG4gICAgY29uc3QgcnVudGltZUluZm8gICAgPSB7IGNvbmZpZywgbWFyaW9uZXR0ZVBvcnQgfTtcblxuICAgIHJ1bnRpbWVJbmZvLnRlbXBQcm9maWxlRGlyID0gIWNvbmZpZy51c2VyUHJvZmlsZSA/IGF3YWl0IGNyZWF0ZVRlbXBQcm9maWxlKHJ1bnRpbWVJbmZvKSA6IG51bGw7XG5cbiAgICByZXR1cm4gcnVudGltZUluZm87XG59XG4iXX0= diff --git a/lib/browser/provider/built-in/index.js b/lib/browser/provider/built-in/index.js new file mode 100644 index 00000000..b4472521 --- /dev/null +++ b/lib/browser/provider/built-in/index.js @@ -0,0 +1,41 @@ +'use strict'; + +exports.__esModule = true; + +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + +var _path = require('./path'); + +var _path2 = _interopRequireDefault(_path); + +var _locallyInstalled = require('./locally-installed'); + +var _locallyInstalled2 = _interopRequireDefault(_locallyInstalled); + +var _remote = require('./remote'); + +var _remote2 = _interopRequireDefault(_remote); + +var _firefox = require('./firefox'); + +var _firefox2 = _interopRequireDefault(_firefox); + +var _chrome = require('./chrome'); + +var _chrome2 = _interopRequireDefault(_chrome); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = (0, _assign2.default)({ + 'locally-installed': _locallyInstalled2.default, + 'path': _path2.default, + 'remote': _remote2.default, + 'firefox': _firefox2.default, + 'chrome': _chrome2.default, + 'chromium': _chrome2.default, + 'chrome-canary': _chrome2.default +}); +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2luZGV4LmpzIl0sIm5hbWVzIjpbImxvY2FsbHlJbnN0YWxsZWRCcm93c2VyUHJvdmlkZXIiLCJwYXRoQnJvd3NlclByb3ZpZGVyIiwicmVtb3RlQnJvd3NlclByb3ZpZGVyIiwiZmlyZWZveFByb3ZpZGVyIiwiY2hyb21lUHJvdmlkZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O2tCQUVlLHNCQUNYO0FBQ0kseUJBQXFCQSwwQkFEekI7QUFFSSxZQUFxQkMsY0FGekI7QUFHSSxjQUFxQkMsZ0JBSHpCO0FBSUksZUFBcUJDLGlCQUp6QjtBQUtJLGNBQXFCQyxnQkFMekI7QUFNSSxnQkFBcUJBLGdCQU56QjtBQU9JLHFCQUFxQkE7QUFQekIsQ0FEVyxDIiwiZmlsZSI6ImJyb3dzZXIvcHJvdmlkZXIvYnVpbHQtaW4vaW5kZXguanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aEJyb3dzZXJQcm92aWRlciBmcm9tICcuL3BhdGgnO1xuaW1wb3J0IGxvY2FsbHlJbnN0YWxsZWRCcm93c2VyUHJvdmlkZXIgZnJvbSAnLi9sb2NhbGx5LWluc3RhbGxlZCc7XG5pbXBvcnQgcmVtb3RlQnJvd3NlclByb3ZpZGVyIGZyb20gJy4vcmVtb3RlJztcbmltcG9ydCBmaXJlZm94UHJvdmlkZXIgZnJvbSAnLi9maXJlZm94JztcbmltcG9ydCBjaHJvbWVQcm92aWRlciBmcm9tICcuL2Nocm9tZSc7XG5cbmV4cG9ydCBkZWZhdWx0IE9iamVjdC5hc3NpZ24oXG4gICAge1xuICAgICAgICAnbG9jYWxseS1pbnN0YWxsZWQnOiBsb2NhbGx5SW5zdGFsbGVkQnJvd3NlclByb3ZpZGVyLFxuICAgICAgICAncGF0aCc6ICAgICAgICAgICAgICBwYXRoQnJvd3NlclByb3ZpZGVyLFxuICAgICAgICAncmVtb3RlJzogICAgICAgICAgICByZW1vdGVCcm93c2VyUHJvdmlkZXIsXG4gICAgICAgICdmaXJlZm94JzogICAgICAgICAgIGZpcmVmb3hQcm92aWRlcixcbiAgICAgICAgJ2Nocm9tZSc6ICAgICAgICAgICAgY2hyb21lUHJvdmlkZXIsXG4gICAgICAgICdjaHJvbWl1bSc6ICAgICAgICAgIGNocm9tZVByb3ZpZGVyLFxuICAgICAgICAnY2hyb21lLWNhbmFyeSc6ICAgICBjaHJvbWVQcm92aWRlclxuICAgIH1cbik7XG4iXX0= diff --git a/lib/browser/provider/built-in/locally-installed.js b/lib/browser/provider/built-in/locally-installed.js new file mode 100644 index 00000000..7fb4945a --- /dev/null +++ b/lib/browser/provider/built-in/locally-installed.js @@ -0,0 +1,67 @@ +'use strict'; + +exports.__esModule = true; + +var _keys = require('babel-runtime/core-js/object/keys'); + +var _keys2 = _interopRequireDefault(_keys); + +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _testcafeBrowserTools = require('testcafe-browser-tools'); + +var _testcafeBrowserTools2 = _interopRequireDefault(_testcafeBrowserTools); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + isMultiBrowser: true, + + openBrowser(browserId, pageUrl, browserName) { + return (0, _asyncToGenerator3.default)(function* () { + const args = browserName.split(' '); + const alias = args.shift(); + + const browserInfo = yield _testcafeBrowserTools2.default.getBrowserInfo(alias); + const openParameters = (0, _assign2.default)({}, browserInfo); + + if (args.length) openParameters.cmd = args.join(' ') + (openParameters.cmd ? ' ' + openParameters.cmd : ''); + + yield _testcafeBrowserTools2.default.open(openParameters, pageUrl); + })(); + }, + + isLocalBrowser() { + return (0, _asyncToGenerator3.default)(function* () { + return true; + })(); + }, + + getBrowserList() { + return (0, _asyncToGenerator3.default)(function* () { + const installations = yield _testcafeBrowserTools2.default.getInstallations(); + + return (0, _keys2.default)(installations); + })(); + }, + + isValidBrowserName(browserName) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + const browserNames = yield _this.getBrowserList(); + + browserName = browserName.toLowerCase().split(' ')[0]; + + return browserNames.indexOf(browserName) > -1; + })(); + } +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL2xvY2FsbHktaW5zdGFsbGVkLmpzIl0sIm5hbWVzIjpbImlzTXVsdGlCcm93c2VyIiwib3BlbkJyb3dzZXIiLCJicm93c2VySWQiLCJwYWdlVXJsIiwiYnJvd3Nlck5hbWUiLCJhcmdzIiwic3BsaXQiLCJhbGlhcyIsInNoaWZ0IiwiYnJvd3NlckluZm8iLCJicm93c2VyVG9vbHMiLCJnZXRCcm93c2VySW5mbyIsIm9wZW5QYXJhbWV0ZXJzIiwibGVuZ3RoIiwiY21kIiwiam9pbiIsIm9wZW4iLCJpc0xvY2FsQnJvd3NlciIsImdldEJyb3dzZXJMaXN0IiwiaW5zdGFsbGF0aW9ucyIsImdldEluc3RhbGxhdGlvbnMiLCJpc1ZhbGlkQnJvd3Nlck5hbWUiLCJicm93c2VyTmFtZXMiLCJ0b0xvd2VyQ2FzZSIsImluZGV4T2YiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7Ozs7O2tCQUdlO0FBQ1hBLG9CQUFnQixJQURMOztBQUdMQyxlQUFOLENBQW1CQyxTQUFuQixFQUE4QkMsT0FBOUIsRUFBdUNDLFdBQXZDLEVBQW9EO0FBQUE7QUFDaEQsa0JBQU1DLE9BQVFELFlBQVlFLEtBQVosQ0FBa0IsR0FBbEIsQ0FBZDtBQUNBLGtCQUFNQyxRQUFRRixLQUFLRyxLQUFMLEVBQWQ7O0FBRUEsa0JBQU1DLGNBQWlCLE1BQU1DLCtCQUFhQyxjQUFiLENBQTRCSixLQUE1QixDQUE3QjtBQUNBLGtCQUFNSyxpQkFBaUIsc0JBQWMsRUFBZCxFQUFrQkgsV0FBbEIsQ0FBdkI7O0FBRUEsZ0JBQUlKLEtBQUtRLE1BQVQsRUFDSUQsZUFBZUUsR0FBZixHQUFxQlQsS0FBS1UsSUFBTCxDQUFVLEdBQVYsS0FBa0JILGVBQWVFLEdBQWYsR0FBcUIsTUFBTUYsZUFBZUUsR0FBMUMsR0FBZ0QsRUFBbEUsQ0FBckI7O0FBRUosa0JBQU1KLCtCQUFhTSxJQUFiLENBQWtCSixjQUFsQixFQUFrQ1QsT0FBbEMsQ0FBTjtBQVZnRDtBQVduRCxLQWRVOztBQWdCTGMsa0JBQU4sR0FBd0I7QUFBQTtBQUNwQixtQkFBTyxJQUFQO0FBRG9CO0FBRXZCLEtBbEJVOztBQW9CTEMsa0JBQU4sR0FBd0I7QUFBQTtBQUNwQixrQkFBTUMsZ0JBQWdCLE1BQU1ULCtCQUFhVSxnQkFBYixFQUE1Qjs7QUFFQSxtQkFBTyxvQkFBWUQsYUFBWixDQUFQO0FBSG9CO0FBSXZCLEtBeEJVOztBQTBCTEUsc0JBQU4sQ0FBMEJqQixXQUExQixFQUF1QztBQUFBOztBQUFBO0FBQ25DLGtCQUFNa0IsZUFBZSxNQUFNLE1BQUtKLGNBQUwsRUFBM0I7O0FBRUFkLDBCQUFjQSxZQUFZbUIsV0FBWixHQUEwQmpCLEtBQTFCLENBQWdDLEdBQWhDLEVBQXFDLENBQXJDLENBQWQ7O0FBRUEsbUJBQU9nQixhQUFhRSxPQUFiLENBQXFCcEIsV0FBckIsSUFBb0MsQ0FBQyxDQUE1QztBQUxtQztBQU10QztBQWhDVSxDIiwiZmlsZSI6ImJyb3dzZXIvcHJvdmlkZXIvYnVpbHQtaW4vbG9jYWxseS1pbnN0YWxsZWQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYnJvd3NlclRvb2xzIGZyb20gJ3Rlc3RjYWZlLWJyb3dzZXItdG9vbHMnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBpc011bHRpQnJvd3NlcjogdHJ1ZSxcblxuICAgIGFzeW5jIG9wZW5Ccm93c2VyIChicm93c2VySWQsIHBhZ2VVcmwsIGJyb3dzZXJOYW1lKSB7XG4gICAgICAgIGNvbnN0IGFyZ3MgID0gYnJvd3Nlck5hbWUuc3BsaXQoJyAnKTtcbiAgICAgICAgY29uc3QgYWxpYXMgPSBhcmdzLnNoaWZ0KCk7XG5cbiAgICAgICAgY29uc3QgYnJvd3NlckluZm8gICAgPSBhd2FpdCBicm93c2VyVG9vbHMuZ2V0QnJvd3NlckluZm8oYWxpYXMpO1xuICAgICAgICBjb25zdCBvcGVuUGFyYW1ldGVycyA9IE9iamVjdC5hc3NpZ24oe30sIGJyb3dzZXJJbmZvKTtcblxuICAgICAgICBpZiAoYXJncy5sZW5ndGgpXG4gICAgICAgICAgICBvcGVuUGFyYW1ldGVycy5jbWQgPSBhcmdzLmpvaW4oJyAnKSArIChvcGVuUGFyYW1ldGVycy5jbWQgPyAnICcgKyBvcGVuUGFyYW1ldGVycy5jbWQgOiAnJyk7XG5cbiAgICAgICAgYXdhaXQgYnJvd3NlclRvb2xzLm9wZW4ob3BlblBhcmFtZXRlcnMsIHBhZ2VVcmwpO1xuICAgIH0sXG5cbiAgICBhc3luYyBpc0xvY2FsQnJvd3NlciAoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRCcm93c2VyTGlzdCAoKSB7XG4gICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbnMgPSBhd2FpdCBicm93c2VyVG9vbHMuZ2V0SW5zdGFsbGF0aW9ucygpO1xuXG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhpbnN0YWxsYXRpb25zKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgaXNWYWxpZEJyb3dzZXJOYW1lIChicm93c2VyTmFtZSkge1xuICAgICAgICBjb25zdCBicm93c2VyTmFtZXMgPSBhd2FpdCB0aGlzLmdldEJyb3dzZXJMaXN0KCk7XG5cbiAgICAgICAgYnJvd3Nlck5hbWUgPSBicm93c2VyTmFtZS50b0xvd2VyQ2FzZSgpLnNwbGl0KCcgJylbMF07XG5cbiAgICAgICAgcmV0dXJuIGJyb3dzZXJOYW1lcy5pbmRleE9mKGJyb3dzZXJOYW1lKSA+IC0xO1xuICAgIH1cbn07XG4iXX0= diff --git a/lib/browser/provider/built-in/path.js b/lib/browser/provider/built-in/path.js new file mode 100644 index 00000000..09031e61 --- /dev/null +++ b/lib/browser/provider/built-in/path.js @@ -0,0 +1,82 @@ +'use strict'; + +exports.__esModule = true; + +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _testcafeBrowserTools = require('testcafe-browser-tools'); + +var _testcafeBrowserTools2 = _interopRequireDefault(_testcafeBrowserTools); + +var _string = require('../../../utils/string'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + isMultiBrowser: true, + + _handleString(str) { + return (0, _asyncToGenerator3.default)(function* () { + const args = (0, _string.splitQuotedText)(str, ' ', '`"\''); + const path = args.shift(); + + const browserInfo = yield _testcafeBrowserTools2.default.getBrowserInfo(path); + + if (!browserInfo) return null; + + const params = (0, _assign2.default)({}, browserInfo); + + if (args.length) params.cmd = args.join(' ') + (params.cmd ? ' ' + params.cmd : ''); + + return params; + })(); + }, + + _handleJSON(str) { + return (0, _asyncToGenerator3.default)(function* () { + let params = null; + + try { + params = JSON.parse(str); + } catch (e) { + return null; + } + + if (!params.path) return null; + + const openParameters = yield _testcafeBrowserTools2.default.getBrowserInfo(params.path); + + if (!openParameters) return null; + + if (params.cmd) openParameters.cmd = params.cmd; + + return openParameters; + })(); + }, + + openBrowser(browserId, pageUrl, browserName) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + const openParameters = (yield _this._handleString(browserName)) || (yield _this._handleJSON(browserName)); + + if (!openParameters) throw new Error('The specified browser name is not valid!'); + + yield _testcafeBrowserTools2.default.open(openParameters, pageUrl); + })(); + }, + + isLocalBrowser() { + return (0, _asyncToGenerator3.default)(function* () { + return true; + })(); + } +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL3BhdGguanMiXSwibmFtZXMiOlsiaXNNdWx0aUJyb3dzZXIiLCJfaGFuZGxlU3RyaW5nIiwic3RyIiwiYXJncyIsInBhdGgiLCJzaGlmdCIsImJyb3dzZXJJbmZvIiwiYnJvd3NlclRvb2xzIiwiZ2V0QnJvd3NlckluZm8iLCJwYXJhbXMiLCJsZW5ndGgiLCJjbWQiLCJqb2luIiwiX2hhbmRsZUpTT04iLCJKU09OIiwicGFyc2UiLCJlIiwib3BlblBhcmFtZXRlcnMiLCJvcGVuQnJvd3NlciIsImJyb3dzZXJJZCIsInBhZ2VVcmwiLCJicm93c2VyTmFtZSIsIkVycm9yIiwib3BlbiIsImlzTG9jYWxCcm93c2VyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQTs7OztBQUNBOzs7O2tCQUVlO0FBQ1hBLG9CQUFnQixJQURMOztBQUdMQyxpQkFBTixDQUFxQkMsR0FBckIsRUFBMEI7QUFBQTtBQUN0QixrQkFBTUMsT0FBTyw2QkFBZ0JELEdBQWhCLEVBQXFCLEdBQXJCLEVBQTBCLE1BQTFCLENBQWI7QUFDQSxrQkFBTUUsT0FBT0QsS0FBS0UsS0FBTCxFQUFiOztBQUVBLGtCQUFNQyxjQUFjLE1BQU1DLCtCQUFhQyxjQUFiLENBQTRCSixJQUE1QixDQUExQjs7QUFFQSxnQkFBSSxDQUFDRSxXQUFMLEVBQ0ksT0FBTyxJQUFQOztBQUVKLGtCQUFNRyxTQUFTLHNCQUFjLEVBQWQsRUFBa0JILFdBQWxCLENBQWY7O0FBRUEsZ0JBQUlILEtBQUtPLE1BQVQsRUFDSUQsT0FBT0UsR0FBUCxHQUFhUixLQUFLUyxJQUFMLENBQVUsR0FBVixLQUFrQkgsT0FBT0UsR0FBUCxHQUFhLE1BQU1GLE9BQU9FLEdBQTFCLEdBQWdDLEVBQWxELENBQWI7O0FBRUosbUJBQU9GLE1BQVA7QUFkc0I7QUFlekIsS0FsQlU7O0FBb0JMSSxlQUFOLENBQW1CWCxHQUFuQixFQUF3QjtBQUFBO0FBQ3BCLGdCQUFJTyxTQUFTLElBQWI7O0FBRUEsZ0JBQUk7QUFDQUEseUJBQVNLLEtBQUtDLEtBQUwsQ0FBV2IsR0FBWCxDQUFUO0FBQ0gsYUFGRCxDQUdBLE9BQU9jLENBQVAsRUFBVTtBQUNOLHVCQUFPLElBQVA7QUFDSDs7QUFFRCxnQkFBSSxDQUFDUCxPQUFPTCxJQUFaLEVBQ0ksT0FBTyxJQUFQOztBQUVKLGtCQUFNYSxpQkFBaUIsTUFBTVYsK0JBQWFDLGNBQWIsQ0FBNEJDLE9BQU9MLElBQW5DLENBQTdCOztBQUVBLGdCQUFJLENBQUNhLGNBQUwsRUFDSSxPQUFPLElBQVA7O0FBRUosZ0JBQUlSLE9BQU9FLEdBQVgsRUFDSU0sZUFBZU4sR0FBZixHQUFxQkYsT0FBT0UsR0FBNUI7O0FBRUosbUJBQU9NLGNBQVA7QUFyQm9CO0FBc0J2QixLQTFDVTs7QUE0Q0xDLGVBQU4sQ0FBbUJDLFNBQW5CLEVBQThCQyxPQUE5QixFQUF1Q0MsV0FBdkMsRUFBb0Q7QUFBQTs7QUFBQTtBQUNoRCxrQkFBTUosaUJBQWlCLE9BQU0sTUFBS2hCLGFBQUwsQ0FBbUJvQixXQUFuQixDQUFOLE1BQXlDLE1BQU0sTUFBS1IsV0FBTCxDQUFpQlEsV0FBakIsQ0FBL0MsQ0FBdkI7O0FBRUEsZ0JBQUksQ0FBQ0osY0FBTCxFQUNJLE1BQU0sSUFBSUssS0FBSixDQUFVLDBDQUFWLENBQU47O0FBRUosa0JBQU1mLCtCQUFhZ0IsSUFBYixDQUFrQk4sY0FBbEIsRUFBa0NHLE9BQWxDLENBQU47QUFOZ0Q7QUFPbkQsS0FuRFU7O0FBcURMSSxrQkFBTixHQUF3QjtBQUFBO0FBQ3BCLG1CQUFPLElBQVA7QUFEb0I7QUFFdkI7QUF2RFUsQyIsImZpbGUiOiJicm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL3BhdGguanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYnJvd3NlclRvb2xzIGZyb20gJ3Rlc3RjYWZlLWJyb3dzZXItdG9vbHMnO1xuaW1wb3J0IHsgc3BsaXRRdW90ZWRUZXh0IH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvc3RyaW5nJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIGlzTXVsdGlCcm93c2VyOiB0cnVlLFxuXG4gICAgYXN5bmMgX2hhbmRsZVN0cmluZyAoc3RyKSB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBzcGxpdFF1b3RlZFRleHQoc3RyLCAnICcsICdgXCJcXCcnKTtcbiAgICAgICAgY29uc3QgcGF0aCA9IGFyZ3Muc2hpZnQoKTtcblxuICAgICAgICBjb25zdCBicm93c2VySW5mbyA9IGF3YWl0IGJyb3dzZXJUb29scy5nZXRCcm93c2VySW5mbyhwYXRoKTtcblxuICAgICAgICBpZiAoIWJyb3dzZXJJbmZvKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0gT2JqZWN0LmFzc2lnbih7fSwgYnJvd3NlckluZm8pO1xuXG4gICAgICAgIGlmIChhcmdzLmxlbmd0aClcbiAgICAgICAgICAgIHBhcmFtcy5jbWQgPSBhcmdzLmpvaW4oJyAnKSArIChwYXJhbXMuY21kID8gJyAnICsgcGFyYW1zLmNtZCA6ICcnKTtcblxuICAgICAgICByZXR1cm4gcGFyYW1zO1xuICAgIH0sXG5cbiAgICBhc3luYyBfaGFuZGxlSlNPTiAoc3RyKSB7XG4gICAgICAgIGxldCBwYXJhbXMgPSBudWxsO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwYXJhbXMgPSBKU09OLnBhcnNlKHN0cik7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFwYXJhbXMucGF0aClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IG9wZW5QYXJhbWV0ZXJzID0gYXdhaXQgYnJvd3NlclRvb2xzLmdldEJyb3dzZXJJbmZvKHBhcmFtcy5wYXRoKTtcblxuICAgICAgICBpZiAoIW9wZW5QYXJhbWV0ZXJzKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgaWYgKHBhcmFtcy5jbWQpXG4gICAgICAgICAgICBvcGVuUGFyYW1ldGVycy5jbWQgPSBwYXJhbXMuY21kO1xuXG4gICAgICAgIHJldHVybiBvcGVuUGFyYW1ldGVycztcbiAgICB9LFxuXG4gICAgYXN5bmMgb3BlbkJyb3dzZXIgKGJyb3dzZXJJZCwgcGFnZVVybCwgYnJvd3Nlck5hbWUpIHtcbiAgICAgICAgY29uc3Qgb3BlblBhcmFtZXRlcnMgPSBhd2FpdCB0aGlzLl9oYW5kbGVTdHJpbmcoYnJvd3Nlck5hbWUpIHx8IGF3YWl0IHRoaXMuX2hhbmRsZUpTT04oYnJvd3Nlck5hbWUpO1xuXG4gICAgICAgIGlmICghb3BlblBhcmFtZXRlcnMpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBzcGVjaWZpZWQgYnJvd3NlciBuYW1lIGlzIG5vdCB2YWxpZCEnKTtcblxuICAgICAgICBhd2FpdCBicm93c2VyVG9vbHMub3BlbihvcGVuUGFyYW1ldGVycywgcGFnZVVybCk7XG4gICAgfSxcblxuICAgIGFzeW5jIGlzTG9jYWxCcm93c2VyICgpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxufTtcbiJdfQ== diff --git a/lib/browser/provider/built-in/remote.js b/lib/browser/provider/built-in/remote.js new file mode 100644 index 00000000..a3243d62 --- /dev/null +++ b/lib/browser/provider/built-in/remote.js @@ -0,0 +1,90 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _testcafeBrowserTools = require('testcafe-browser-tools'); + +var _warningMessage = require('../../../notifications/warning-message'); + +var _warningMessage2 = _interopRequireDefault(_warningMessage); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = { + localBrowsersFlags: {}, + + openBrowser(browserId) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _this.waitForConnectionReady(browserId); + + const localBrowserWindow = yield (0, _testcafeBrowserTools.findWindow)(browserId); + + _this.localBrowsersFlags[browserId] = localBrowserWindow !== null; + })(); + }, + + closeBrowser(browserId) { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + delete _this2.localBrowsersFlags[browserId]; + })(); + }, + + isLocalBrowser(browserId) { + var _this3 = this; + + return (0, _asyncToGenerator3.default)(function* () { + return _this3.localBrowsersFlags[browserId]; + })(); + }, + + // NOTE: we must try to do a local screenshot or resize, if browser is accessible, and emit warning otherwise + hasCustomActionForBrowser(browserId) { + var _this4 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const isLocalBrowser = _this4.localBrowsersFlags[browserId]; + + return { + hasCloseBrowser: true, + hasResizeWindow: !isLocalBrowser, + hasMaximizeWindow: !isLocalBrowser, + hasTakeScreenshot: !isLocalBrowser, + hasCanResizeWindowToDimensions: !isLocalBrowser + }; + })(); + }, + + takeScreenshot(browserId) { + var _this5 = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this5.reportWarning(browserId, _warningMessage2.default.browserManipulationsOnRemoteBrowser); + })(); + }, + + resizeWindow(browserId) { + var _this6 = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this6.reportWarning(browserId, _warningMessage2.default.browserManipulationsOnRemoteBrowser); + })(); + }, + + maximizeWindow(browserId) { + var _this7 = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this7.reportWarning(browserId, _warningMessage2.default.browserManipulationsOnRemoteBrowser); + })(); + } +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL3JlbW90ZS5qcyJdLCJuYW1lcyI6WyJsb2NhbEJyb3dzZXJzRmxhZ3MiLCJvcGVuQnJvd3NlciIsImJyb3dzZXJJZCIsIndhaXRGb3JDb25uZWN0aW9uUmVhZHkiLCJsb2NhbEJyb3dzZXJXaW5kb3ciLCJjbG9zZUJyb3dzZXIiLCJpc0xvY2FsQnJvd3NlciIsImhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIiLCJoYXNDbG9zZUJyb3dzZXIiLCJoYXNSZXNpemVXaW5kb3ciLCJoYXNNYXhpbWl6ZVdpbmRvdyIsImhhc1Rha2VTY3JlZW5zaG90IiwiaGFzQ2FuUmVzaXplV2luZG93VG9EaW1lbnNpb25zIiwidGFrZVNjcmVlbnNob3QiLCJyZXBvcnRXYXJuaW5nIiwiV0FSTklOR19NRVNTQUdFIiwiYnJvd3Nlck1hbmlwdWxhdGlvbnNPblJlbW90ZUJyb3dzZXIiLCJyZXNpemVXaW5kb3ciLCJtYXhpbWl6ZVdpbmRvdyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQTs7QUFDQTs7Ozs7O2tCQUdlO0FBQ1hBLHdCQUFvQixFQURUOztBQUdMQyxlQUFOLENBQW1CQyxTQUFuQixFQUE4QjtBQUFBOztBQUFBO0FBQzFCLGtCQUFNLE1BQUtDLHNCQUFMLENBQTRCRCxTQUE1QixDQUFOOztBQUVBLGtCQUFNRSxxQkFBcUIsTUFBTSxzQ0FBV0YsU0FBWCxDQUFqQzs7QUFFQSxrQkFBS0Ysa0JBQUwsQ0FBd0JFLFNBQXhCLElBQXFDRSx1QkFBdUIsSUFBNUQ7QUFMMEI7QUFNN0IsS0FUVTs7QUFXTEMsZ0JBQU4sQ0FBb0JILFNBQXBCLEVBQStCO0FBQUE7O0FBQUE7QUFDM0IsbUJBQU8sT0FBS0Ysa0JBQUwsQ0FBd0JFLFNBQXhCLENBQVA7QUFEMkI7QUFFOUIsS0FiVTs7QUFlTEksa0JBQU4sQ0FBc0JKLFNBQXRCLEVBQWlDO0FBQUE7O0FBQUE7QUFDN0IsbUJBQU8sT0FBS0Ysa0JBQUwsQ0FBd0JFLFNBQXhCLENBQVA7QUFENkI7QUFFaEMsS0FqQlU7O0FBbUJYO0FBQ01LLDZCQUFOLENBQWlDTCxTQUFqQyxFQUE0QztBQUFBOztBQUFBO0FBQ3hDLGtCQUFNSSxpQkFBaUIsT0FBS04sa0JBQUwsQ0FBd0JFLFNBQXhCLENBQXZCOztBQUVBLG1CQUFPO0FBQ0hNLGlDQUFnQyxJQUQ3QjtBQUVIQyxpQ0FBZ0MsQ0FBQ0gsY0FGOUI7QUFHSEksbUNBQWdDLENBQUNKLGNBSDlCO0FBSUhLLG1DQUFnQyxDQUFDTCxjQUo5QjtBQUtITSxnREFBZ0MsQ0FBQ047QUFMOUIsYUFBUDtBQUh3QztBQVUzQyxLQTlCVTs7QUFnQ0xPLGtCQUFOLENBQXNCWCxTQUF0QixFQUFpQztBQUFBOztBQUFBO0FBQzdCLG1CQUFLWSxhQUFMLENBQW1CWixTQUFuQixFQUE4QmEseUJBQWdCQyxtQ0FBOUM7QUFENkI7QUFFaEMsS0FsQ1U7O0FBb0NMQyxnQkFBTixDQUFvQmYsU0FBcEIsRUFBK0I7QUFBQTs7QUFBQTtBQUMzQixtQkFBS1ksYUFBTCxDQUFtQlosU0FBbkIsRUFBOEJhLHlCQUFnQkMsbUNBQTlDO0FBRDJCO0FBRTlCLEtBdENVOztBQXdDTEUsa0JBQU4sQ0FBc0JoQixTQUF0QixFQUFpQztBQUFBOztBQUFBO0FBQzdCLG1CQUFLWSxhQUFMLENBQW1CWixTQUFuQixFQUE4QmEseUJBQWdCQyxtQ0FBOUM7QUFENkI7QUFFaEM7QUExQ1UsQyIsImZpbGUiOiJicm93c2VyL3Byb3ZpZGVyL2J1aWx0LWluL3JlbW90ZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGZpbmRXaW5kb3cgfSBmcm9tICd0ZXN0Y2FmZS1icm93c2VyLXRvb2xzJztcbmltcG9ydCBXQVJOSU5HX01FU1NBR0UgZnJvbSAnLi4vLi4vLi4vbm90aWZpY2F0aW9ucy93YXJuaW5nLW1lc3NhZ2UnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICBsb2NhbEJyb3dzZXJzRmxhZ3M6IHt9LFxuXG4gICAgYXN5bmMgb3BlbkJyb3dzZXIgKGJyb3dzZXJJZCkge1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JDb25uZWN0aW9uUmVhZHkoYnJvd3NlcklkKTtcblxuICAgICAgICBjb25zdCBsb2NhbEJyb3dzZXJXaW5kb3cgPSBhd2FpdCBmaW5kV2luZG93KGJyb3dzZXJJZCk7XG5cbiAgICAgICAgdGhpcy5sb2NhbEJyb3dzZXJzRmxhZ3NbYnJvd3NlcklkXSA9IGxvY2FsQnJvd3NlcldpbmRvdyAhPT0gbnVsbDtcbiAgICB9LFxuXG4gICAgYXN5bmMgY2xvc2VCcm93c2VyIChicm93c2VySWQpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMubG9jYWxCcm93c2Vyc0ZsYWdzW2Jyb3dzZXJJZF07XG4gICAgfSxcblxuICAgIGFzeW5jIGlzTG9jYWxCcm93c2VyIChicm93c2VySWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxCcm93c2Vyc0ZsYWdzW2Jyb3dzZXJJZF07XG4gICAgfSxcblxuICAgIC8vIE5PVEU6IHdlIG11c3QgdHJ5IHRvIGRvIGEgbG9jYWwgc2NyZWVuc2hvdCBvciByZXNpemUsIGlmIGJyb3dzZXIgaXMgYWNjZXNzaWJsZSwgYW5kIGVtaXQgd2FybmluZyBvdGhlcndpc2VcbiAgICBhc3luYyBoYXNDdXN0b21BY3Rpb25Gb3JCcm93c2VyIChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgaXNMb2NhbEJyb3dzZXIgPSB0aGlzLmxvY2FsQnJvd3NlcnNGbGFnc1ticm93c2VySWRdO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoYXNDbG9zZUJyb3dzZXI6ICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICBoYXNSZXNpemVXaW5kb3c6ICAgICAgICAgICAgICAgICFpc0xvY2FsQnJvd3NlcixcbiAgICAgICAgICAgIGhhc01heGltaXplV2luZG93OiAgICAgICAgICAgICAgIWlzTG9jYWxCcm93c2VyLFxuICAgICAgICAgICAgaGFzVGFrZVNjcmVlbnNob3Q6ICAgICAgICAgICAgICAhaXNMb2NhbEJyb3dzZXIsXG4gICAgICAgICAgICBoYXNDYW5SZXNpemVXaW5kb3dUb0RpbWVuc2lvbnM6ICFpc0xvY2FsQnJvd3NlclxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBhc3luYyB0YWtlU2NyZWVuc2hvdCAoYnJvd3NlcklkKSB7XG4gICAgICAgIHRoaXMucmVwb3J0V2FybmluZyhicm93c2VySWQsIFdBUk5JTkdfTUVTU0FHRS5icm93c2VyTWFuaXB1bGF0aW9uc09uUmVtb3RlQnJvd3Nlcik7XG4gICAgfSxcblxuICAgIGFzeW5jIHJlc2l6ZVdpbmRvdyAoYnJvd3NlcklkKSB7XG4gICAgICAgIHRoaXMucmVwb3J0V2FybmluZyhicm93c2VySWQsIFdBUk5JTkdfTUVTU0FHRS5icm93c2VyTWFuaXB1bGF0aW9uc09uUmVtb3RlQnJvd3Nlcik7XG4gICAgfSxcblxuICAgIGFzeW5jIG1heGltaXplV2luZG93IChicm93c2VySWQpIHtcbiAgICAgICAgdGhpcy5yZXBvcnRXYXJuaW5nKGJyb3dzZXJJZCwgV0FSTklOR19NRVNTQUdFLmJyb3dzZXJNYW5pcHVsYXRpb25zT25SZW1vdGVCcm93c2VyKTtcbiAgICB9XG59O1xuIl19 diff --git a/lib/browser/provider/index.js b/lib/browser/provider/index.js new file mode 100644 index 00000000..f5e0e4fa --- /dev/null +++ b/lib/browser/provider/index.js @@ -0,0 +1,406 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _pinkie = require('pinkie'); + +var _pinkie2 = _interopRequireDefault(_pinkie); + +var _testcafeBrowserTools = require('testcafe-browser-tools'); + +var _testcafeBrowserTools2 = _interopRequireDefault(_testcafeBrowserTools); + +var _osFamily = require('os-family'); + +var _osFamily2 = _interopRequireDefault(_osFamily); + +var _connection = require('../connection'); + +var _connection2 = _interopRequireDefault(_connection); + +var _delay = require('../../utils/delay'); + +var _delay2 = _interopRequireDefault(_delay); + +var _clientFunctions = require('./utils/client-functions'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const BROWSER_OPENING_DELAY = 2000; + +const RESIZE_DIFF_SIZE = { + width: 100, + height: 100 +}; + +function sumSizes(sizeA, sizeB) { + return { + width: sizeA.width + sizeB.width, + height: sizeA.height + sizeB.height + }; +} + +function subtractSizes(sizeA, sizeB) { + return { + width: sizeA.width - sizeB.width, + height: sizeA.height - sizeB.height + }; +} + +class BrowserProvider { + constructor(plugin) { + this.plugin = plugin; + this.initPromise = _pinkie2.default.resolve(false); + + this.isMultiBrowser = this.plugin.isMultiBrowser; + // HACK: The browser window has different border sizes in normal and maximized modes. So, we need to be sure that the window is + // not maximized before resizing it in order to keep the mechanism of correcting the client area size working. When browser is started, + // we are resizing it for the first time to switch the window to normal mode, and for the second time - to restore the client area size. + this.localBrowsersInfo = {}; + } + + _createLocalBrowserInfo(browserId) { + if (this.localBrowsersInfo[browserId]) return; + + this.localBrowsersInfo[browserId] = { + windowDescriptor: null, + maxScreenSize: null, + resizeCorrections: null + }; + } + + _getWindowDescriptor(browserId) { + return this.localBrowsersInfo[browserId] && this.localBrowsersInfo[browserId].windowDescriptor; + } + + _getMaxScreenSize(browserId) { + return this.localBrowsersInfo[browserId] && this.localBrowsersInfo[browserId].maxScreenSize; + } + + _getResizeCorrections(browserId) { + return this.localBrowsersInfo[browserId] && this.localBrowsersInfo[browserId].resizeCorrections; + } + + _isBrowserIdle(browserId) { + const connection = _connection2.default.getById(browserId); + + return connection.idle; + } + + _calculateResizeCorrections(browserId) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (!_this._isBrowserIdle(browserId)) return; + + const title = yield _this.plugin.runInitScript(browserId, _clientFunctions.GET_TITLE_SCRIPT); + + if (!(yield _testcafeBrowserTools2.default.isMaximized(title))) return; + + const currentSize = yield _this.plugin.runInitScript(browserId, _clientFunctions.GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + const etalonSize = subtractSizes(currentSize, RESIZE_DIFF_SIZE); + + yield _testcafeBrowserTools2.default.resize(title, currentSize.width, currentSize.height, etalonSize.width, etalonSize.height); + + let resizedSize = yield _this.plugin.runInitScript(browserId, _clientFunctions.GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + let correctionSize = subtractSizes(resizedSize, etalonSize); + + yield _testcafeBrowserTools2.default.resize(title, resizedSize.width, resizedSize.height, etalonSize.width, etalonSize.height); + + resizedSize = yield _this.plugin.runInitScript(browserId, _clientFunctions.GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + + correctionSize = sumSizes(correctionSize, subtractSizes(resizedSize, etalonSize)); + + if (_this.localBrowsersInfo[browserId]) _this.localBrowsersInfo[browserId].resizeCorrections = correctionSize; + + yield _testcafeBrowserTools2.default.maximize(title); + })(); + } + + _calculateMacSizeLimits(browserId) { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (!_this2._isBrowserIdle(browserId)) return; + + const sizeInfo = yield _this2.plugin.runInitScript(browserId, _clientFunctions.GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + + if (_this2.localBrowsersInfo[browserId]) { + _this2.localBrowsersInfo[browserId].maxScreenSize = { + width: sizeInfo.availableWidth - (sizeInfo.outerWidth - sizeInfo.width), + height: sizeInfo.availableHeight - (sizeInfo.outerHeight - sizeInfo.height) + }; + } + })(); + } + + _ensureBrowserWindowDescriptor(browserId) { + var _this3 = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (_this3._getWindowDescriptor(browserId)) return; + + yield _this3._createLocalBrowserInfo(browserId); + + // NOTE: delay to ensure the window finished the opening + yield _this3.plugin.waitForConnectionReady(browserId); + yield (0, _delay2.default)(BROWSER_OPENING_DELAY); + + if (_this3.localBrowsersInfo[browserId]) _this3.localBrowsersInfo[browserId].windowDescriptor = yield _testcafeBrowserTools2.default.findWindow(browserId); + })(); + } + + _ensureBrowserWindowParameters(browserId) { + var _this4 = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _this4._ensureBrowserWindowDescriptor(browserId); + + if (_osFamily2.default.win && !_this4._getResizeCorrections(browserId)) yield _this4._calculateResizeCorrections(browserId);else if (_osFamily2.default.mac && !_this4._getMaxScreenSize(browserId)) yield _this4._calculateMacSizeLimits(browserId); + })(); + } + + _closeLocalBrowser(browserId) { + var _this5 = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _testcafeBrowserTools2.default.close(_this5._getWindowDescriptor(browserId)); + })(); + } + + _resizeLocalBrowserWindow(browserId, width, height, currentWidth, currentHeight) { + var _this6 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const resizeCorrections = _this6._getResizeCorrections(browserId); + + if (resizeCorrections && (yield _testcafeBrowserTools2.default.isMaximized(_this6._getWindowDescriptor(browserId)))) { + width -= resizeCorrections.width; + height -= resizeCorrections.height; + } + + yield _testcafeBrowserTools2.default.resize(_this6._getWindowDescriptor(browserId), currentWidth, currentHeight, width, height); + })(); + } + + _takeLocalBrowserScreenshot(browserId, screenshotPath) { + var _this7 = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _testcafeBrowserTools2.default.screenshot(_this7._getWindowDescriptor(browserId), screenshotPath); + })(); + } + + _canResizeLocalBrowserWindowToDimensions(browserId, width, height) { + var _this8 = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (!_osFamily2.default.mac) return true; + + const maxScreenSize = _this8._getMaxScreenSize(browserId); + + return width <= maxScreenSize.width && height <= maxScreenSize.height; + })(); + } + + _maximizeLocalBrowserWindow(browserId) { + var _this9 = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _testcafeBrowserTools2.default.maximize(_this9._getWindowDescriptor(browserId)); + })(); + } + + _canUseDefaultWindowActions(browserId) { + var _this10 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const isLocalBrowser = yield _this10.plugin.isLocalBrowser(browserId); + const isHeadlessBrowser = yield _this10.plugin.isHeadlessBrowser(browserId); + + return isLocalBrowser && !isHeadlessBrowser; + })(); + } + + init() { + var _this11 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const initialized = yield _this11.initPromise; + + if (initialized) return; + + _this11.initPromise = _this11.plugin.init().then(function () { + return true; + }); + + try { + yield _this11.initPromise; + } catch (error) { + _this11.initPromise = _pinkie2.default.resolve(false); + + throw error; + } + })(); + } + + dispose() { + var _this12 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const initialized = yield _this12.initPromise; + + if (!initialized) return; + + _this12.initPromise = _this12.plugin.dispose().then(function () { + return false; + }); + + try { + yield _this12.initPromise; + } catch (error) { + _this12.initPromise = _pinkie2.default.resolve(false); + + throw error; + } + })(); + } + + isLocalBrowser(browserId, browserName) { + var _this13 = this; + + return (0, _asyncToGenerator3.default)(function* () { + return yield _this13.plugin.isLocalBrowser(browserId, browserName); + })(); + } + + isHeadlessBrowser(browserId) { + return this.plugin.isHeadlessBrowser(browserId); + } + + openBrowser(browserId, pageUrl, browserName) { + var _this14 = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _this14.plugin.openBrowser(browserId, pageUrl, browserName); + + if (yield _this14._canUseDefaultWindowActions(browserId)) yield _this14._ensureBrowserWindowParameters(browserId); + })(); + } + + closeBrowser(browserId) { + var _this15 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const canUseDefaultWindowActions = yield _this15._canUseDefaultWindowActions(browserId); + const customActionsInfo = yield _this15.hasCustomActionForBrowser(browserId); + const hasCustomCloseBrowser = customActionsInfo.hasCloseBrowser; + const usePluginsCloseBrowser = hasCustomCloseBrowser || !canUseDefaultWindowActions; + + if (usePluginsCloseBrowser) yield _this15.plugin.closeBrowser(browserId);else yield _this15._closeLocalBrowser(browserId); + + if (canUseDefaultWindowActions) delete _this15.localBrowsersInfo[browserId]; + })(); + } + + getBrowserList() { + var _this16 = this; + + return (0, _asyncToGenerator3.default)(function* () { + return yield _this16.plugin.getBrowserList(); + })(); + } + + isValidBrowserName(browserName) { + var _this17 = this; + + return (0, _asyncToGenerator3.default)(function* () { + return yield _this17.plugin.isValidBrowserName(browserName); + })(); + } + + resizeWindow(browserId, width, height, currentWidth, currentHeight) { + var _this18 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const canUseDefaultWindowActions = yield _this18._canUseDefaultWindowActions(browserId); + const customActionsInfo = yield _this18.hasCustomActionForBrowser(browserId); + const hasCustomResizeWindow = customActionsInfo.hasResizeWindow; + + if (canUseDefaultWindowActions && !hasCustomResizeWindow) { + yield _this18._resizeLocalBrowserWindow(browserId, width, height, currentWidth, currentHeight); + return; + } + + yield _this18.plugin.resizeWindow(browserId, width, height, currentWidth, currentHeight); + })(); + } + + canResizeWindowToDimensions(browserId, width, height) { + var _this19 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const canUseDefaultWindowActions = yield _this19._canUseDefaultWindowActions(browserId); + const customActionsInfo = yield _this19.hasCustomActionForBrowser(browserId); + const hasCustomCanResizeToDimensions = customActionsInfo.hasCanResizeWindowToDimensions; + + if (canUseDefaultWindowActions && !hasCustomCanResizeToDimensions) return yield _this19._canResizeLocalBrowserWindowToDimensions(browserId, width, height); + + return yield _this19.plugin.canResizeWindowToDimensions(browserId, width, height); + })(); + } + + maximizeWindow(browserId) { + var _this20 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const canUseDefaultWindowActions = yield _this20._canUseDefaultWindowActions(browserId); + const customActionsInfo = yield _this20.hasCustomActionForBrowser(browserId); + const hasCustomMaximizeWindow = customActionsInfo.hasMaximizeWindow; + + if (canUseDefaultWindowActions && !hasCustomMaximizeWindow) return yield _this20._maximizeLocalBrowserWindow(browserId); + + return yield _this20.plugin.maximizeWindow(browserId); + })(); + } + + takeScreenshot(browserId, screenshotPath, pageWidth, pageHeight) { + var _this21 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const canUseDefaultWindowActions = yield _this21._canUseDefaultWindowActions(browserId); + const customActionsInfo = yield _this21.hasCustomActionForBrowser(browserId); + const hasCustomTakeScreenshot = customActionsInfo.hasTakeScreenshot; + + if (canUseDefaultWindowActions && !hasCustomTakeScreenshot) { + yield _this21._takeLocalBrowserScreenshot(browserId, screenshotPath, pageWidth, pageHeight); + return; + } + + yield _this21.plugin.takeScreenshot(browserId, screenshotPath, pageWidth, pageHeight); + })(); + } + + hasCustomActionForBrowser(browserId) { + var _this22 = this; + + return (0, _asyncToGenerator3.default)(function* () { + return _this22.plugin.hasCustomActionForBrowser(browserId); + })(); + } + + reportJobResult(browserId, status, data) { + var _this23 = this; + + return (0, _asyncToGenerator3.default)(function* () { + yield _this23.plugin.reportJobResult(browserId, status, data); + })(); + } +} +exports.default = BrowserProvider; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL2luZGV4LmpzIl0sIm5hbWVzIjpbIkJST1dTRVJfT1BFTklOR19ERUxBWSIsIlJFU0laRV9ESUZGX1NJWkUiLCJ3aWR0aCIsImhlaWdodCIsInN1bVNpemVzIiwic2l6ZUEiLCJzaXplQiIsInN1YnRyYWN0U2l6ZXMiLCJCcm93c2VyUHJvdmlkZXIiLCJjb25zdHJ1Y3RvciIsInBsdWdpbiIsImluaXRQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJpc011bHRpQnJvd3NlciIsImxvY2FsQnJvd3NlcnNJbmZvIiwiX2NyZWF0ZUxvY2FsQnJvd3NlckluZm8iLCJicm93c2VySWQiLCJ3aW5kb3dEZXNjcmlwdG9yIiwibWF4U2NyZWVuU2l6ZSIsInJlc2l6ZUNvcnJlY3Rpb25zIiwiX2dldFdpbmRvd0Rlc2NyaXB0b3IiLCJfZ2V0TWF4U2NyZWVuU2l6ZSIsIl9nZXRSZXNpemVDb3JyZWN0aW9ucyIsIl9pc0Jyb3dzZXJJZGxlIiwiY29ubmVjdGlvbiIsIkJyb3dzZXJDb25uZWN0aW9uIiwiZ2V0QnlJZCIsImlkbGUiLCJfY2FsY3VsYXRlUmVzaXplQ29ycmVjdGlvbnMiLCJ0aXRsZSIsInJ1bkluaXRTY3JpcHQiLCJHRVRfVElUTEVfU0NSSVBUIiwiYnJvd3NlclRvb2xzIiwiaXNNYXhpbWl6ZWQiLCJjdXJyZW50U2l6ZSIsIkdFVF9XSU5ET1dfRElNRU5TSU9OU19JTkZPX1NDUklQVCIsImV0YWxvblNpemUiLCJyZXNpemUiLCJyZXNpemVkU2l6ZSIsImNvcnJlY3Rpb25TaXplIiwibWF4aW1pemUiLCJfY2FsY3VsYXRlTWFjU2l6ZUxpbWl0cyIsInNpemVJbmZvIiwiYXZhaWxhYmxlV2lkdGgiLCJvdXRlcldpZHRoIiwiYXZhaWxhYmxlSGVpZ2h0Iiwib3V0ZXJIZWlnaHQiLCJfZW5zdXJlQnJvd3NlcldpbmRvd0Rlc2NyaXB0b3IiLCJ3YWl0Rm9yQ29ubmVjdGlvblJlYWR5IiwiZmluZFdpbmRvdyIsIl9lbnN1cmVCcm93c2VyV2luZG93UGFyYW1ldGVycyIsIk9TIiwid2luIiwibWFjIiwiX2Nsb3NlTG9jYWxCcm93c2VyIiwiY2xvc2UiLCJfcmVzaXplTG9jYWxCcm93c2VyV2luZG93IiwiY3VycmVudFdpZHRoIiwiY3VycmVudEhlaWdodCIsIl90YWtlTG9jYWxCcm93c2VyU2NyZWVuc2hvdCIsInNjcmVlbnNob3RQYXRoIiwic2NyZWVuc2hvdCIsIl9jYW5SZXNpemVMb2NhbEJyb3dzZXJXaW5kb3dUb0RpbWVuc2lvbnMiLCJfbWF4aW1pemVMb2NhbEJyb3dzZXJXaW5kb3ciLCJfY2FuVXNlRGVmYXVsdFdpbmRvd0FjdGlvbnMiLCJpc0xvY2FsQnJvd3NlciIsImlzSGVhZGxlc3NCcm93c2VyIiwiaW5pdCIsImluaXRpYWxpemVkIiwidGhlbiIsImVycm9yIiwiZGlzcG9zZSIsImJyb3dzZXJOYW1lIiwib3BlbkJyb3dzZXIiLCJwYWdlVXJsIiwiY2xvc2VCcm93c2VyIiwiY2FuVXNlRGVmYXVsdFdpbmRvd0FjdGlvbnMiLCJjdXN0b21BY3Rpb25zSW5mbyIsImhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIiLCJoYXNDdXN0b21DbG9zZUJyb3dzZXIiLCJoYXNDbG9zZUJyb3dzZXIiLCJ1c2VQbHVnaW5zQ2xvc2VCcm93c2VyIiwiZ2V0QnJvd3Nlckxpc3QiLCJpc1ZhbGlkQnJvd3Nlck5hbWUiLCJyZXNpemVXaW5kb3ciLCJoYXNDdXN0b21SZXNpemVXaW5kb3ciLCJoYXNSZXNpemVXaW5kb3ciLCJjYW5SZXNpemVXaW5kb3dUb0RpbWVuc2lvbnMiLCJoYXNDdXN0b21DYW5SZXNpemVUb0RpbWVuc2lvbnMiLCJoYXNDYW5SZXNpemVXaW5kb3dUb0RpbWVuc2lvbnMiLCJtYXhpbWl6ZVdpbmRvdyIsImhhc0N1c3RvbU1heGltaXplV2luZG93IiwiaGFzTWF4aW1pemVXaW5kb3ciLCJ0YWtlU2NyZWVuc2hvdCIsInBhZ2VXaWR0aCIsInBhZ2VIZWlnaHQiLCJoYXNDdXN0b21UYWtlU2NyZWVu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QUFpQ2hELFNBQWpDLENBQXpDO0FBQ0Esa0JBQU02RCxvQkFBNkIsTUFBTSxRQUFLQyx5QkFBTCxDQUErQjlELFNBQS9CLENBQXpDO0FBQ0Esa0JBQU1nRiwwQkFBNkJuQixrQkFBa0JvQixpQkFBckQ7O0FBRUEsZ0JBQUlyQiw4QkFBOEIsQ0FBQ29CLHVCQUFuQyxFQUE0RDtBQUN4RCxzQkFBTSxRQUFLckMsMkJBQUwsQ0FBaUMzQyxTQUFqQyxFQUE0QzRDLGNBQTVDLEVBQTREa0MsU0FBNUQsRUFBdUVDLFVBQXZFLENBQU47QUFDQTtBQUNIOztBQUVELGtCQUFNLFFBQUt0RixNQUFMLENBQVlvRixjQUFaLENBQTJCN0UsU0FBM0IsRUFBc0M0QyxjQUF0QyxFQUFzRGtDLFNBQXRELEVBQWlFQyxVQUFqRSxDQUFOO0FBVm9FO0FBV3ZFOztBQUVLakIsNkJBQU4sQ0FBaUM5RCxTQUFqQyxFQUE0QztBQUFBOztBQUFBO0FBQ3hDLG1CQUFPLFFBQUtQLE1BQUwsQ0FBWXFFLHlCQUFaLENBQXNDOUQsU0FBdEMsQ0FBUDtBQUR3QztBQUUzQzs7QUFFS2tGLG1CQUFOLENBQXVCbEYsU0FBdkIsRUFBa0NtRixNQUFsQyxFQUEwQ0MsSUFBMUMsRUFBZ0Q7QUFBQTs7QUFBQTtBQUM1QyxrQkFBTSxRQUFLM0YsTUFBTCxDQUFZeUYsZUFBWixDQUE0QmxGLFNBQTVCLEVBQXVDbUYsTUFBdkMsRUFBK0NDLElBQS9DLENBQU47QUFENEM7QUFFL0M7QUF6UmdDO2tCQUFoQjdGLGUiLCJmaWxlIjoiYnJvd3Nlci9wcm92aWRlci9pbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlIGZyb20gJ3BpbmtpZSc7XG5pbXBvcnQgYnJvd3NlclRvb2xzIGZyb20gJ3Rlc3RjYWZlLWJyb3dzZXItdG9vbHMnO1xuaW1wb3J0IE9TIGZyb20gJ29zLWZhbWlseSc7XG5pbXBvcnQgQnJvd3NlckNvbm5lY3Rpb24gZnJvbSAnLi4vY29ubmVjdGlvbic7XG5pbXBvcnQgZGVsYXkgZnJvbSAnLi4vLi4vdXRpbHMvZGVsYXknO1xuaW1wb3J0IHsgR0VUX1RJVExFX1NDUklQVCwgR0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUIH0gZnJvbSAnLi91dGlscy9jbGllbnQtZnVuY3Rpb25zJztcblxuXG5jb25zdCBCUk9XU0VSX09QRU5JTkdfREVMQVkgPSAyMDAwO1xuXG5jb25zdCBSRVNJWkVfRElGRl9TSVpFID0ge1xuICAgIHdpZHRoOiAgMTAwLFxuICAgIGhlaWdodDogMTAwXG59O1xuXG5cbmZ1bmN0aW9uIHN1bVNpemVzIChzaXplQSwgc2l6ZUIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB3aWR0aDogIHNpemVBLndpZHRoICsgc2l6ZUIud2lkdGgsXG4gICAgICAgIGhlaWdodDogc2l6ZUEuaGVpZ2h0ICsgc2l6ZUIuaGVpZ2h0XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gc3VidHJhY3RTaXplcyAoc2l6ZUEsIHNpemVCKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgd2lkdGg6ICBzaXplQS53aWR0aCAtIHNpemVCLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IHNpemVBLmhlaWdodCAtIHNpemVCLmhlaWdodFxuICAgIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJyb3dzZXJQcm92aWRlciB7XG4gICAgY29uc3RydWN0b3IgKHBsdWdpbikge1xuICAgICAgICB0aGlzLnBsdWdpbiAgICAgID0gcGx1Z2luO1xuICAgICAgICB0aGlzLmluaXRQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcblxuICAgICAgICB0aGlzLmlzTXVsdGlCcm93c2VyID0gdGhpcy5wbHVnaW4uaXNNdWx0aUJyb3dzZXI7XG4gICAgICAgIC8vIEhBQ0s6IFRoZSBicm93c2VyIHdpbmRvdyBoYXMgZGlmZmVyZW50IGJvcmRlciBzaXplcyBpbiBub3JtYWwgYW5kIG1heGltaXplZCBtb2Rlcy4gU28sIHdlIG5lZWQgdG8gYmUgc3VyZSB0aGF0IHRoZSB3aW5kb3cgaXNcbiAgICAgICAgLy8gbm90IG1heGltaXplZCBiZWZvcmUgcmVzaXppbmcgaXQgaW4gb3JkZXIgdG8ga2VlcCB0aGUgbWVjaGFuaXNtIG9mIGNvcnJlY3RpbmcgdGhlIGNsaWVudCBhcmVhIHNpemUgd29ya2luZy4gV2hlbiBicm93c2VyIGlzIHN0YXJ0ZWQsXG4gICAgICAgIC8vIHdlIGFyZSByZXNpemluZyBpdCBmb3IgdGhlIGZpcnN0IHRpbWUgdG8gc3dpdGNoIHRoZSB3aW5kb3cgdG8gbm9ybWFsIG1vZGUsIGFuZCBmb3IgdGhlIHNlY29uZCB0aW1lIC0gdG8gcmVzdG9yZSB0aGUgY2xpZW50IGFyZWEgc2l6ZS5cbiAgICAgICAgdGhpcy5sb2NhbEJyb3dzZXJzSW5mbyA9IHt9O1xuICAgIH1cblxuICAgIF9jcmVhdGVMb2NhbEJyb3dzZXJJbmZvIChicm93c2VySWQpIHtcbiAgICAgICAgaWYgKHRoaXMubG9jYWxCcm93c2Vyc0luZm9bYnJvd3NlcklkXSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0aGlzLmxvY2FsQnJvd3NlcnNJbmZvW2Jyb3dzZXJJZF0gPSB7XG4gICAgICAgICAgICB3aW5kb3dEZXNjcmlwdG9yOiAgbnVsbCxcbiAgICAgICAgICAgIG1heFNjcmVlblNpemU6ICAgICBudWxsLFxuICAgICAgICAgICAgcmVzaXplQ29ycmVjdGlvbnM6IG51bGxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBfZ2V0V2luZG93RGVzY3JpcHRvciAoYnJvd3NlcklkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsQnJvd3NlcnNJbmZvW2Jyb3dzZXJJZF0gJiYgdGhpcy5sb2NhbEJyb3dzZXJzSW5mb1ticm93c2VySWRdLndpbmRvd0Rlc2NyaXB0b3I7XG4gICAgfVxuXG4gICAgX2dldE1heFNjcmVlblNpemUgKGJyb3dzZXJJZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NhbEJyb3dzZXJzSW5mb1ticm93c2VySWRdICYmIHRoaXMubG9jYWxCcm93c2Vyc0luZm9bYnJvd3NlcklkXS5tYXhTY3JlZW5TaXplO1xuICAgIH1cblxuICAgIF9nZXRSZXNpemVDb3JyZWN0aW9ucyAoYnJvd3NlcklkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2FsQnJvd3NlcnNJbmZvW2Jyb3dzZXJJZF0gJiYgdGhpcy5sb2NhbEJyb3dzZXJzSW5mb1ticm93c2VySWRdLnJlc2l6ZUNvcnJlY3Rpb25zO1xuICAgIH1cblxuICAgIF9pc0Jyb3dzZXJJZGxlIChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IEJyb3dzZXJDb25uZWN0aW9uLmdldEJ5SWQoYnJvd3NlcklkKTtcblxuICAgICAgICByZXR1cm4gY29ubmVjdGlvbi5pZGxlO1xuICAgIH1cblxuICAgIGFzeW5jIF9jYWxjdWxhdGVSZXNpemVDb3JyZWN0aW9ucyAoYnJvd3NlcklkKSB7XG4gICAgICAgIGlmICghdGhpcy5faXNCcm93c2VySWRsZShicm93c2VySWQpKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHRpdGxlID0gYXdhaXQgdGhpcy5wbHVnaW4ucnVuSW5pdFNjcmlwdChicm93c2VySWQsIEdFVF9USVRMRV9TQ1JJUFQpO1xuXG4gICAgICAgIGlmICghYXdhaXQgYnJvd3NlclRvb2xzLmlzTWF4aW1pemVkKHRpdGxlKSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCBjdXJyZW50U2l6ZSA9IGF3YWl0IHRoaXMucGx1Z2luLnJ1bkluaXRTY3JpcHQoYnJvd3NlcklkLCBHRVRfV0lORE9XX0RJTUVOU0lPTlNfSU5GT19TQ1JJUFQpO1xuICAgICAgICBjb25zdCBldGFsb25TaXplICA9IHN1YnRyYWN0U2l6ZXMoY3VycmVudFNpemUsIFJFU0laRV9ESUZGX1NJWkUpO1xuXG4gICAgICAgIGF3YWl0IGJyb3dzZXJUb29scy5yZXNpemUodGl0bGUsIGN1cnJlbnRTaXplLndpZHRoLCBjdXJyZW50U2l6ZS5oZWlnaHQsIGV0YWxvblNpemUud2lkdGgsIGV0YWxvblNpemUuaGVpZ2h0KTtcblxuICAgICAgICBsZXQgcmVzaXplZFNpemUgICAgPSBhd2FpdCB0aGlzLnBsdWdpbi5ydW5Jbml0U2NyaXB0KGJyb3dzZXJJZCwgR0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUKTtcbiAgICAgICAgbGV0IGNvcnJlY3Rpb25TaXplID0gc3VidHJhY3RTaXplcyhyZXNpemVkU2l6ZSwgZXRhbG9uU2l6ZSk7XG5cbiAgICAgICAgYXdhaXQgYnJvd3NlclRvb2xzLnJlc2l6ZSh0aXRsZSwgcmVzaXplZFNpemUud2lkdGgsIHJlc2l6ZWRTaXplLmhlaWdodCwgZXRhbG9uU2l6ZS53aWR0aCwgZXRhbG9uU2l6ZS5oZWlnaHQpO1xuXG4gICAgICAgIHJlc2l6ZWRTaXplID0gYXdhaXQgdGhpcy5wbHVnaW4ucnVuSW5pdFNjcmlwdChicm93c2VySWQsIEdFVF9XSU5ET1dfRElNRU5TSU9OU19JTkZPX1NDUklQVCk7XG5cbiAgICAgICAgY29ycmVjdGlvblNpemUgPSBzdW1TaXplcyhjb3JyZWN0aW9uU2l6ZSwgc3VidHJhY3RTaXplcyhyZXNpemVkU2l6ZSwgZXRhbG9uU2l6ZSkpO1xuXG4gICAgICAgIGlmICh0aGlzLmxvY2FsQnJvd3NlcnNJbmZvW2Jyb3dzZXJJZF0pXG4gICAgICAgICAgICB0aGlzLmxvY2FsQnJvd3NlcnNJbmZvW2Jyb3dzZXJJZF0ucmVzaXplQ29ycmVjdGlvbnMgPSBjb3JyZWN0aW9uU2l6ZTtcblxuICAgICAgICBhd2FpdCBicm93c2VyVG9vbHMubWF4aW1pemUodGl0bGUpO1xuICAgIH1cblxuXG4gICAgYXN5bmMgX2NhbGN1bGF0ZU1hY1NpemVMaW1pdHMgKGJyb3dzZXJJZCkge1xuICAgICAgICBpZiAoIXRoaXMuX2lzQnJvd3NlcklkbGUoYnJvd3NlcklkKSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCBzaXplSW5mbyA9IGF3YWl0IHRoaXMucGx1Z2luLnJ1bkluaXRTY3JpcHQoYnJvd3NlcklkLCBHRVRfV0lORE9XX0RJTUVOU0lPTlNfSU5GT19TQ1JJUFQpO1xuXG4gICAgICAgIGlmICh0aGlzLmxvY2FsQnJvd3NlcnNJbmZvW2Jyb3dzZXJJZF0pIHtcbiAgICAgICAgICAgIHRoaXMubG9jYWxCcm93c2Vyc0luZm9bYnJvd3NlcklkXS5tYXhTY3JlZW5TaXplID0ge1xuICAgICAgICAgICAgICAgIHdpZHRoOiAgc2l6ZUluZm8uYXZhaWxhYmxlV2lkdGggLSAoc2l6ZUluZm8ub3V0ZXJXaWR0aCAtIHNpemVJbmZvLndpZHRoKSxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHNpemVJbmZvLmF2YWlsYWJsZUhlaWdodCAtIChzaXplSW5mby5vdXRlckhlaWdodCAtIHNpemVJbmZvLmhlaWdodClcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBfZW5zdXJlQnJvd3NlcldpbmRvd0Rlc2NyaXB0b3IgKGJyb3dzZXJJZCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0V2luZG93RGVzY3JpcHRvcihicm93c2VySWQpKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuX2NyZWF0ZUxvY2FsQnJvd3NlckluZm8oYnJvd3NlcklkKTtcblxuICAgICAgICAvLyBOT1RFOiBkZWxheSB0byBlbnN1cmUgdGhlIHdpbmRvdyBmaW5pc2hlZCB0aGUgb3BlbmluZ1xuICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi53YWl0Rm9yQ29ubmVjdGlvblJlYWR5KGJyb3dzZXJJZCk7XG4gICAgICAgIGF3YWl0IGRlbGF5KEJST1dTRVJfT1BFTklOR19ERUxBWSk7XG5cbiAgICAgICAgaWYgKHRoaXMubG9jYWxCcm93c2Vyc0luZm9bYnJvd3NlcklkXSlcbiAgICAgICAgICAgIHRoaXMubG9jYWxCcm93c2Vyc0luZm9bYnJvd3NlcklkXS53aW5kb3dEZXNjcmlwdG9yID0gYXdhaXQgYnJvd3NlclRvb2xzLmZpbmRXaW5kb3coYnJvd3NlcklkKTtcbiAgICB9XG5cbiAgICBhc3luYyBfZW5zdXJlQnJvd3NlcldpbmRvd1BhcmFtZXRlcnMgKGJyb3dzZXJJZCkge1xuICAgICAgICBhd2FpdCB0aGlzLl9lbnN1cmVCcm93c2VyV2luZG93RGVzY3JpcHRvcihicm93c2VySWQpO1xuXG4gICAgICAgIGlmIChPUy53aW4gJiYgIXRoaXMuX2dldFJlc2l6ZUNvcnJlY3Rpb25zKGJyb3dzZXJJZCkpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9jYWxjdWxhdGVSZXNpemVDb3JyZWN0aW9ucyhicm93c2VySWQpO1xuICAgICAgICBlbHNlIGlmIChPUy5tYWMgJiYgIXRoaXMuX2dldE1heFNjcmVlblNpemUoYnJvd3NlcklkKSlcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2NhbGN1bGF0ZU1hY1NpemVMaW1pdHMoYnJvd3NlcklkKTtcbiAgICB9XG5cbiAgICBhc3luYyBfY2xvc2VMb2NhbEJyb3dzZXIgKGJyb3dzZXJJZCkge1xuICAgICAgICBhd2FpdCBicm93c2VyVG9vbHMuY2xvc2UodGhpcy5fZ2V0V2luZG93RGVzY3JpcHRvcihicm93c2VySWQpKTtcbiAgICB9XG5cbiAgICBhc3luYyBfcmVzaXplTG9jYWxCcm93c2VyV2luZG93IChicm93c2VySWQsIHdpZHRoLCBoZWlnaHQsIGN1cnJlbnRXaWR0aCwgY3VycmVudEhlaWdodCkge1xuICAgICAgICBjb25zdCByZXNpemVDb3JyZWN0aW9ucyA9IHRoaXMuX2dldFJlc2l6ZUNvcnJlY3Rpb25zKGJyb3dzZXJJZCk7XG5cbiAgICAgICAgaWYgKHJlc2l6ZUNvcnJlY3Rpb25zICYmIGF3YWl0IGJyb3dzZXJUb29scy5pc01heGltaXplZCh0aGlzLl9nZXRXaW5kb3dEZXNjcmlwdG9yKGJyb3dzZXJJZCkpKSB7XG4gICAgICAgICAgICB3aWR0aCAtPSByZXNpemVDb3JyZWN0aW9ucy53aWR0aDtcbiAgICAgICAgICAgIGhlaWdodCAtPSByZXNpemVDb3JyZWN0aW9ucy5oZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCBicm93c2VyVG9vbHMucmVzaXplKHRoaXMuX2dldFdpbmRvd0Rlc2NyaXB0b3IoYnJvd3NlcklkKSwgY3VycmVudFdpZHRoLCBjdXJyZW50SGVpZ2h0LCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB9XG5cbiAgICBhc3luYyBfdGFrZUxvY2FsQnJvd3NlclNjcmVlbnNob3QgKGJyb3dzZXJJZCwgc2NyZWVuc2hvdFBhdGgpIHtcbiAgICAgICAgYXdhaXQgYnJvd3NlclRvb2xzLnNjcmVlbnNob3QodGhpcy5fZ2V0V2luZG93RGVzY3JpcHRvcihicm93c2VySWQpLCBzY3JlZW5zaG90UGF0aCk7XG4gICAgfVxuXG4gICAgYXN5bmMgX2NhblJlc2l6ZUxvY2FsQnJvd3NlcldpbmRvd1RvRGltZW5zaW9ucyAoYnJvd3NlcklkLCB3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgIGlmICghT1MubWFjKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgY29uc3QgbWF4U2NyZWVuU2l6ZSA9IHRoaXMuX2dldE1heFNjcmVlblNpemUoYnJvd3NlcklkKTtcblxuICAgICAgICByZXR1cm4gd2lkdGggPD0gbWF4U2NyZWVuU2l6ZS53aWR0aCAmJiBoZWlnaHQgPD0gbWF4U2NyZWVuU2l6ZS5oZWlnaHQ7XG4gICAgfVxuXG4gICAgYXN5bmMgX21heGltaXplTG9jYWxCcm93c2VyV2luZG93IChicm93c2VySWQpIHtcbiAgICAgICAgYXdhaXQgYnJvd3NlclRvb2xzLm1heGltaXplKHRoaXMuX2dldFdpbmRvd0Rlc2NyaXB0b3IoYnJvd3NlcklkKSk7XG4gICAgfVxuXG4gICAgYXN5bmMgX2NhblVzZURlZmF1bHRXaW5kb3dBY3Rpb25zIChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgaXNMb2NhbEJyb3dzZXIgICAgPSBhd2FpdCB0aGlzLnBsdWdpbi5pc0xvY2FsQnJvd3Nlcihicm93c2VySWQpO1xuICAgICAgICBjb25zdCBpc0hlYWRsZXNzQnJvd3NlciA9IGF3YWl0IHRoaXMucGx1Z2luLmlzSGVhZGxlc3NCcm93c2VyKGJyb3dzZXJJZCk7XG5cbiAgICAgICAgcmV0dXJuIGlzTG9jYWxCcm93c2VyICYmICFpc0hlYWRsZXNzQnJvd3NlcjtcbiAgICB9XG5cbiAgICBhc3luYyBpbml0ICgpIHtcbiAgICAgICAgY29uc3QgaW5pdGlhbGl6ZWQgPSBhd2FpdCB0aGlzLmluaXRQcm9taXNlO1xuXG4gICAgICAgIGlmIChpbml0aWFsaXplZClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0aGlzLmluaXRQcm9taXNlID0gdGhpcy5wbHVnaW5cbiAgICAgICAgICAgIC5pbml0KClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRydWUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmluaXRQcm9taXNlO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhpcy5pbml0UHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG5cbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZGlzcG9zZSAoKSB7XG4gICAgICAgIGNvbnN0IGluaXRpYWxpemVkID0gYXdhaXQgdGhpcy5pbml0UHJvbWlzZTtcblxuICAgICAgICBpZiAoIWluaXRpYWxpemVkKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMuaW5pdFByb21pc2UgPSB0aGlzLnBsdWdpblxuICAgICAgICAgICAgLmRpc3Bvc2UoKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gZmFsc2UpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmluaXRQcm9taXNlO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhpcy5pbml0UHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG5cbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgaXNMb2NhbEJyb3dzZXIgKGJyb3dzZXJJZCwgYnJvd3Nlck5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucGx1Z2luLmlzTG9jYWxCcm93c2VyKGJyb3dzZXJJZCwgYnJvd3Nlck5hbWUpO1xuICAgIH1cblxuICAgIGlzSGVhZGxlc3NCcm93c2VyIChicm93c2VySWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGx1Z2luLmlzSGVhZGxlc3NCcm93c2VyKGJyb3dzZXJJZCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb3BlbkJyb3dzZXIgKGJyb3dzZXJJZCwgcGFnZVVybCwgYnJvd3Nlck5hbWUpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4ub3BlbkJyb3dzZXIoYnJvd3NlcklkLCBwYWdlVXJsLCBicm93c2VyTmFtZSk7XG5cbiAgICAgICAgaWYgKGF3YWl0IHRoaXMuX2NhblVzZURlZmF1bHRXaW5kb3dBY3Rpb25zKGJyb3dzZXJJZCkpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9lbnN1cmVCcm93c2VyV2luZG93UGFyYW1ldGVycyhicm93c2VySWQpO1xuICAgIH1cblxuICAgIGFzeW5jIGNsb3NlQnJvd3NlciAoYnJvd3NlcklkKSB7XG4gICAgICAgIGNvbnN0IGNhblVzZURlZmF1bHRXaW5kb3dBY3Rpb25zID0gYXdhaXQgdGhpcy5fY2FuVXNlRGVmYXVsdFdpbmRvd0FjdGlvbnMoYnJvd3NlcklkKTtcbiAgICAgICAgY29uc3QgY3VzdG9tQWN0aW9uc0luZm8gICAgICAgICAgPSBhd2FpdCB0aGlzLmhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIoYnJvd3NlcklkKTtcbiAgICAgICAgY29uc3QgaGFzQ3VzdG9tQ2xvc2VCcm93c2VyICAgICAgPSBjdXN0b21BY3Rpb25zSW5mby5oYXNDbG9zZUJyb3dzZXI7XG4gICAgICAgIGNvbnN0IHVzZVBsdWdpbnNDbG9zZUJyb3dzZXIgICAgID0gaGFzQ3VzdG9tQ2xvc2VCcm93c2VyIHx8ICFjYW5Vc2VEZWZhdWx0V2luZG93QWN0aW9ucztcblxuICAgICAgICBpZiAodXNlUGx1Z2luc0Nsb3NlQnJvd3NlcilcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLmNsb3NlQnJvd3Nlcihicm93c2VySWQpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9jbG9zZUxvY2FsQnJvd3Nlcihicm93c2VySWQpO1xuXG4gICAgICAgIGlmIChjYW5Vc2VEZWZhdWx0V2luZG93QWN0aW9ucylcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmxvY2FsQnJvd3NlcnNJbmZvW2Jyb3dzZXJJZF07XG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0QnJvd3Nlckxpc3QgKCkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5wbHVnaW4uZ2V0QnJvd3Nlckxpc3QoKTtcbiAgICB9XG5cbiAgICBhc3luYyBpc1ZhbGlkQnJvd3Nlck5hbWUgKGJyb3dzZXJOYW1lKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnBsdWdpbi5pc1ZhbGlkQnJvd3Nlck5hbWUoYnJvd3Nlck5hbWUpO1xuICAgIH1cblxuICAgIGFzeW5jIHJlc2l6ZVdpbmRvdyAoYnJvd3NlcklkLCB3aWR0aCwgaGVpZ2h0LCBjdXJyZW50V2lkdGgsIGN1cnJlbnRIZWlnaHQpIHtcbiAgICAgICAgY29uc3QgY2FuVXNlRGVmYXVsdFdpbmRvd0FjdGlvbnMgPSBhd2FpdCB0aGlzLl9jYW5Vc2VEZWZhdWx0V2luZG93QWN0aW9ucyhicm93c2VySWQpO1xuICAgICAgICBjb25zdCBjdXN0b21BY3Rpb25zSW5mbyAgICAgICAgICA9IGF3YWl0IHRoaXMuaGFzQ3VzdG9tQWN0aW9uRm9yQnJvd3Nlcihicm93c2VySWQpO1xuICAgICAgICBjb25zdCBoYXNDdXN0b21SZXNpemVXaW5kb3cgICAgICA9IGN1c3RvbUFjdGlvbnNJbmZvLmhhc1Jlc2l6ZVdpbmRvdztcblxuXG4gICAgICAgIGlmIChjYW5Vc2VEZWZhdWx0V2luZG93QWN0aW9ucyAmJiAhaGFzQ3VzdG9tUmVzaXplV2luZG93KSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9yZXNpemVMb2NhbEJyb3dzZXJXaW5kb3coYnJvd3NlcklkLCB3aWR0aCwgaGVpZ2h0LCBjdXJyZW50V2lkdGgsIGN1cnJlbnRIZWlnaHQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4ucmVzaXplV2luZG93KGJyb3dzZXJJZCwgd2lkdGgsIGhlaWdodCwgY3VycmVudFdpZHRoLCBjdXJyZW50SGVpZ2h0KTtcbiAgICB9XG5cbiAgICBhc3luYyBjYW5SZXNpemVXaW5kb3dUb0RpbWVuc2lvbnMgKGJyb3dzZXJJZCwgd2lkdGgsIGhlaWdodCkge1xuICAgICAgICBjb25zdCBjYW5Vc2VEZWZhdWx0V2luZG93QWN0aW9ucyAgICAgPSBhd2FpdCB0aGlzLl9jYW5Vc2VEZWZhdWx0V2luZG93QWN0aW9ucyhicm93c2VySWQpO1xuICAgICAgICBjb25zdCBjdXN0b21BY3Rpb25zSW5mbyAgICAgICAgICAgICAgPSBhd2FpdCB0aGlzLmhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIoYnJvd3NlcklkKTtcbiAgICAgICAgY29uc3QgaGFzQ3VzdG9tQ2FuUmVzaXplVG9EaW1lbnNpb25zID0gY3VzdG9tQWN0aW9uc0luZm8uaGFzQ2FuUmVzaXplV2luZG93VG9EaW1lbnNpb25zO1xuXG5cbiAgICAgICAgaWYgKGNhblVzZURlZmF1bHRXaW5kb3dBY3Rpb25zICYmICFoYXNDdXN0b21DYW5SZXNpemVUb0RpbWVuc2lvbnMpXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fY2FuUmVzaXplTG9jYWxCcm93c2VyV2luZG93VG9EaW1lbnNpb25zKGJyb3dzZXJJZCwgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucGx1Z2luLmNhblJlc2l6ZVdpbmRvd1RvRGltZW5zaW9ucyhicm93c2VySWQsIHdpZHRoLCBoZWlnaHQpO1xuICAgIH1cblxuICAgIGFzeW5jIG1heGltaXplV2luZG93IChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgY2FuVXNlRGVmYXVsdFdpbmRvd0FjdGlvbnMgPSBhd2FpdCB0aGlzLl9jYW5Vc2VEZWZhdWx0V2luZG93QWN0aW9ucyhicm93c2VySWQpO1xuICAgICAgICBjb25zdCBjdXN0b21BY3Rpb25zSW5mbyAgICAgICAgICA9IGF3YWl0IHRoaXMuaGFzQ3VzdG9tQWN0aW9uRm9yQnJvd3Nlcihicm93c2VySWQpO1xuICAgICAgICBjb25zdCBoYXNDdXN0b21NYXhpbWl6ZVdpbmRvdyAgICA9IGN1c3RvbUFjdGlvbnNJbmZvLmhhc01heGltaXplV2luZG93O1xuXG4gICAgICAgIGlmIChjYW5Vc2VEZWZhdWx0V2luZG93QWN0aW9ucyAmJiAhaGFzQ3VzdG9tTWF4aW1pemVXaW5kb3cpXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fbWF4aW1pemVMb2NhbEJyb3dzZXJXaW5kb3coYnJvd3NlcklkKTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5wbHVnaW4ubWF4aW1pemVXaW5kb3coYnJvd3NlcklkKTtcbiAgICB9XG5cbiAgICBhc3luYyB0YWtlU2NyZWVuc2hvdCAoYnJvd3NlcklkLCBzY3JlZW5zaG90UGF0aCwgcGFnZVdpZHRoLCBwYWdlSGVpZ2h0KSB7XG4gICAgICAgIGNvbnN0IGNhblVzZURlZmF1bHRXaW5kb3dBY3Rpb25zID0gYXdhaXQgdGhpcy5fY2FuVXNlRGVmYXVsdFdpbmRvd0FjdGlvbnMoYnJvd3NlcklkKTtcbiAgICAgICAgY29uc3QgY3VzdG9tQWN0aW9uc0luZm8gICAgICAgICAgPSBhd2FpdCB0aGlzLmhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIoYnJvd3NlcklkKTtcbiAgICAgICAgY29uc3QgaGFzQ3VzdG9tVGFrZVNjcmVlbnNob3QgICAgPSBjdXN0b21BY3Rpb25zSW5mby5oYXNUYWtlU2NyZWVuc2hvdDtcblxuICAgICAgICBpZiAoY2FuVXNlRGVmYXVsdFdpbmRvd0FjdGlvbnMgJiYgIWhhc0N1c3RvbVRha2VTY3JlZW5zaG90KSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl90YWtlTG9jYWxCcm93c2VyU2NyZWVuc2hvdChicm93c2VySWQsIHNjcmVlbnNob3RQYXRoLCBwYWdlV2lkdGgsIHBhZ2VIZWlnaHQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4udGFrZVNjcmVlbnNob3QoYnJvd3NlcklkLCBzY3JlZW5zaG90UGF0aCwgcGFnZVdpZHRoLCBwYWdlSGVpZ2h0KTtcbiAgICB9XG5cbiAgICBhc3luYyBoYXNDdXN0b21BY3Rpb25Gb3JCcm93c2VyIChicm93c2VySWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGx1Z2luLmhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIoYnJvd3NlcklkKTtcbiAgICB9XG5cbiAgICBhc3luYyByZXBvcnRKb2JSZXN1bHQgKGJyb3dzZXJJZCwgc3RhdHVzLCBkYXRhKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnJlcG9ydEpvYlJlc3VsdChicm93c2VySWQsIHN0YXR1cywgZGF0YSk7XG4gICAgfVxufVxuIl19 diff --git a/lib/browser/provider/parse-provider-name.js b/lib/browser/provider/parse-provider-name.js new file mode 100644 index 00000000..0076b216 --- /dev/null +++ b/lib/browser/provider/parse-provider-name.js @@ -0,0 +1,26 @@ +'use strict'; + +exports.__esModule = true; + +exports.default = function (providerName) { + var _BROWSER_PROVIDER_NAM = BROWSER_PROVIDER_NAME_RE.exec(providerName); + + let scope = _BROWSER_PROVIDER_NAM[1], + name = _BROWSER_PROVIDER_NAM[2]; + + + if (!scope) scope = ''; + + if (name.indexOf(BROWSER_PROVIDER_MODULE_NAME_PREFIX) === 0) name = name.replace(BROWSER_PROVIDER_MODULE_NAME_PREFIX, ''); + + return { + providerName: scope + name, + moduleName: scope + BROWSER_PROVIDER_MODULE_NAME_PREFIX + name + }; +}; + +const BROWSER_PROVIDER_NAME_RE = /^(@(?:[^/]+)\/)?(.+)$/; +const BROWSER_PROVIDER_MODULE_NAME_PREFIX = 'testcafe-browser-provider-'; + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL3BhcnNlLXByb3ZpZGVyLW5hbWUuanMiXSwibmFtZXMiOlsicHJvdmlkZXJOYW1lIiwiQlJPV1NFUl9QUk9WSURFUl9OQU1FX1JFIiwiZXhlYyIsInNjb3BlIiwibmFtZSIsImluZGV4T2YiLCJCUk9XU0VSX1BST1ZJREVSX01PRFVMRV9OQU1FX1BSRUZJWCIsInJlcGxhY2UiLCJtb2R1bGVOYW1lIl0sIm1hcHBpbmdzIjoiOzs7O2tCQUllLFVBQVVBLFlBQVYsRUFBd0I7QUFBQSxnQ0FDWEMseUJBQXlCQyxJQUF6QixDQUE4QkYsWUFBOUIsQ0FEVzs7QUFBQSxRQUMzQkcsS0FEMkI7QUFBQSxRQUNwQkMsSUFEb0I7OztBQUduQyxRQUFJLENBQUNELEtBQUwsRUFDSUEsUUFBUSxFQUFSOztBQUVKLFFBQUlDLEtBQUtDLE9BQUwsQ0FBYUMsbUNBQWIsTUFBc0QsQ0FBMUQsRUFDSUYsT0FBT0EsS0FBS0csT0FBTCxDQUFhRCxtQ0FBYixFQUFrRCxFQUFsRCxDQUFQOztBQUVKLFdBQU87QUFDSE4sc0JBQWNHLFFBQVFDLElBRG5CO0FBRUhJLG9CQUFjTCxRQUFRRyxtQ0FBUixHQUE4Q0Y7QUFGekQsS0FBUDtBQUlILEM7O0FBakJELE1BQU1ILDJCQUFzQyx1QkFBNUM7QUFDQSxNQUFNSyxzQ0FBc0MsNEJBQTVDIiwiZmlsZSI6ImJyb3dzZXIvcHJvdmlkZXIvcGFyc2UtcHJvdmlkZXItbmFtZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IEJST1dTRVJfUFJPVklERVJfTkFNRV9SRSAgICAgICAgICAgID0gL14oQCg/OlteL10rKVxcLyk/KC4rKSQvO1xuY29uc3QgQlJPV1NFUl9QUk9WSURFUl9NT0RVTEVfTkFNRV9QUkVGSVggPSAndGVzdGNhZmUtYnJvd3Nlci1wcm92aWRlci0nO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChwcm92aWRlck5hbWUpIHtcbiAgICBsZXQgWyAsIHNjb3BlLCBuYW1lIF0gPSBCUk9XU0VSX1BST1ZJREVSX05BTUVfUkUuZXhlYyhwcm92aWRlck5hbWUpO1xuXG4gICAgaWYgKCFzY29wZSlcbiAgICAgICAgc2NvcGUgPSAnJztcblxuICAgIGlmIChuYW1lLmluZGV4T2YoQlJPV1NFUl9QUk9WSURFUl9NT0RVTEVfTkFNRV9QUkVGSVgpID09PSAwKVxuICAgICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKEJST1dTRVJfUFJPVklERVJfTU9EVUxFX05BTUVfUFJFRklYLCAnJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBwcm92aWRlck5hbWU6IHNjb3BlICsgbmFtZSxcbiAgICAgICAgbW9kdWxlTmFtZTogICBzY29wZSArIEJST1dTRVJfUFJPVklERVJfTU9EVUxFX05BTUVfUFJFRklYICsgbmFtZVxuICAgIH07XG59XG4iXX0= diff --git a/lib/browser/provider/plugin-host.js b/lib/browser/provider/plugin-host.js new file mode 100644 index 00000000..4fa69583 --- /dev/null +++ b/lib/browser/provider/plugin-host.js @@ -0,0 +1,203 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _symbol = require('babel-runtime/core-js/symbol'); + +var _symbol2 = _interopRequireDefault(_symbol); + +var _pinkie = require('pinkie'); + +var _pinkie2 = _interopRequireDefault(_pinkie); + +var _lodash = require('lodash'); + +var _promisifyEvent = require('promisify-event'); + +var _promisifyEvent2 = _interopRequireDefault(_promisifyEvent); + +var _browserJobResult = require('../../runner/browser-job-result'); + +var _browserJobResult2 = _interopRequireDefault(_browserJobResult); + +var _connection = require('../connection'); + +var _connection2 = _interopRequireDefault(_connection); + +var _warningMessage = require('../../notifications/warning-message'); + +var _warningMessage2 = _interopRequireDefault(_warningMessage); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* global Symbol */ +const name = (0, _symbol2.default)(); + +class BrowserProviderPluginHost { + constructor(providerObject, providerName) { + this.JOB_RESULT = (0, _lodash.assignIn)({}, _browserJobResult2.default); + + (0, _lodash.assignIn)(this, providerObject); + + this[name] = providerName; + } + + // Helpers + get providerName() { + return this[name]; + } + + runInitScript(browserId, code) { + const connection = _connection2.default.getById(browserId); + + return connection.runInitScript(`(${code})()`); + } + + waitForConnectionReady(browserId) { + const connection = _connection2.default.getById(browserId); + + if (connection.ready) return _pinkie2.default.resolve(); + + return (0, _promisifyEvent2.default)(connection, 'ready'); + } + + reportWarning(browserId, ...args) { + const connection = _connection2.default.getById(browserId); + + connection.addWarning(...args); + } + + setUserAgentMetaInfo(browserId, message) { + const connection = _connection2.default.getById(browserId); + + connection.setProviderMetaInfo(message); + } + + closeLocalBrowser(browserId) { + return (0, _asyncToGenerator3.default)(function* () { + const connection = _connection2.default.getById(browserId); + + yield connection.provider._ensureBrowserWindowDescriptor(browserId); + yield connection.provider._closeLocalBrowser(browserId); + })(); + } + + resizeLocalBrowserWindow(browserId, width, height, currentWidth, currentHeight) { + return (0, _asyncToGenerator3.default)(function* () { + const connection = _connection2.default.getById(browserId); + + yield connection.provider._ensureBrowserWindowParameters(browserId); + yield connection.provider._resizeLocalBrowserWindow(browserId, width, height, currentWidth, currentHeight); + })(); + } + + // API + // Browser control + openBrowser() /* browserId, pageUrl, browserName */{ + return (0, _asyncToGenerator3.default)(function* () { + throw new Error('Not implemented!'); + })(); + } + + closeBrowser() /* browserId */{ + return (0, _asyncToGenerator3.default)(function* () { + throw new Error('Not implemented!'); + })(); + } + + // Initialization + init() { + return (0, _asyncToGenerator3.default)(function* () { + return; + })(); + } + + dispose() { + return (0, _asyncToGenerator3.default)(function* () { + return; + })(); + } + + // Browser names handling + getBrowserList() { + return (0, _asyncToGenerator3.default)(function* () { + throw new Error('Not implemented!'); + })(); + } + + isValidBrowserName() /* browserName */{ + return (0, _asyncToGenerator3.default)(function* () { + return true; + })(); + } + + // Extra functions + // NOTE: The browserName argument is optional, and must be supplied if the browserId argument is not valid (browser is not opened) + isLocalBrowser() /* browserId[, browserName] */{ + return (0, _asyncToGenerator3.default)(function* () { + return false; + })(); + } + + isHeadlessBrowser() /* browserId */{ + return false; + } + + hasCustomActionForBrowser() /* browserId */{ + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + return { + hasCloseBrowser: _this.hasOwnProperty('closeBrowser'), + hasResizeWindow: _this.hasOwnProperty('resizeWindow'), + hasTakeScreenshot: _this.hasOwnProperty('takeScreenshot'), + hasCanResizeWindowToDimensions: _this.hasOwnProperty('canResizeWindowToDimensions'), + hasMaximizeWindow: _this.hasOwnProperty('maximizeWindow'), + hasChromelessScreenshots: false + }; + })(); + } + + resizeWindow(browserId /*, width, height, currentWidth, currentHeight */) { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this2.reportWarning(browserId, _warningMessage2.default.resizeNotSupportedByBrowserProvider, _this2[name]); + })(); + } + + canResizeWindowToDimensions() /* browserId, width, height */{ + return (0, _asyncToGenerator3.default)(function* () { + return true; + })(); + } + + takeScreenshot(browserId /*, screenshotPath, pageWidth, pageHeight */) { + var _this3 = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this3.reportWarning(browserId, _warningMessage2.default.screenshotNotSupportedByBrowserProvider, _this3[name]); + })(); + } + + maximizeWindow(browserId) { + var _this4 = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this4.reportWarning(browserId, _warningMessage2.default.maximizeNotSupportedByBrowserProvider, _this4[name]); + })(); + } + + reportJobResult() /*browserId, status, data*/{ + return (0, _asyncToGenerator3.default)(function* () { + return; + })(); + } +} +exports.default = BrowserProviderPluginHost; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL3BsdWdpbi1ob3N0LmpzIl0sIm5hbWVzIjpbIm5hbWUiLCJCcm93c2VyUHJvdmlkZXJQbHVnaW5Ib3N0IiwiY29uc3RydWN0b3IiLCJwcm92aWRlck9iamVjdCIsInByb3ZpZGVyTmFtZSIsIkpPQl9SRVNVTFQiLCJCUk9XU0VSX0pPQl9SRVNVTFQiLCJydW5Jbml0U2NyaXB0IiwiYnJvd3NlcklkIiwiY29kZSIsImNvbm5lY3Rpb24iLCJCcm93c2VyQ29ubmVjdGlvbiIsImdldEJ5SWQiLCJ3YWl0Rm9yQ29ubmVjdGlvblJlYWR5IiwicmVhZHkiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlcG9ydFdhcm5pbmciLCJhcmdzIiwiYWRkV2FybmluZyIsInNldFVzZXJBZ2VudE1ldGFJbmZvIiwibWVzc2FnZSIsInNldFByb3ZpZGVyTWV0YUluZm8iLCJjbG9zZUxvY2FsQnJvd3NlciIsInByb3ZpZGVyIiwiX2Vuc3VyZUJyb3dzZXJXaW5kb3dEZXNjcmlwdG9yIiwiX2Nsb3NlTG9jYWxCcm93c2VyIiwicmVzaXplTG9jYWxCcm93c2VyV2luZG93Iiwid2lkdGgiLCJoZWlnaHQiLCJjdXJyZW50V2lkdGgiLCJjdXJyZW50SGVpZ2h0IiwiX2Vuc3VyZUJyb3dzZXJXaW5kb3dQYXJhbWV0ZXJzIiwiX3Jlc2l6ZUxvY2FsQnJvd3NlcldpbmRvdyIsIm9wZW5Ccm93c2VyIiwiRXJyb3IiLCJjbG9zZUJyb3dzZXIiLCJpbml0IiwiZGlzcG9zZSIsImdldEJyb3dzZXJMaXN0IiwiaXNWYWxpZEJyb3dzZXJOYW1lIiwiaXNMb2NhbEJyb3dzZXIiLCJpc0hlYWRsZXNzQnJvd3NlciIsImhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIiLCJoYXNDbG9zZUJyb3dzZXIiLCJoYXNPd25Qcm9wZXJ0eSIsImhhc1Jlc2l6ZVdpbmRvdyIsImhhc1Rha2VTY3JlZW5zaG90IiwiaGFzQ2FuUmVzaXplV2luZG93VG9EaW1lbnNpb25zIiwiaGFzTWF4aW1pemVXaW5kb3ciLCJoYXNDaHJvbWVsZXNzU2NyZWVuc2hvdHMiLCJyZXNpemVXaW5kb3ciLCJXQVJOSU5HX01FU1NBR0UiLCJyZXNpemVOb3RTdXBwb3J0ZWRCeUJyb3dzZXJQcm92aWRlciIsImNhblJlc2l6ZVdpbmRvd1RvRGltZW5zaW9ucyIsInRha2VTY3JlZW5zaG90Iiwic2NyZWVuc2hvdE5vdFN1cHBvcnRlZEJ5QnJvd3NlclByb3ZpZGVyIiwibWF4aW1pemVXaW5kb3ciLCJtYXhpbWl6ZU5vdFN1cHBvcnRlZEJ5QnJvd3NlclByb3ZpZGVyIiwicmVwb3J0Sm9iUmVzdWx0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFDQTs7OztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7QUFOQTtBQVNBLE1BQU1BLE9BQU8sdUJBQWI7O0FBRWUsTUFBTUMseUJBQU4sQ0FBZ0M7QUFDM0NDLGdCQUFhQyxjQUFiLEVBQTZCQyxZQUE3QixFQUEyQztBQUN2QyxhQUFLQyxVQUFMLEdBQWtCLHNCQUFTLEVBQVQsRUFBYUMsMEJBQWIsQ0FBbEI7O0FBRUEsOEJBQVMsSUFBVCxFQUFlSCxjQUFmOztBQUVBLGFBQUtILElBQUwsSUFBYUksWUFBYjtBQUNIOztBQUdEO0FBQ0EsUUFBSUEsWUFBSixHQUFvQjtBQUNoQixlQUFPLEtBQUtKLElBQUwsQ0FBUDtBQUNIOztBQUVETyxrQkFBZUMsU0FBZixFQUEwQkMsSUFBMUIsRUFBZ0M7QUFDNUIsY0FBTUMsYUFBYUMscUJBQWtCQyxPQUFsQixDQUEwQkosU0FBMUIsQ0FBbkI7O0FBRUEsZUFBT0UsV0FBV0gsYUFBWCxDQUEwQixJQUFHRSxJQUFLLEtBQWxDLENBQVA7QUFDSDs7QUFFREksMkJBQXdCTCxTQUF4QixFQUFtQztBQUMvQixjQUFNRSxhQUFhQyxxQkFBa0JDLE9BQWxCLENBQTBCSixTQUExQixDQUFuQjs7QUFFQSxZQUFJRSxXQUFXSSxLQUFmLEVBQ0ksT0FBT0MsaUJBQVFDLE9BQVIsRUFBUDs7QUFFSixl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TixHQUFtQyw4QkFBZ0M7QUFBQTtBQUMvRCxtQkFBTyxJQUFQO0FBRCtEO0FBRWxFOztBQUVLQyxrQkFBTixDQUFzQi9DLFNBQXRCLENBQStCLDRDQUEvQixFQUE2RTtBQUFBOztBQUFBO0FBQ3pFLG1CQUFLUyxhQUFMLENBQW1CVCxTQUFuQixFQUE4QjRDLHlCQUFnQkksdUNBQTlDLEVBQXVGLE9BQUt4RCxJQUFMLENBQXZGO0FBRHlFO0FBRTVFOztBQUVLeUQsa0JBQU4sQ0FBc0JqRCxTQUF0QixFQUFpQztBQUFBOztBQUFBO0FBQzdCLG1CQUFLUyxhQUFMLENBQW1CVCxTQUFuQixFQUE4QjRDLHlCQUFnQk0scUNBQTlDLEVBQXFGLE9BQUsxRCxJQUFMLENBQXJGO0FBRDZCO0FBRWhDOztBQUVLMkQsbUJBQU4sR0FBdUIsMkJBQTZCO0FBQUE7QUFDaEQ7QUFEZ0Q7QUFFbkQ7QUE1SDBDO2tCQUExQjFELHlCIiwiZmlsZSI6ImJyb3dzZXIvcHJvdmlkZXIvcGx1Z2luLWhvc3QuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBnbG9iYWwgU3ltYm9sICovXG5pbXBvcnQgUHJvbWlzZSBmcm9tICdwaW5raWUnO1xuaW1wb3J0IHsgYXNzaWduSW4gfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHByb21pc2lmeUV2ZW50IGZyb20gJ3Byb21pc2lmeS1ldmVudCc7XG5pbXBvcnQgQlJPV1NFUl9KT0JfUkVTVUxUIGZyb20gJy4uLy4uL3J1bm5lci9icm93c2VyLWpvYi1yZXN1bHQnO1xuaW1wb3J0IEJyb3dzZXJDb25uZWN0aW9uIGZyb20gJy4uL2Nvbm5lY3Rpb24nO1xuaW1wb3J0IFdBUk5JTkdfTUVTU0FHRSBmcm9tICcuLi8uLi9ub3RpZmljYXRpb25zL3dhcm5pbmctbWVzc2FnZSc7XG5cblxuY29uc3QgbmFtZSA9IFN5bWJvbCgpO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCcm93c2VyUHJvdmlkZXJQbHVnaW5Ib3N0IHtcbiAgICBjb25zdHJ1Y3RvciAocHJvdmlkZXJPYmplY3QsIHByb3ZpZGVyTmFtZSkge1xuICAgICAgICB0aGlzLkpPQl9SRVNVTFQgPSBhc3NpZ25Jbih7fSwgQlJPV1NFUl9KT0JfUkVTVUxUKTtcblxuICAgICAgICBhc3NpZ25Jbih0aGlzLCBwcm92aWRlck9iamVjdCk7XG5cbiAgICAgICAgdGhpc1tuYW1lXSA9IHByb3ZpZGVyTmFtZTtcbiAgICB9XG5cblxuICAgIC8vIEhlbHBlcnNcbiAgICBnZXQgcHJvdmlkZXJOYW1lICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbbmFtZV07XG4gICAgfVxuXG4gICAgcnVuSW5pdFNjcmlwdCAoYnJvd3NlcklkLCBjb2RlKSB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBCcm93c2VyQ29ubmVjdGlvbi5nZXRCeUlkKGJyb3dzZXJJZCk7XG5cbiAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb24ucnVuSW5pdFNjcmlwdChgKCR7Y29kZX0pKClgKTtcbiAgICB9XG5cbiAgICB3YWl0Rm9yQ29ubmVjdGlvblJlYWR5IChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IEJyb3dzZXJDb25uZWN0aW9uLmdldEJ5SWQoYnJvd3NlcklkKTtcblxuICAgICAgICBpZiAoY29ubmVjdGlvbi5yZWFkeSlcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgICAgICByZXR1cm4gcHJvbWlzaWZ5RXZlbnQoY29ubmVjdGlvbiwgJ3JlYWR5Jyk7XG4gICAgfVxuXG4gICAgcmVwb3J0V2FybmluZyAoYnJvd3NlcklkLCAuLi5hcmdzKSB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBCcm93c2VyQ29ubmVjdGlvbi5nZXRCeUlkKGJyb3dzZXJJZCk7XG5cbiAgICAgICAgY29ubmVjdGlvbi5hZGRXYXJuaW5nKC4uLmFyZ3MpO1xuICAgIH1cblxuICAgIHNldFVzZXJBZ2VudE1ldGFJbmZvIChicm93c2VySWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IEJyb3dzZXJDb25uZWN0aW9uLmdldEJ5SWQoYnJvd3NlcklkKTtcblxuICAgICAgICBjb25uZWN0aW9uLnNldFByb3ZpZGVyTWV0YUluZm8obWVzc2FnZSk7XG4gICAgfVxuXG4gICAgYXN5bmMgY2xvc2VMb2NhbEJyb3dzZXIgKGJyb3dzZXJJZCkge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gQnJvd3NlckNvbm5lY3Rpb24uZ2V0QnlJZChicm93c2VySWQpO1xuXG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucHJvdmlkZXIuX2Vuc3VyZUJyb3dzZXJXaW5kb3dEZXNjcmlwdG9yKGJyb3dzZXJJZCk7XG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucHJvdmlkZXIuX2Nsb3NlTG9jYWxCcm93c2VyKGJyb3dzZXJJZCk7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVzaXplTG9jYWxCcm93c2VyV2luZG93IChicm93c2VySWQsIHdpZHRoLCBoZWlnaHQsIGN1cnJlbnRXaWR0aCwgY3VycmVudEhlaWdodCkge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gQnJvd3NlckNvbm5lY3Rpb24uZ2V0QnlJZChicm93c2VySWQpO1xuXG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucHJvdmlkZXIuX2Vuc3VyZUJyb3dzZXJXaW5kb3dQYXJhbWV0ZXJzKGJyb3dzZXJJZCk7XG4gICAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucHJvdmlkZXIuX3Jlc2l6ZUxvY2FsQnJvd3NlcldpbmRvdyhicm93c2VySWQsIHdpZHRoLCBoZWlnaHQsIGN1cnJlbnRXaWR0aCwgY3VycmVudEhlaWdodCk7XG4gICAgfVxuXG4gICAgLy8gQVBJXG4gICAgLy8gQnJvd3NlciBjb250cm9sXG4gICAgYXN5bmMgb3BlbkJyb3dzZXIgKC8qIGJyb3dzZXJJZCwgcGFnZVVybCwgYnJvd3Nlck5hbWUgKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQhJyk7XG4gICAgfVxuXG4gICAgYXN5bmMgY2xvc2VCcm93c2VyICgvKiBicm93c2VySWQgKi8pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQhJyk7XG4gICAgfVxuXG4gICAgLy8gSW5pdGlhbGl6YXRpb25cbiAgICBhc3luYyBpbml0ICgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGFzeW5jIGRpc3Bvc2UgKCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG5cbiAgICAvLyBCcm93c2VyIG5hbWVzIGhhbmRsaW5nXG4gICAgYXN5bmMgZ2V0QnJvd3Nlckxpc3QgKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCEnKTtcbiAgICB9XG5cbiAgICBhc3luYyBpc1ZhbGlkQnJvd3Nlck5hbWUgKC8qIGJyb3dzZXJOYW1lICovKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIEV4dHJhIGZ1bmN0aW9uc1xuICAgIC8vIE5PVEU6IFRoZSBicm93c2VyTmFtZSBhcmd1bWVudCBpcyBvcHRpb25hbCwgYW5kIG11c3QgYmUgc3VwcGxpZWQgaWYgdGhlIGJyb3dzZXJJZCBhcmd1bWVudCBpcyBub3QgdmFsaWQgKGJyb3dzZXIgaXMgbm90IG9wZW5lZClcbiAgICBhc3luYyBpc0xvY2FsQnJvd3NlciAoLyogYnJvd3NlcklkWywgYnJvd3Nlck5hbWVdICovKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpc0hlYWRsZXNzQnJvd3NlciAoLyogYnJvd3NlcklkICovKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBhc3luYyBoYXNDdXN0b21BY3Rpb25Gb3JCcm93c2VyICgvKiBicm93c2VySWQgKi8pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhhc0Nsb3NlQnJvd3NlcjogICAgICAgICAgICAgICAgdGhpcy5oYXNPd25Qcm9wZXJ0eSgnY2xvc2VCcm93c2VyJyksXG4gICAgICAgICAgICBoYXNSZXNpemVXaW5kb3c6ICAgICAgICAgICAgICAgIHRoaXMuaGFzT3duUHJvcGVydHkoJ3Jlc2l6ZVdpbmRvdycpLFxuICAgICAgICAgICAgaGFzVGFrZVNjcmVlbnNob3Q6ICAgICAgICAgICAgICB0aGlzLmhhc093blByb3BlcnR5KCd0YWtlU2NyZWVuc2hvdCcpLFxuICAgICAgICAgICAgaGFzQ2FuUmVzaXplV2luZG93VG9EaW1lbnNpb25zOiB0aGlzLmhhc093blByb3BlcnR5KCdjYW5SZXNpemVXaW5kb3dUb0RpbWVuc2lvbnMnKSxcbiAgICAgICAgICAgIGhhc01heGltaXplV2luZG93OiAgICAgICAgICAgICAgdGhpcy5oYXNPd25Qcm9wZXJ0eSgnbWF4aW1pemVXaW5kb3cnKSxcbiAgICAgICAgICAgIGhhc0Nocm9tZWxlc3NTY3JlZW5zaG90czogICAgICAgZmFsc2VcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBhc3luYyByZXNpemVXaW5kb3cgKGJyb3dzZXJJZC8qLCB3aWR0aCwgaGVpZ2h0LCBjdXJyZW50V2lkdGgsIGN1cnJlbnRIZWlnaHQgKi8pIHtcbiAgICAgICAgdGhpcy5yZXBvcnRXYXJuaW5nKGJyb3dzZXJJZCwgV0FSTklOR19NRVNTQUdFLnJlc2l6ZU5vdFN1cHBvcnRlZEJ5QnJvd3NlclByb3ZpZGVyLCB0aGlzW25hbWVdKTtcbiAgICB9XG5cbiAgICBhc3luYyBjYW5SZXNpemVXaW5kb3dUb0RpbWVuc2lvbnMgKC8qIGJyb3dzZXJJZCwgd2lkdGgsIGhlaWdodCAqLykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBhc3luYyB0YWtlU2NyZWVuc2hvdCAoYnJvd3NlcklkLyosIHNjcmVlbnNob3RQYXRoLCBwYWdlV2lkdGgsIHBhZ2VIZWlnaHQgKi8pIHtcbiAgICAgICAgdGhpcy5yZXBvcnRXYXJuaW5nKGJyb3dzZXJJZCwgV0FSTklOR19NRVNTQUdFLnNjcmVlbnNob3ROb3RTdXBwb3J0ZWRCeUJyb3dzZXJQcm92aWRlciwgdGhpc1tuYW1lXSk7XG4gICAgfVxuXG4gICAgYXN5bmMgbWF4aW1pemVXaW5kb3cgKGJyb3dzZXJJZCkge1xuICAgICAgICB0aGlzLnJlcG9ydFdhcm5pbmcoYnJvd3NlcklkLCBXQVJOSU5HX01FU1NBR0UubWF4aW1pemVOb3RTdXBwb3J0ZWRCeUJyb3dzZXJQcm92aWRlciwgdGhpc1tuYW1lXSk7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVwb3J0Sm9iUmVzdWx0ICgvKmJyb3dzZXJJZCwgc3RhdHVzLCBkYXRhKi8pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbn1cbiJdfQ== diff --git a/lib/browser/provider/pool.js b/lib/browser/provider/pool.js new file mode 100644 index 00000000..a41c3b6d --- /dev/null +++ b/lib/browser/provider/pool.js @@ -0,0 +1,195 @@ +'use strict'; + +exports.__esModule = true; + +var _values = require('babel-runtime/core-js/object/values'); + +var _values2 = _interopRequireDefault(_values); + +var _stringify = require('babel-runtime/core-js/json/stringify'); + +var _stringify2 = _interopRequireDefault(_stringify); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _pinkie = require('pinkie'); + +var _pinkie2 = _interopRequireDefault(_pinkie); + +var _builtIn = require('./built-in'); + +var _builtIn2 = _interopRequireDefault(_builtIn); + +var _pluginHost = require('./plugin-host'); + +var _pluginHost2 = _interopRequireDefault(_pluginHost); + +var _parseProviderName = require('./parse-provider-name'); + +var _parseProviderName2 = _interopRequireDefault(_parseProviderName); + +var _ = require('./'); + +var _2 = _interopRequireDefault(_); + +var _connection = require('../connection'); + +var _connection2 = _interopRequireDefault(_connection); + +var _runtime = require('../../errors/runtime'); + +var _message = require('../../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const BROWSER_PROVIDER_RE = /^([^:\s]+):?(.*)?$/; + +exports.default = { + providersCache: {}, + + _handlePathAndCmd(alias) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + const browserName = (0, _stringify2.default)(alias); + const providerName = 'path'; + const provider = yield _this.getProvider(providerName); + + return { provider, providerName, browserName }; + })(); + }, + + _parseAliasString(alias) { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const providerRegExpMatch = BROWSER_PROVIDER_RE.exec(alias); + + if (!providerRegExpMatch) throw new _runtime.GeneralError(_message2.default.cantFindBrowser, alias); + + let providerName = providerRegExpMatch[1]; + let browserName = providerRegExpMatch[2] || ''; + + let provider = yield _this2.getProvider(providerName); + + if (!provider && providerRegExpMatch[2]) provider = yield _this2.getProvider(providerName + ':'); + + if (!provider) { + providerName = 'locally-installed'; + provider = yield _this2.getProvider(providerName); + browserName = providerRegExpMatch[1] || ''; + } + + return { provider, providerName, browserName }; + })(); + }, + + _parseAlias(alias) { + var _this3 = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (alias && alias.path) return _this3._handlePathAndCmd(alias); + + if (typeof alias === 'string') return _this3._parseAliasString(alias); + + throw new _runtime.GeneralError(_message2.default.cantFindBrowser, alias); + })(); + }, + + _getInfoForAllBrowserNames(provider, providerName) { + return (0, _asyncToGenerator3.default)(function* () { + const allBrowserNames = provider.isMultiBrowser ? yield provider.getBrowserList() : []; + + if (!allBrowserNames.length) return { provider, providerName, browserName: '' }; + + return allBrowserNames.map(function (browserName) { + return { provider, providerName, browserName }; + }); + })(); + }, + + _getProviderModule(providerName, moduleName) { + try { + const providerObject = require(moduleName); + + this.addProvider(providerName, providerObject); + return this._getProviderFromCache(providerName); + } catch (e) { + return null; + } + }, + + _getProviderFromCache(providerName) { + return this.providersCache[providerName] || null; + }, + + _getBuiltinProvider(providerName) { + const providerObject = _builtIn2.default[providerName]; + + if (!providerObject) return null; + + this.addProvider(providerName, providerObject); + + return this._getProviderFromCache(providerName); + }, + + getBrowserInfo(alias) { + var _this4 = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (alias instanceof _connection2.default) return alias; + + const browserInfo = yield _this4._parseAlias(alias); + + const provider = browserInfo.provider, + providerName = browserInfo.providerName, + browserName = browserInfo.browserName; + + + if (browserName === 'all') return yield _this4._getInfoForAllBrowserNames(provider, providerName); + + if (!(yield provider.isValidBrowserName(browserName))) throw new _runtime.GeneralError(_message2.default.cantFindBrowser, alias); + + return browserInfo; + })(); + }, + + addProvider(providerName, providerObject) { + providerName = (0, _parseProviderName2.default)(providerName).providerName; + + this.providersCache[providerName] = new _2.default(new _pluginHost2.default(providerObject, providerName)); + }, + + removeProvider(providerName) { + providerName = (0, _parseProviderName2.default)(providerName).providerName; + + delete this.providersCache[providerName]; + }, + + getProvider(providerName) { + var _this5 = this; + + return (0, _asyncToGenerator3.default)(function* () { + const parsedProviderName = (0, _parseProviderName2.default)(providerName); + const moduleName = parsedProviderName.moduleName; + + providerName = parsedProviderName.providerName; + + const provider = _this5._getProviderFromCache(providerName) || _this5._getProviderModule(providerName, moduleName) || _this5._getBuiltinProvider(providerName); + + if (provider) yield _this5.providersCache[providerName].init(); + + return provider; + })(); + }, + + dispose() { + return _pinkie2.default.all((0, _values2.default)(this.providersCache).map(item => item.dispose())); + } +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL3Bvb2wuanMiXSwibmFtZXMiOlsiQlJPV1NFUl9QUk9WSURFUl9SRSIsInByb3ZpZGVyc0NhY2hlIiwiX2hhbmRsZVBhdGhBbmRDbWQiLCJhbGlhcyIsImJyb3dzZXJOYW1lIiwicHJvdmlkZXJOYW1lIiwicHJvdmlkZXIiLCJnZXRQcm92aWRlciIsIl9wYXJzZUFsaWFzU3RyaW5nIiwicHJvdmlkZXJSZWdFeHBNYXRjaCIsImV4ZWMiLCJHZW5lcmFsRXJyb3IiLCJNRVNTQUdFIiwiY2FudEZpbmRCcm93c2VyIiwiX3BhcnNlQWxpYXMiLCJwYXRoIiwiX2dldEluZm9Gb3JBbGxCcm93c2VyTmFtZXMiLCJhbGxCcm93c2VyTmFtZXMiLCJpc011bHRpQnJvd3NlciIsImdldEJyb3dzZXJMaXN0IiwibGVuZ3RoIiwibWFwIiwiX2dldFByb3ZpZGVyTW9kdWxlIiwibW9kdWxlTmFtZSIsInByb3ZpZGVyT2JqZWN0IiwicmVxdWlyZSIsImFkZFByb3ZpZGVyIiwiX2dldFByb3ZpZGVyRnJvbUNhY2hlIiwiZSIsIl9nZXRCdWlsdGluUHJvdmlkZXIiLCJCVUlMVF9JTl9QUk9WSURFUlMiLCJnZXRCcm93c2VySW5mbyIsIkJyb3dzZXJDb25uZWN0aW9uIiwiYnJvd3NlckluZm8iLCJpc1ZhbGlkQnJvd3Nlck5hbWUiLCJCcm93c2VyUHJvdmlkZXIiLCJCcm93c2VyUHJvdmlkZXJQbHVnaW5Ib3N0IiwicmVtb3ZlUHJvdmlkZXIiLCJwYXJzZWRQcm92aWRlck5hbWUiLCJpbml0IiwiZGlzcG9zZSIsIlByb21pc2UiLCJhbGwiLCJpdGVtIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLE1BQU1BLHNCQUFzQixvQkFBNUI7O2tCQUVlO0FBQ1hDLG9CQUFnQixFQURMOztBQUdMQyxxQkFB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QkFBZ0JoQyxZQUFoQixFQUE4QjtBQUMxQkEsdUJBQWUsaUNBQWtCQSxZQUFsQixFQUFnQ0EsWUFBL0M7O0FBRUEsZUFBTyxLQUFLSixjQUFMLENBQW9CSSxZQUFwQixDQUFQO0FBQ0gsS0FoSFU7O0FBa0hMRSxlQUFOLENBQW1CRixZQUFuQixFQUFpQztBQUFBOztBQUFBO0FBQzdCLGtCQUFNaUMscUJBQXFCLGlDQUFrQmpDLFlBQWxCLENBQTNCO0FBQ0Esa0JBQU1rQixhQUFxQmUsbUJBQW1CZixVQUE5Qzs7QUFFQWxCLDJCQUFlaUMsbUJBQW1CakMsWUFBbEM7O0FBRUEsa0JBQU1DLFdBQVcsT0FBS3FCLHFCQUFMLENBQTJCdEIsWUFBM0IsS0FDRixPQUFLaUIsa0JBQUwsQ0FBd0JqQixZQUF4QixFQUFzQ2tCLFVBQXRDLENBREUsSUFFRixPQUFLTSxtQkFBTCxDQUF5QnhCLFlBQXpCLENBRmY7O0FBSUEsZ0JBQUlDLFFBQUosRUFDSSxNQUFNLE9BQUtMLGNBQUwsQ0FBb0JJLFlBQXBCLEVBQWtDa0MsSUFBbEMsRUFBTjs7QUFFSixtQkFBT2pDLFFBQVA7QUFiNkI7QUFjaEMsS0FoSVU7O0FBa0lYa0MsY0FBVztBQUNQLGVBQU9DLGlCQUFRQyxHQUFSLENBQVksc0JBQWMsS0FBS3pDLGNBQW5CLEVBQW1Db0IsR0FBbkMsQ0FBdUNzQixRQUFRQSxLQUFLSCxPQUFMLEVBQS9DLENBQVosQ0FBUDtBQUNIO0FBcElVLEMiLCJmaWxlIjoiYnJvd3Nlci9wcm92aWRlci9wb29sLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFByb21pc2UgZnJvbSAncGlua2llJztcbmltcG9ydCBCVUlMVF9JTl9QUk9WSURFUlMgZnJvbSAnLi9idWlsdC1pbic7XG5pbXBvcnQgQnJvd3NlclByb3ZpZGVyUGx1Z2luSG9zdCBmcm9tICcuL3BsdWdpbi1ob3N0JztcbmltcG9ydCBwYXJzZVByb3ZpZGVyTmFtZSBmcm9tICcuL3BhcnNlLXByb3ZpZGVyLW5hbWUnO1xuaW1wb3J0IEJyb3dzZXJQcm92aWRlciBmcm9tICcuLyc7XG5pbXBvcnQgQnJvd3NlckNvbm5lY3Rpb24gZnJvbSAnLi4vY29ubmVjdGlvbic7XG5pbXBvcnQgeyBHZW5lcmFsRXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgTUVTU0FHRSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZS9tZXNzYWdlJztcblxuY29uc3QgQlJPV1NFUl9QUk9WSURFUl9SRSA9IC9eKFteOlxcc10rKTo/KC4qKT8kLztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAgIHByb3ZpZGVyc0NhY2hlOiB7fSxcblxuICAgIGFzeW5jIF9oYW5kbGVQYXRoQW5kQ21kIChhbGlhcykge1xuICAgICAgICBjb25zdCBicm93c2VyTmFtZSAgPSBKU09OLnN0cmluZ2lmeShhbGlhcyk7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVyTmFtZSA9ICdwYXRoJztcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgICAgID0gYXdhaXQgdGhpcy5nZXRQcm92aWRlcihwcm92aWRlck5hbWUpO1xuXG4gICAgICAgIHJldHVybiB7IHByb3ZpZGVyLCBwcm92aWRlck5hbWUsIGJyb3dzZXJOYW1lIH07XG4gICAgfSxcblxuICAgIGFzeW5jIF9wYXJzZUFsaWFzU3RyaW5nIChhbGlhcykge1xuICAgICAgICBjb25zdCBwcm92aWRlclJlZ0V4cE1hdGNoID0gQlJPV1NFUl9QUk9WSURFUl9SRS5leGVjKGFsaWFzKTtcblxuICAgICAgICBpZiAoIXByb3ZpZGVyUmVnRXhwTWF0Y2gpXG4gICAgICAgICAgICB0aHJvdyBuZXcgR2VuZXJhbEVycm9yKE1FU1NBR0UuY2FudEZpbmRCcm93c2VyLCBhbGlhcyk7XG5cbiAgICAgICAgbGV0IHByb3ZpZGVyTmFtZSA9IHByb3ZpZGVyUmVnRXhwTWF0Y2hbMV07XG4gICAgICAgIGxldCBicm93c2VyTmFtZSAgPSBwcm92aWRlclJlZ0V4cE1hdGNoWzJdIHx8ICcnO1xuXG4gICAgICAgIGxldCBwcm92aWRlciA9IGF3YWl0IHRoaXMuZ2V0UHJvdmlkZXIocHJvdmlkZXJOYW1lKTtcblxuICAgICAgICBpZiAoIXByb3ZpZGVyICYmIHByb3ZpZGVyUmVnRXhwTWF0Y2hbMl0pXG4gICAgICAgICAgICBwcm92aWRlciA9IGF3YWl0IHRoaXMuZ2V0UHJvdmlkZXIocHJvdmlkZXJOYW1lICsgJzonKTtcblxuICAgICAgICBpZiAoIXByb3ZpZGVyKSB7XG4gICAgICAgICAgICBwcm92aWRlck5hbWUgPSAnbG9jYWxseS1pbnN0YWxsZWQnO1xuICAgICAgICAgICAgcHJvdmlkZXIgICAgID0gYXdhaXQgdGhpcy5nZXRQcm92aWRlcihwcm92aWRlck5hbWUpO1xuICAgICAgICAgICAgYnJvd3Nlck5hbWUgID0gcHJvdmlkZXJSZWdFeHBNYXRjaFsxXSB8fCAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IHByb3ZpZGVyLCBwcm92aWRlck5hbWUsIGJyb3dzZXJOYW1lIH07XG4gICAgfSxcblxuICAgIGFzeW5jIF9wYXJzZUFsaWFzIChhbGlhcykge1xuICAgICAgICBpZiAoYWxpYXMgJiYgYWxpYXMucGF0aClcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVQYXRoQW5kQ21kKGFsaWFzKTtcblxuICAgICAgICBpZiAodHlwZW9mIGFsaWFzID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXJzZUFsaWFzU3RyaW5nKGFsaWFzKTtcblxuICAgICAgICB0aHJvdyBuZXcgR2VuZXJhbEVycm9yKE1FU1NBR0UuY2FudEZpbmRCcm93c2VyLCBhbGlhcyk7XG4gICAgfSxcblxuICAgIGFzeW5jIF9nZXRJbmZvRm9yQWxsQnJvd3Nlck5hbWVzIChwcm92aWRlciwgcHJvdmlkZXJOYW1lKSB7XG4gICAgICAgIGNvbnN0IGFsbEJyb3dzZXJOYW1lcyA9IHByb3ZpZGVyLmlzTXVsdGlCcm93c2VyID9cbiAgICAgICAgICAgIGF3YWl0IHByb3ZpZGVyLmdldEJyb3dzZXJMaXN0KCkgOlxuICAgICAgICAgICAgW107XG5cbiAgICAgICAgaWYgKCFhbGxCcm93c2VyTmFtZXMubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIHsgcHJvdmlkZXIsIHByb3ZpZGVyTmFtZSwgYnJvd3Nlck5hbWU6ICcnIH07XG5cbiAgICAgICAgcmV0dXJuIGFsbEJyb3dzZXJOYW1lc1xuICAgICAgICAgICAgLm1hcChicm93c2VyTmFtZSA9PiAoeyBwcm92aWRlciwgcHJvdmlkZXJOYW1lLCBicm93c2VyTmFtZSB9KSk7XG4gICAgfSxcblxuICAgIF9nZXRQcm92aWRlck1vZHVsZSAocHJvdmlkZXJOYW1lLCBtb2R1bGVOYW1lKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwcm92aWRlck9iamVjdCA9IHJlcXVpcmUobW9kdWxlTmFtZSk7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkUHJvdmlkZXIocHJvdmlkZXJOYW1lLCBwcm92aWRlck9iamVjdCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0UHJvdmlkZXJGcm9tQ2FjaGUocHJvdmlkZXJOYW1lKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgX2dldFByb3ZpZGVyRnJvbUNhY2hlIChwcm92aWRlck5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvdmlkZXJzQ2FjaGVbcHJvdmlkZXJOYW1lXSB8fCBudWxsO1xuICAgIH0sXG5cbiAgICBfZ2V0QnVpbHRpblByb3ZpZGVyIChwcm92aWRlck5hbWUpIHtcbiAgICAgICAgY29uc3QgcHJvdmlkZXJPYmplY3QgPSBCVUlMVF9JTl9QUk9WSURFUlNbcHJvdmlkZXJOYW1lXTtcblxuICAgICAgICBpZiAoIXByb3ZpZGVyT2JqZWN0KVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgdGhpcy5hZGRQcm92aWRlcihwcm92aWRlck5hbWUsIHByb3ZpZGVyT2JqZWN0KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0UHJvdmlkZXJGcm9tQ2FjaGUocHJvdmlkZXJOYW1lKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0QnJvd3NlckluZm8gKGFsaWFzKSB7XG4gICAgICAgIGlmIChhbGlhcyBpbnN0YW5jZW9mIEJyb3dzZXJDb25uZWN0aW9uKVxuICAgICAgICAgICAgcmV0dXJuIGFsaWFzO1xuXG4gICAgICAgIGNvbnN0IGJyb3dzZXJJbmZvID0gYXdhaXQgdGhpcy5fcGFyc2VBbGlhcyhhbGlhcyk7XG5cbiAgICAgICAgY29uc3QgeyBwcm92aWRlciwgcHJvdmlkZXJOYW1lLCBicm93c2VyTmFtZSB9ID0gYnJvd3NlckluZm87XG5cbiAgICAgICAgaWYgKGJyb3dzZXJOYW1lID09PSAnYWxsJylcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9nZXRJbmZvRm9yQWxsQnJvd3Nlck5hbWVzKHByb3ZpZGVyLCBwcm92aWRlck5hbWUpO1xuXG4gICAgICAgIGlmICghYXdhaXQgcHJvdmlkZXIuaXNWYWxpZEJyb3dzZXJOYW1lKGJyb3dzZXJOYW1lKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBHZW5lcmFsRXJyb3IoTUVTU0FHRS5jYW50RmluZEJyb3dzZXIsIGFsaWFzKTtcblxuICAgICAgICByZXR1cm4gYnJvd3NlckluZm87XG4gICAgfSxcblxuICAgIGFkZFByb3ZpZGVyIChwcm92aWRlck5hbWUsIHByb3ZpZGVyT2JqZWN0KSB7XG4gICAgICAgIHByb3ZpZGVyTmFtZSA9IHBhcnNlUHJvdmlkZXJOYW1lKHByb3ZpZGVyTmFtZSkucHJvdmlkZXJOYW1lO1xuXG4gICAgICAgIHRoaXMucHJvdmlkZXJzQ2FjaGVbcHJvdmlkZXJOYW1lXSA9IG5ldyBCcm93c2VyUHJvdmlkZXIoXG4gICAgICAgICAgICBuZXcgQnJvd3NlclByb3ZpZGVyUGx1Z2luSG9zdChwcm92aWRlck9iamVjdCwgcHJvdmlkZXJOYW1lKVxuICAgICAgICApO1xuICAgIH0sXG5cbiAgICByZW1vdmVQcm92aWRlciAocHJvdmlkZXJOYW1lKSB7XG4gICAgICAgIHByb3ZpZGVyTmFtZSA9IHBhcnNlUHJvdmlkZXJOYW1lKHByb3ZpZGVyTmFtZSkucHJvdmlkZXJOYW1lO1xuXG4gICAgICAgIGRlbGV0ZSB0aGlzLnByb3ZpZGVyc0NhY2hlW3Byb3ZpZGVyTmFtZV07XG4gICAgfSxcblxuICAgIGFzeW5jIGdldFByb3ZpZGVyIChwcm92aWRlck5hbWUpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkUHJvdmlkZXJOYW1lID0gcGFyc2VQcm92aWRlck5hbWUocHJvdmlkZXJOYW1lKTtcbiAgICAgICAgY29uc3QgbW9kdWxlTmFtZSAgICAgICAgID0gcGFyc2VkUHJvdmlkZXJOYW1lLm1vZHVsZU5hbWU7XG5cbiAgICAgICAgcHJvdmlkZXJOYW1lID0gcGFyc2VkUHJvdmlkZXJOYW1lLnByb3ZpZGVyTmFtZTtcblxuICAgICAgICBjb25zdCBwcm92aWRlciA9IHRoaXMuX2dldFByb3ZpZGVyRnJvbUNhY2hlKHByb3ZpZGVyTmFtZSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZ2V0UHJvdmlkZXJNb2R1bGUocHJvdmlkZXJOYW1lLCBtb2R1bGVOYW1lKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9nZXRCdWlsdGluUHJvdmlkZXIocHJvdmlkZXJOYW1lKTtcblxuICAgICAgICBpZiAocHJvdmlkZXIpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnByb3ZpZGVyc0NhY2hlW3Byb3ZpZGVyTmFtZV0uaW5pdCgpO1xuXG4gICAgICAgIHJldHVybiBwcm92aWRlcjtcbiAgICB9LFxuXG4gICAgZGlzcG9zZSAoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChPYmplY3QudmFsdWVzKHRoaXMucHJvdmlkZXJzQ2FjaGUpLm1hcChpdGVtID0+IGl0ZW0uZGlzcG9zZSgpKSk7XG4gICAgfVxufTtcbiJdfQ== diff --git a/lib/browser/provider/utils/argument-parsing.js b/lib/browser/provider/utils/argument-parsing.js new file mode 100644 index 00000000..b26b76f7 --- /dev/null +++ b/lib/browser/provider/utils/argument-parsing.js @@ -0,0 +1,99 @@ +'use strict'; + +exports.__esModule = true; +exports.hasMatch = hasMatch; +exports.findMatch = findMatch; +exports.isMatchTrue = isMatchTrue; +exports.splitEscaped = splitEscaped; +exports.getPathFromParsedModes = getPathFromParsedModes; +exports.getModes = getModes; +exports.parseConfig = parseConfig; + +var _lodash = require('lodash'); + +var _osFamily = require('os-family'); + +var _osFamily2 = _interopRequireDefault(_osFamily); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const CONFIG_TERMINATOR_RE = /(\s+|^)-/; + +function hasMatch(array, re) { + return !!(0, _lodash.find)(array, el => el.match(re)); +} + +function findMatch(array, re) { + const element = (0, _lodash.find)(array, el => el.match(re)); + + return element ? element.match(re)[1] : ''; +} + +function isMatchTrue(array, re) { + const match = findMatch(array, re); + + return match && match !== '0' && match !== 'false'; +} + +function splitEscaped(str, splitterChar) { + const result = ['']; + + for (let i = 0; i < str.length; i++) { + if (str[i] === splitterChar) { + result.push(''); + continue; + } + + if (str[i] === '\\' && (str[i + 1] === '\\' || str[i + 1] === splitterChar)) i++; + + result[result.length - 1] += str[i]; + } + + return result; +} + +function getPathFromParsedModes(modes, availableModes = []) { + if (!modes.length) return ''; + + if (availableModes.some(mode => mode === modes[0])) return ''; + + let path = modes.shift(); + + if (_osFamily2.default.win && modes.length && path.match(/^[A-Za-z]$/)) path += ':' + modes.shift(); + + return path; +} + +function getModes(modes, availableModes = []) { + const result = {}; + + availableModes = availableModes.slice(); + + availableModes.forEach(key => { + result[key] = false; + }); + + while (modes.length && availableModes.length) { + if (modes[0] === availableModes[0]) { + result[availableModes[0]] = true; + + modes.shift(); + } + + availableModes.shift(); + } + + return result; +} + +function parseConfig(str) { + const configTerminatorMatch = str.match(CONFIG_TERMINATOR_RE); + + if (!configTerminatorMatch) return { modesString: str, userArgs: '' }; + + return { + modesString: str.substr(0, configTerminatorMatch.index), + userArgs: str.substr(configTerminatorMatch.index + configTerminatorMatch[1].length) + }; +} +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL3V0aWxzL2FyZ3VtZW50LXBhcnNpbmcuanMiXSwibmFtZXMiOlsiaGFzTWF0Y2giLCJmaW5kTWF0Y2giLCJpc01hdGNoVHJ1ZSIsInNwbGl0RXNjYXBlZCIsImdldFBhdGhGcm9tUGFyc2VkTW9kZXMiLCJnZXRNb2RlcyIsInBhcnNlQ29uZmlnIiwiQ09ORklHX1RFUk1JTkFUT1JfUkUiLCJhcnJheSIsInJlIiwiZWwiLCJtYXRjaCIsImVsZW1lbnQiLCJzdHIiLCJzcGxpdHRlckNoYXIiLCJyZXN1bHQiLCJpIiwibGVuZ3RoIiwicHVzaCIsIm1vZGVzIiwiYXZhaWxhYmxlTW9kZXMiLCJzb21lIiwibW9kZSIsInBhdGgiLCJzaGlmdCIsIk9TIiwid2luIiwic2xpY2UiLCJmb3JFYWNoIiwia2V5IiwiY29uZmlnVGVybWluYXRvck1hdGNoIiwibW9kZXNTdHJpbmciLCJ1c2VyQXJncyIsInN1YnN0ciIsImluZGV4Il0sIm1hcHBpbmdzIjoiOzs7UUFLZ0JBLFEsR0FBQUEsUTtRQUlBQyxTLEdBQUFBLFM7UUFNQUMsVyxHQUFBQSxXO1FBTUFDLFksR0FBQUEsWTtRQWtCQUMsc0IsR0FBQUEsc0I7UUFlQUMsUSxHQUFBQSxRO1FBc0JBQyxXLEdBQUFBLFc7O0FBNUVoQjs7QUFDQTs7Ozs7O0FBRUEsTUFBTUMsdUJBQXVCLFVBQTdCOztBQUVPLFNBQVNQLFFBQVQsQ0FBbUJRLEtBQW5CLEVBQTBCQyxFQUExQixFQUE4QjtBQUNqQyxXQUFPLENBQUMsQ0FBQyxrQkFBWUQsS0FBWixFQUFtQkUsTUFBTUEsR0FBR0MsS0FBSCxDQUFTRixFQUFULENBQXpCLENBQVQ7QUFDSDs7QUFFTSxTQUFTUixTQUFULENBQW9CTyxLQUFwQixFQUEyQkMsRUFBM0IsRUFBK0I7QUFDbEMsVUFBTUcsVUFBVSxrQkFBWUosS0FBWixFQUFtQkUsTUFBTUEsR0FBR0MsS0FBSCxDQUFTRixFQUFULENBQXpCLENBQWhCOztBQUVBLFdBQU9HLFVBQVVBLFFBQVFELEtBQVIsQ0FBY0YsRUFBZCxFQUFrQixDQUFsQixDQUFWLEdBQWlDLEVBQXhDO0FBQ0g7O0FBRU0sU0FBU1AsV0FBVCxDQUFzQk0sS0FBdEIsRUFBNkJDLEVBQTdCLEVBQWlDO0FBQ3BDLFVBQU1FLFFBQVFWLFVBQVVPLEtBQVYsRUFBaUJDLEVBQWpCLENBQWQ7O0FBRUEsV0FBT0UsU0FBU0EsVUFBVSxHQUFuQixJQUEwQkEsVUFBVSxPQUEzQztBQUNIOztBQUVNLFNBQVNSLFlBQVQsQ0FBdUJVLEdBQXZCLEVBQTRCQyxZQUE1QixFQUEwQztBQUM3QyxVQUFNQyxTQUFTLENBQUMsRUFBRCxDQUFmOztBQUVBLFNBQUssSUFBSUMsSUFBSSxDQUFiLEVBQWdCQSxJQUFJSCxJQUFJSSxNQUF4QixFQUFnQ0QsR0FBaEMsRUFBcUM7QUFDakMsWUFBSUgsSUFBSUcsQ0FBSixNQUFXRixZQUFmLEVBQTZCO0FBQ3pCQyxtQkFBT0csSUFBUCxDQUFZLEVBQVo7QUFDQTtBQUNIOztBQUVELFlBQUlMLElBQUlHLENBQUosTUFBVyxJQUFYLEtBQW9CSCxJQUFJRyxJQUFJLENBQVIsTUFBZSxJQUFmLElBQXVCSCxJQUFLRyxJQUFJLENBQVQsTUFBZ0JGLFlBQTNELENBQUosRUFDSUU7O0FBRUpELGVBQU9BLE9BQU9FLE1BQVAsR0FBZ0IsQ0FBdkIsS0FBNkJKLElBQUlHLENBQUosQ0FBN0I7QUFDSDs7QUFFRCxXQUFPRCxNQUFQO0FBQ0g7O0FBRU0sU0FBU1gsc0JBQVQsQ0FBaUNlLEtBQWpDLEVBQXdDQyxpQkFBaUIsRUFBekQsRUFBNkQ7QUFDaEUsUUFBSSxDQUFDRCxNQUFNRixNQUFYLEVBQ0ksT0FBTyxFQUFQOztBQUVKLFFBQUlHLGVBQWVDLElBQWYsQ0FBb0JDLFFBQVFBLFNBQVNILE1BQU0sQ0FBTixDQUFyQyxDQUFKLEVBQ0ksT0FBTyxFQUFQOztBQUVKLFFBQUlJLE9BQU9KLE1BQU1LLEtBQU4sRUFBWDs7QUFFQSxRQUFJQyxtQkFBR0MsR0FBSCxJQUFVUCxNQUFNRixNQUFoQixJQUEwQk0sS0FBS1osS0FBTCxDQUFXLFlBQVgsQ0FBOUIsRUFDSVksUUFBUSxNQUFNSixNQUFNSyxLQUFOLEVBQWQ7O0FBRUosV0FBT0QsSUFBUDtBQUNIOztBQUVNLFNBQVNsQixRQUFULENBQW1CYyxLQUFuQixFQUEwQkMsaUJBQWlCLEVBQTNDLEVBQStDO0FBQ2xELFVBQU1MLFNBQVMsRUFBZjs7QUFFQUsscUJBQWlCQSxlQUFlTyxLQUFmLEVBQWpCOztBQUVBUCxtQkFBZVEsT0FBZixDQUF1QkMsT0FBTztBQUMxQmQsZUFBT2MsR0FBUCxJQUFjLEtBQWQ7QUFDSCxLQUZEOztBQUlBLFdBQU9WLE1BQU1GLE1BQU4sSUFBZ0JHLGVBQWVILE1BQXRDLEVBQThDO0FBQzFDLFlBQUlFLE1BQU0sQ0FBTixNQUFhQyxlQUFlLENBQWYsQ0FBakIsRUFBb0M7QUFDaENMLG1CQUFPSyxlQUFlLENBQWYsQ0FBUCxJQUE0QixJQUE1Qjs7QUFFQUQsa0JBQU1LLEtBQU47QUFDSDs7QUFFREosdUJBQWVJLEtBQWY7QUFDSDs7QUFFRCxXQUFPVCxNQUFQO0FBQ0g7O0FBRU0sU0FBU1QsV0FBVCxDQUFzQk8sR0FBdEIsRUFBMkI7QUFDOUIsVUFBTWlCLHdCQUF3QmpCLElBQUlGLEtBQUosQ0FBVUosb0JBQVYsQ0FBOUI7O0FBRUEsUUFBSSxDQUFDdUIscUJBQUwsRUFDSSxPQUFPLEVBQUVDLGFBQWFsQixHQUFmLEVBQW9CbUIsVUFBVSxFQUE5QixFQUFQOztBQUVKLFdBQU87QUFDSEQscUJBQWFsQixJQUFJb0IsTUFBSixDQUFXLENBQVgsRUFBY0gsc0JBQXNCSSxLQUFwQyxDQURWO0FBRUhGLGtCQUFhbkIsSUFBSW9CLE1BQUosQ0FBV0gsc0JBQXNCSSxLQUF0QixHQUE4Qkosc0JBQXNCLENBQXRCLEVBQXlCYixNQUFsRTtBQUZWLEtBQVA7QUFJSCIsImZpbGUiOiJicm93c2VyL3Byb3ZpZGVyL3V0aWxzL2FyZ3VtZW50LXBhcnNpbmcuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmaW5kIGFzIGZpbmRFbGVtZW50IH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBPUyBmcm9tICdvcy1mYW1pbHknO1xuXG5jb25zdCBDT05GSUdfVEVSTUlOQVRPUl9SRSA9IC8oXFxzK3xeKS0vO1xuXG5leHBvcnQgZnVuY3Rpb24gaGFzTWF0Y2ggKGFycmF5LCByZSkge1xuICAgIHJldHVybiAhIWZpbmRFbGVtZW50KGFycmF5LCBlbCA9PiBlbC5tYXRjaChyZSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZmluZE1hdGNoIChhcnJheSwgcmUpIHtcbiAgICBjb25zdCBlbGVtZW50ID0gZmluZEVsZW1lbnQoYXJyYXksIGVsID0+IGVsLm1hdGNoKHJlKSk7XG5cbiAgICByZXR1cm4gZWxlbWVudCA/IGVsZW1lbnQubWF0Y2gocmUpWzFdIDogJyc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc01hdGNoVHJ1ZSAoYXJyYXksIHJlKSB7XG4gICAgY29uc3QgbWF0Y2ggPSBmaW5kTWF0Y2goYXJyYXksIHJlKTtcblxuICAgIHJldHVybiBtYXRjaCAmJiBtYXRjaCAhPT0gJzAnICYmIG1hdGNoICE9PSAnZmFsc2UnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3BsaXRFc2NhcGVkIChzdHIsIHNwbGl0dGVyQ2hhcikge1xuICAgIGNvbnN0IHJlc3VsdCA9IFsnJ107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoc3RyW2ldID09PSBzcGxpdHRlckNoYXIpIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKCcnKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0cltpXSA9PT0gJ1xcXFwnICYmIChzdHJbaSArIDFdID09PSAnXFxcXCcgfHwgc3RyIFtpICsgMV0gPT09IHNwbGl0dGVyQ2hhcikpXG4gICAgICAgICAgICBpKys7XG5cbiAgICAgICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXSArPSBzdHJbaV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBhdGhGcm9tUGFyc2VkTW9kZXMgKG1vZGVzLCBhdmFpbGFibGVNb2RlcyA9IFtdKSB7XG4gICAgaWYgKCFtb2Rlcy5sZW5ndGgpXG4gICAgICAgIHJldHVybiAnJztcblxuICAgIGlmIChhdmFpbGFibGVNb2Rlcy5zb21lKG1vZGUgPT4gbW9kZSA9PT0gbW9kZXNbMF0pKVxuICAgICAgICByZXR1cm4gJyc7XG5cbiAgICBsZXQgcGF0aCA9IG1vZGVzLnNoaWZ0KCk7XG5cbiAgICBpZiAoT1Mud2luICYmIG1vZGVzLmxlbmd0aCAmJiBwYXRoLm1hdGNoKC9eW0EtWmEtel0kLykpXG4gICAgICAgIHBhdGggKz0gJzonICsgbW9kZXMuc2hpZnQoKTtcblxuICAgIHJldHVybiBwYXRoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TW9kZXMgKG1vZGVzLCBhdmFpbGFibGVNb2RlcyA9IFtdKSB7XG4gICAgY29uc3QgcmVzdWx0ID0ge307XG5cbiAgICBhdmFpbGFibGVNb2RlcyA9IGF2YWlsYWJsZU1vZGVzLnNsaWNlKCk7XG5cbiAgICBhdmFpbGFibGVNb2Rlcy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIHJlc3VsdFtrZXldID0gZmFsc2U7XG4gICAgfSk7XG5cbiAgICB3aGlsZSAobW9kZXMubGVuZ3RoICYmIGF2YWlsYWJsZU1vZGVzLmxlbmd0aCkge1xuICAgICAgICBpZiAobW9kZXNbMF0gPT09IGF2YWlsYWJsZU1vZGVzWzBdKSB7XG4gICAgICAgICAgICByZXN1bHRbYXZhaWxhYmxlTW9kZXNbMF1dID0gdHJ1ZTtcblxuICAgICAgICAgICAgbW9kZXMuc2hpZnQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF2YWlsYWJsZU1vZGVzLnNoaWZ0KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQ29uZmlnIChzdHIpIHtcbiAgICBjb25zdCBjb25maWdUZXJtaW5hdG9yTWF0Y2ggPSBzdHIubWF0Y2goQ09ORklHX1RFUk1JTkFUT1JfUkUpO1xuXG4gICAgaWYgKCFjb25maWdUZXJtaW5hdG9yTWF0Y2gpXG4gICAgICAgIHJldHVybiB7IG1vZGVzU3RyaW5nOiBzdHIsIHVzZXJBcmdzOiAnJyB9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgbW9kZXNTdHJpbmc6IHN0ci5zdWJzdHIoMCwgY29uZmlnVGVybWluYXRvck1hdGNoLmluZGV4KSxcbiAgICAgICAgdXNlckFyZ3M6ICAgIHN0ci5zdWJzdHIoY29uZmlnVGVybWluYXRvck1hdGNoLmluZGV4ICsgY29uZmlnVGVybWluYXRvck1hdGNoWzFdLmxlbmd0aClcbiAgICB9O1xufVxuIl19 diff --git a/lib/browser/provider/utils/browser-starter.js b/lib/browser/provider/utils/browser-starter.js new file mode 100644 index 00000000..9e0ff51d --- /dev/null +++ b/lib/browser/provider/utils/browser-starter.js @@ -0,0 +1,64 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _pinkie = require('pinkie'); + +var _pinkie2 = _interopRequireDefault(_pinkie); + +var _osFamily = require('os-family'); + +var _osFamily2 = _interopRequireDefault(_osFamily); + +var _testcafeBrowserTools = require('testcafe-browser-tools'); + +var _testcafeBrowserTools2 = _interopRequireDefault(_testcafeBrowserTools); + +var _delay = require('../../../utils/delay'); + +var _delay2 = _interopRequireDefault(_delay); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const POST_OPERATION_DELAY = 500; + +class OperationsQueue { + constructor() { + this.chainPromise = _pinkie2.default.resolve(); + } + + executeOperation(operation) { + const operationPromise = this.chainPromise.then(operation); + + this.chainPromise = operationPromise.then(() => (0, _delay2.default)(POST_OPERATION_DELAY)); + + return operationPromise; + } +} + +class BrowserStarter { + constructor() { + // NOTE: You can't start multiple instances of the same app at the same time on macOS. + // That's why a queue of opening requests is needed. + this.macOSBrowserOpeningQueue = new OperationsQueue(); + } + + startBrowser(...openArgs) { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + const openBrowserOperation = function openBrowserOperation() { + return _testcafeBrowserTools2.default.open(...openArgs); + }; + + if (_osFamily2.default.mac) yield _this.macOSBrowserOpeningQueue.executeOperation(openBrowserOperation);else yield openBrowserOperation(); + })(); + } +} +exports.default = BrowserStarter; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL3V0aWxzL2Jyb3dzZXItc3RhcnRlci5qcyJdLCJuYW1lcyI6WyJQT1NUX09QRVJBVElPTl9ERUxBWSIsIk9wZXJhdGlvbnNRdWV1ZSIsImNvbnN0cnVjdG9yIiwiY2hhaW5Qcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJleGVjdXRlT3BlcmF0aW9uIiwib3BlcmF0aW9uIiwib3BlcmF0aW9uUHJvbWlzZSIsInRoZW4iLCJCcm93c2VyU3RhcnRlciIsIm1hY09TQnJvd3Nlck9wZW5pbmdRdWV1ZSIsInN0YXJ0QnJvd3NlciIsIm9wZW5BcmdzIiwib3BlbkJyb3dzZXJPcGVyYXRpb24iLCJicm93c2VyVG9vbHMiLCJvcGVuIiwiT1MiLCJtYWMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7OztBQUdBLE1BQU1BLHVCQUF1QixHQUE3Qjs7QUFFQSxNQUFNQyxlQUFOLENBQXNCO0FBQ2xCQyxrQkFBZTtBQUNYLGFBQUtDLFlBQUwsR0FBb0JDLGlCQUFRQyxPQUFSLEVBQXBCO0FBQ0g7O0FBRURDLHFCQUFrQkMsU0FBbEIsRUFBNkI7QUFDekIsY0FBTUMsbUJBQW1CLEtBQUtMLFlBQUwsQ0FBa0JNLElBQWxCLENBQXVCRixTQUF2QixDQUF6Qjs7QUFFQSxhQUFLSixZQUFMLEdBQW9CSyxpQkFBaUJDLElBQWpCLENBQXNCLE1BQU0scUJBQU1ULG9CQUFOLENBQTVCLENBQXBCOztBQUVBLGVBQU9RLGdCQUFQO0FBQ0g7QUFYaUI7O0FBY1AsTUFBTUUsY0FBTixDQUFxQjtBQUNoQ1Isa0JBQWU7QUFDWDtBQUNBO0FBQ0EsYUFBS1Msd0JBQUwsR0FBZ0MsSUFBSVYsZUFBSixFQUFoQztBQUNIOztBQUVLVyxnQkFBTixDQUFvQixHQUFHQyxRQUF2QixFQUFpQztBQUFBOztBQUFBO0FBQzdCLGtCQUFNQyx1QkFBdUIsU0FBdkJBLG9CQUF1QjtBQUFBLHVCQUFNQywrQkFBYUMsSUFBYixDQUFrQixHQUFHSCxRQUFyQixDQUFOO0FBQUEsYUFBN0I7O0FBRUEsZ0JBQUlJLG1CQUFHQyxHQUFQLEVBQ0ksTUFBTSxNQUFLUCx3QkFBTCxDQUE4QkwsZ0JBQTlCLENBQStDUSxvQkFBL0MsQ0FBTixDQURKLEtBR0ksTUFBTUEsc0JBQU47QUFOeUI7QUFPaEM7QUFkK0I7a0JBQWZKLGMiLCJmaWxlIjoiYnJvd3Nlci9wcm92aWRlci91dGlscy9icm93c2VyLXN0YXJ0ZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUHJvbWlzZSBmcm9tICdwaW5raWUnO1xuaW1wb3J0IE9TIGZyb20gJ29zLWZhbWlseSc7XG5pbXBvcnQgYnJvd3NlclRvb2xzIGZyb20gJ3Rlc3RjYWZlLWJyb3dzZXItdG9vbHMnO1xuaW1wb3J0IGRlbGF5IGZyb20gJy4uLy4uLy4uL3V0aWxzL2RlbGF5JztcblxuXG5jb25zdCBQT1NUX09QRVJBVElPTl9ERUxBWSA9IDUwMDtcblxuY2xhc3MgT3BlcmF0aW9uc1F1ZXVlIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuY2hhaW5Qcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgZXhlY3V0ZU9wZXJhdGlvbiAob3BlcmF0aW9uKSB7XG4gICAgICAgIGNvbnN0IG9wZXJhdGlvblByb21pc2UgPSB0aGlzLmNoYWluUHJvbWlzZS50aGVuKG9wZXJhdGlvbik7XG5cbiAgICAgICAgdGhpcy5jaGFpblByb21pc2UgPSBvcGVyYXRpb25Qcm9taXNlLnRoZW4oKCkgPT4gZGVsYXkoUE9TVF9PUEVSQVRJT05fREVMQVkpKTtcblxuICAgICAgICByZXR1cm4gb3BlcmF0aW9uUHJvbWlzZTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJyb3dzZXJTdGFydGVyIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIC8vIE5PVEU6IFlvdSBjYW4ndCBzdGFydCBtdWx0aXBsZSBpbnN0YW5jZXMgb2YgdGhlIHNhbWUgYXBwIGF0IHRoZSBzYW1lIHRpbWUgb24gbWFjT1MuXG4gICAgICAgIC8vIFRoYXQncyB3aHkgYSBxdWV1ZSBvZiBvcGVuaW5nIHJlcXVlc3RzIGlzIG5lZWRlZC5cbiAgICAgICAgdGhpcy5tYWNPU0Jyb3dzZXJPcGVuaW5nUXVldWUgPSBuZXcgT3BlcmF0aW9uc1F1ZXVlKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgc3RhcnRCcm93c2VyICguLi5vcGVuQXJncykge1xuICAgICAgICBjb25zdCBvcGVuQnJvd3Nlck9wZXJhdGlvbiA9ICgpID0+IGJyb3dzZXJUb29scy5vcGVuKC4uLm9wZW5BcmdzKTtcblxuICAgICAgICBpZiAoT1MubWFjKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5tYWNPU0Jyb3dzZXJPcGVuaW5nUXVldWUuZXhlY3V0ZU9wZXJhdGlvbihvcGVuQnJvd3Nlck9wZXJhdGlvbik7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGF3YWl0IG9wZW5Ccm93c2VyT3BlcmF0aW9uKCk7XG4gICAgfVxufVxuIl19 diff --git a/lib/browser/provider/utils/client-functions.js b/lib/browser/provider/utils/client-functions.js new file mode 100644 index 00000000..3857fd0a --- /dev/null +++ b/lib/browser/provider/utils/client-functions.js @@ -0,0 +1,23 @@ +"use strict"; + +exports.__esModule = true; +/*eslint-disable no-undef*/ +function getTitle() { + return document.title; +} + +function getWindowDimensionsInfo() { + return { + width: window.innerWidth, + height: window.innerHeight, + outerWidth: window.outerWidth, + outerHeight: window.outerHeight, + availableWidth: screen.availWidth, + availableHeight: screen.availHeight + }; +} +/*eslint-disable no-undef*/ + +const GET_TITLE_SCRIPT = exports.GET_TITLE_SCRIPT = getTitle.toString(); +const GET_WINDOW_DIMENSIONS_INFO_SCRIPT = exports.GET_WINDOW_DIMENSIONS_INFO_SCRIPT = getWindowDimensionsInfo.toString(); +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL3V0aWxzL2NsaWVudC1mdW5jdGlvbnMuanMiXSwibmFtZXMiOlsiZ2V0VGl0bGUiLCJkb2N1bWVudCIsInRpdGxlIiwiZ2V0V2luZG93RGltZW5zaW9uc0luZm8iLCJ3aWR0aCIsIndpbmRvdyIsImlubmVyV2lkdGgiLCJoZWlnaHQiLCJpbm5lckhlaWdodCIsIm91dGVyV2lkdGgiLCJvdXRlckhlaWdodCIsImF2YWlsYWJsZVdpZHRoIiwic2NyZWVuIiwiYXZhaWxXaWR0aCIsImF2YWlsYWJsZUhlaWdodCIsImF2YWlsSGVpZ2h0IiwiR0VUX1RJVExFX1NDUklQVCIsInRvU3RyaW5nIiwiR0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUIl0sIm1hcHBpbmdzIjoiOzs7QUFBQTtBQUNBLFNBQVNBLFFBQVQsR0FBcUI7QUFDakIsV0FBT0MsU0FBU0MsS0FBaEI7QUFDSDs7QUFFRCxTQUFTQyx1QkFBVCxHQUFvQztBQUNoQyxXQUFPO0FBQ0hDLGVBQWlCQyxPQUFPQyxVQURyQjtBQUVIQyxnQkFBaUJGLE9BQU9HLFdBRnJCO0FBR0hDLG9CQUFpQkosT0FBT0ksVUFIckI7QUFJSEMscUJBQWlCTCxPQUFPSyxXQUpyQjtBQUtIQyx3QkFBaUJDLE9BQU9DLFVBTHJCO0FBTUhDLHlCQUFpQkYsT0FBT0c7QUFOckIsS0FBUDtBQVFIO0FBQ0Q7O0FBRU8sTUFBTUMsOENBQW9DaEIsU0FBU2lCLFFBQVQsRUFBMUM7QUFDQSxNQUFNQyxnRkFBb0NmLHdCQUF3QmMsUUFBeEIsRUFBMUMiLCJmaWxlIjoiYnJvd3Nlci9wcm92aWRlci91dGlscy9jbGllbnQtZnVuY3Rpb25zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQtZGlzYWJsZSBuby11bmRlZiovXG5mdW5jdGlvbiBnZXRUaXRsZSAoKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LnRpdGxlO1xufVxuXG5mdW5jdGlvbiBnZXRXaW5kb3dEaW1lbnNpb25zSW5mbyAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgd2lkdGg6ICAgICAgICAgICB3aW5kb3cuaW5uZXJXaWR0aCxcbiAgICAgICAgaGVpZ2h0OiAgICAgICAgICB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgICAgIG91dGVyV2lkdGg6ICAgICAgd2luZG93Lm91dGVyV2lkdGgsXG4gICAgICAgIG91dGVySGVpZ2h0OiAgICAgd2luZG93Lm91dGVySGVpZ2h0LFxuICAgICAgICBhdmFpbGFibGVXaWR0aDogIHNjcmVlbi5hdmFpbFdpZHRoLFxuICAgICAgICBhdmFpbGFibGVIZWlnaHQ6IHNjcmVlbi5hdmFpbEhlaWdodFxuICAgIH07XG59XG4vKmVzbGludC1kaXNhYmxlIG5vLXVuZGVmKi9cblxuZXhwb3J0IGNvbnN0IEdFVF9USVRMRV9TQ1JJUFQgICAgICAgICAgICAgICAgICA9IGdldFRpdGxlLnRvU3RyaW5nKCk7XG5leHBvcnQgY29uc3QgR0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUID0gZ2V0V2luZG93RGltZW5zaW9uc0luZm8udG9TdHJpbmcoKTtcbiJdfQ== diff --git a/lib/browser/provider/utils/get-maximized-headless-window-size.js b/lib/browser/provider/utils/get-maximized-headless-window-size.js new file mode 100644 index 00000000..8dcf564d --- /dev/null +++ b/lib/browser/provider/utils/get-maximized-headless-window-size.js @@ -0,0 +1,20 @@ +'use strict'; + +exports.__esModule = true; + +exports.default = function () { + const sizeString = process.env.MAXIMIZED_HEADLESS_WINDOW_SIZE || DEFAULT_MAXIMIZED_HEADLESS_WINDOW_SIZE; + + var _sizeString$split$map = sizeString.split('x').map(str => Number(str)); + + const width = _sizeString$split$map[0], + height = _sizeString$split$map[1]; + + + return { width, height }; +}; + +const DEFAULT_MAXIMIZED_HEADLESS_WINDOW_SIZE = '1920x1080'; + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9icm93c2VyL3Byb3ZpZGVyL3V0aWxzL2dldC1tYXhpbWl6ZWQtaGVhZGxlc3Mtd2luZG93LXNpemUuanMiXSwibmFtZXMiOlsic2l6ZVN0cmluZyIsInByb2Nlc3MiLCJlbnYiLCJNQVhJTUlaRURfSEVBRExFU1NfV0lORE9XX1NJWkUiLCJERUZBVUxUX01BWElNSVpFRF9IRUFETEVTU19XSU5ET1dfU0laRSIsInNwbGl0IiwibWFwIiwic3RyIiwiTnVtYmVyIiwid2lkdGgiLCJoZWlnaHQiXSwibWFwcGluZ3MiOiI7Ozs7a0JBRWUsWUFBWTtBQUN2QixVQUFNQSxhQUFhQyxRQUFRQyxHQUFSLENBQVlDLDhCQUFaLElBQThDQyxzQ0FBakU7O0FBRHVCLGdDQUdTSixXQUFXSyxLQUFYLENBQWlCLEdBQWpCLEVBQXNCQyxHQUF0QixDQUEwQkMsT0FBT0MsT0FBT0QsR0FBUCxDQUFqQyxDQUhUOztBQUFBLFVBR1pFLEtBSFkseUJBR2YsQ0FIZTtBQUFBLFVBR0ZDLE1BSEUseUJBR0wsQ0FISzs7O0FBS3ZCLFdBQU8sRUFBRUQsS0FBRixFQUFTQyxNQUFULEVBQVA7QUFDSCxDOztBQVJELE1BQU1OLHlDQUF5QyxXQUEvQyIsImZpbGUiOiJicm93c2VyL3Byb3ZpZGVyL3V0aWxzL2dldC1tYXhpbWl6ZWQtaGVhZGxlc3Mtd2luZG93LXNpemUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBERUZBVUxUX01BWElNSVpFRF9IRUFETEVTU19XSU5ET1dfU0laRSA9ICcxOTIweDEwODAnO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2l6ZVN0cmluZyA9IHByb2Nlc3MuZW52Lk1BWElNSVpFRF9IRUFETEVTU19XSU5ET1dfU0laRSB8fCBERUZBVUxUX01BWElNSVpFRF9IRUFETEVTU19XSU5ET1dfU0laRTtcblxuICAgIGNvbnN0IHsgMDogd2lkdGgsIDE6IGhlaWdodCB9ID0gc2l6ZVN0cmluZy5zcGxpdCgneCcpLm1hcChzdHIgPT4gTnVtYmVyKHN0cikpO1xuXG4gICAgcmV0dXJuIHsgd2lkdGgsIGhlaWdodCB9O1xufVxuIl19 diff --git a/lib/cli/argument-parser.js b/lib/cli/argument-parser.js new file mode 100644 index 00000000..6d574bd8 --- /dev/null +++ b/lib/cli/argument-parser.js @@ -0,0 +1,315 @@ +'use strict'; + +exports.__esModule = true; + +var _getIterator2 = require('babel-runtime/core-js/get-iterator'); + +var _getIterator3 = _interopRequireDefault(_getIterator2); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _keys = require('babel-runtime/core-js/object/keys'); + +var _keys2 = _interopRequireDefault(_keys); + +var _path = require('path'); + +var _commander = require('commander'); + +var _dedent = require('dedent'); + +var _dedent2 = _interopRequireDefault(_dedent); + +var _readFileRelative = require('read-file-relative'); + +var _makeDir = require('make-dir'); + +var _makeDir2 = _interopRequireDefault(_makeDir); + +var _runtime = require('../errors/runtime'); + +var _message = require('../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +var _typeAssertions = require('../errors/runtime/type-assertions'); + +var _getViewportWidth = require('../utils/get-viewport-width'); + +var _getViewportWidth2 = _interopRequireDefault(_getViewportWidth); + +var _string = require('../utils/string'); + +var _lodash = require('lodash'); + +var _parseSslOptions = require('./parse-ssl-options'); + +var _parseSslOptions2 = _interopRequireDefault(_parseSslOptions); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const REMOTE_ALIAS_RE = /^remote(?::(\d*))?$/; + +const DESCRIPTION = (0, _dedent2.default)(` + In the browser list, you can use browser names (e.g. "ie", "chrome", etc.) as well as paths to executables. + + To run tests against all installed browsers, use the "all" alias. + + To use a remote browser connection (e.g., to connect a mobile device), specify "remote" as the browser alias. + If you need to connect multiple devices, add a colon and the number of browsers you want to connect (e.g., "remote:3"). + + To run tests in a browser accessed through a browser provider plugin, specify a browser alias that consists of two parts - the browser provider name prefix and the name of the browser itself; for example, "saucelabs:chrome@51". + + You can use one or more file paths or glob patterns to specify which tests to run. + + More info: https://devexpress.github.io/testcafe/documentation +`); + +class CLIArgumentParser { + constructor(cwd) { + this.program = new _commander.Command('testcafe'); + + this.cwd = cwd || process.cwd(); + + this.src = null; + this.browsers = null; + this.filter = null; + this.remoteCount = 0; + this.opts = null; + + this._describeProgram(); + } + + static _parsePortNumber(value) { + (0, _typeAssertions.assertType)(_typeAssertions.is.nonNegativeNumberString, null, 'Port number', value); + + return parseInt(value, 10); + } + + static _optionValueToRegExp(name, value) { + if (value === void 0) return value; + + try { + return new RegExp(value); + } catch (err) { + throw new _runtime.GeneralError(_message2.default.optionValueIsNotValidRegExp, name); + } + } + + static _optionValueToKeyValue(name, value) { + if (value === void 0) return value; + + const keyValue = value.split(',').reduce((obj, pair) => { + var _pair$split = pair.split('='); + + const key = _pair$split[0], + val = _pair$split[1]; + + + if (!key || !val) throw new _runtime.GeneralError(_message2.default.optionValueIsNotValidKeyValue, name); + + obj[key] = val; + return obj; + }, {}); + + if ((0, _keys2.default)(keyValue).length === 0) throw new _runtime.GeneralError(_message2.default.optionValueIsNotValidKeyValue, name); + + return keyValue; + } + + static _getDescription() { + // NOTE: add empty line to workaround commander-forced indentation on the first line. + return '\n' + (0, _string.wordWrap)(DESCRIPTION, 2, (0, _getViewportWidth2.default)(process.stdout)); + } + + _describeProgram() { + const version = JSON.parse((0, _readFileRelative.readSync)('../../package.json')).version; + + this.program.version(version, '-v, --version').usage('[options] ').description(CLIArgumentParser._getDescription()).option('-b, --list-browsers [provider]', 'output the aliases for local browsers or browsers available through the specified browser provider').option('-r, --reporter ', 'specify the reporters and optionally files where reports are saved').option('-s, --screenshots ', 'enable screenshot capturing and specify the path to save the screenshots to').option('-S, --screenshots-on-fails', 'take a screenshot whenever a test fails').option('-p, --screenshot-path-pattern ', 'use patterns to compose screenshot file names and paths: ${BROWSER}, ${BROWSER_VERSION}, ${OS}, etc.').option('-q, --quarantine-mode', 'enable the quarantine mode').option('-d, --debug-mode', 'execute test steps one by one pausing the test after each step').option('-e, --skip-js-errors', 'make tests not fail when a JS error happens on a page').option('-u, --skip-uncaught-errors', 'ignore uncaught errors and unhandled promise rejections, which occur during test execution').option('-t, --test ', 'run only tests with the specified name').option('-T, --test-grep ', 'run only tests matching the specified pattern').option('-f, --fixture ', 'run only fixtures with the specified name').option('-F, --fixture-grep ', 'run only fixtures matching the specified pattern').option('-a, --app ', 'launch the tested app using the specified command before running tests').option('-c, --concurrency ', 'run tests concurrently').option('--test-meta ', 'run only tests with matching metadata').option('--fixture-meta ', 'run only fixtures with matching metadata').option('--debug-on-fail', 'pause the test if it fails').option('--app-init-delay ', 'specify how much time it takes for the tested app to initialize').option('--selector-timeout ', 'set the amount of time within which selectors make attempts to obtain a node to be returned').option('--assertion-timeout ', 'set the amount of time within which assertion should pass').option('--page-load-timeout ', 'set the amount of time within which TestCafe waits for the `window.load` event to fire on page load before proceeding to the next test action').option('--speed ', 'set the speed of test execution (0.01 ... 1)').option('--ports ', 'specify custom port numbers').option('--hostname ', 'specify the hostname').option('--proxy ', 'specify the host of the proxy server').option('--proxy-bypass ', 'specify a comma-separated list of rules that define URLs accessed bypassing the proxy server').option('--ssl ', 'specify SSL options to run TestCafe proxy server over the HTTPS protocol').option('--disable-page-reloads', 'disable page reloads between tests').option('--dev', 'enables mechanisms to log and diagnose errors').option('--qr-code', 'outputs QR-code that repeats URLs used to connect the remote browsers').option('--sf, --stop-on-first-fail', 'stop an entire test run if any test fails').option('--disable-test-syntax-validation', 'disables checks for \'test\' and \'fixture\' directives to run dynamically loaded tests').option('--record-screen-capture', 'take screenshots of each action') + + // NOTE: these options will be handled by chalk internally + .option('--color', 'force colors in command line').option('--no-color', 'disable colors in command line'); + } + + _filterAndCountRemotes(browser) { + const remoteMatch = browser.match(REMOTE_ALIAS_RE); + + if (remoteMatch) { + this.remoteCount += parseInt(remoteMatch[1], 10) || 1; + return false; + } + + return true; + } + + _parseFilteringOptions() { + this.opts.testGrep = CLIArgumentParser._optionValueToRegExp('--test-grep', this.opts.testGrep); + this.opts.fixtureGrep = CLIArgumentParser._optionValueToRegExp('--fixture-grep', this.opts.fixtureGrep); + this.opts.testMeta = CLIArgumentParser._optionValueToKeyValue('--test-meta', this.opts.testMeta); + this.opts.fixtureMeta = CLIArgumentParser._optionValueToKeyValue('--fixture-meta', this.opts.fixtureMeta); + + this.filter = (testName, fixtureName, fixturePath, testMeta, fixtureMeta) => { + + if (this.opts.test && testName !== this.opts.test) return false; + + if (this.opts.testGrep && !this.opts.testGrep.test(testName)) return false; + + if (this.opts.fixture && fixtureName !== this.opts.fixture) return false; + + if (this.opts.fixtureGrep && !this.opts.fixtureGrep.test(fixtureName)) return false; + + if (this.opts.testMeta && !(0, _lodash.isMatch)(testMeta, this.opts.testMeta)) return false; + + if (this.opts.fixtureMeta && !(0, _lodash.isMatch)(fixtureMeta, this.opts.fixtureMeta)) return false; + + return true; + }; + } + + _parseAppInitDelay() { + if (this.opts.appInitDelay) { + (0, _typeAssertions.assertType)(_typeAssertions.is.nonNegativeNumberString, null, 'Tested app initialization delay', this.opts.appInitDelay); + + this.opts.appInitDelay = parseInt(this.opts.appInitDelay, 10); + } + } + + _parseSelectorTimeout() { + if (this.opts.selectorTimeout) { + (0, _typeAssertions.assertType)(_typeAssertions.is.nonNegativeNumberString, null, 'Selector timeout', this.opts.selectorTimeout); + + this.opts.selectorTimeout = parseInt(this.opts.selectorTimeout, 10); + } + } + + _parseAssertionTimeout() { + if (this.opts.assertionTimeout) { + (0, _typeAssertions.assertType)(_typeAssertions.is.nonNegativeNumberString, null, 'Assertion timeout', this.opts.assertionTimeout); + + this.opts.assertionTimeout = parseInt(this.opts.assertionTimeout, 10); + } + } + + _parsePageLoadTimeout() { + if (this.opts.pageLoadTimeout) { + (0, _typeAssertions.assertType)(_typeAssertions.is.nonNegativeNumberString, null, 'Page load timeout', this.opts.pageLoadTimeout); + + this.opts.pageLoadTimeout = parseInt(this.opts.pageLoadTimeout, 10); + } + } + + _parseSpeed() { + if (this.opts.speed) this.opts.speed = parseFloat(this.opts.speed); + } + + _parseConcurrency() { + if (this.opts.concurrency) this.concurrency = parseInt(this.opts.concurrency, 10); + } + + _parsePorts() { + if (this.opts.ports) { + this.opts.ports = this.opts.ports.split(',').map(CLIArgumentParser._parsePortNumber); + + if (this.opts.ports.length < 2) throw new _runtime.GeneralError(_message2.default.portsOptionRequiresTwoNumbers); + } + } + + _parseBrowserList() { + const browsersArg = this.program.args[0] || ''; + + this.browsers = (0, _string.splitQuotedText)(browsersArg, ',').filter(browser => browser && this._filterAndCountRemotes(browser)); + } + + _parseSslOptions() { + if (this.opts.ssl) this.opts.ssl = (0, _parseSslOptions2.default)(this.opts.ssl); + } + + _parseReporters() { + var _this = this; + + return (0, _asyncToGenerator3.default)(function* () { + if (!_this.opts.reporter) { + _this.opts.reporters = []; + return; + } + + const reporters = _this.opts.reporter.split(','); + + _this.opts.reporters = reporters.map(function (reporter) { + const separatorIndex = reporter.indexOf(':'); + + if (separatorIndex < 0) return { name: reporter }; + + const name = reporter.substring(0, separatorIndex); + const outFile = reporter.substring(separatorIndex + 1); + + return { name, outFile }; + }); + + for (var _iterator = _this.opts.reporters, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : (0, _getIterator3.default)(_iterator);;) { + var _ref; + + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; + } + + const reporter = _ref; + + if (reporter.outFile) { + reporter.outFile = (0, _path.resolve)(_this.cwd, reporter.outFile); + + yield (0, _makeDir2.default)((0, _path.dirname)(reporter.outFile)); + } + } + })(); + } + + _parseFileList() { + this.src = this.program.args.slice(1); + } + + _getProviderName() { + this.opts.providerName = this.opts.listBrowsers === true ? void 0 : this.opts.listBrowsers; + } + + parse(argv) { + var _this2 = this; + + return (0, _asyncToGenerator3.default)(function* () { + _this2.program.parse(argv); + + _this2.opts = _this2.program.opts(); + + // NOTE: the '-list-browsers' option only lists browsers and immediately exits the app. + // Therefore, we don't need to process other arguments. + if (_this2.opts.listBrowsers) { + _this2._getProviderName(); + return; + } + + _this2._parseFilteringOptions(); + _this2._parseSelectorTimeout(); + _this2._parseAssertionTimeout(); + _this2._parsePageLoadTimeout(); + _this2._parseAppInitDelay(); + _this2._parseSpeed(); + _this2._parsePorts(); + _this2._parseBrowserList(); + _this2._parseConcurrency(); + _this2._parseSslOptions(); + _this2._parseFileList(); + + yield _this2._parseReporters(); + })(); + } +} +exports.default = CLIArgumentParser; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvYXJndW1lbnQtcGFyc2VyLmpzIl0sIm5hbWVzIjpbIlJFTU9URV9BTElBU19SRSIsIkRFU0NSSVBUSU9OIiwiQ0xJQXJndW1lbnRQYXJzZXIiLCJjb25zdHJ1Y3RvciIsImN3ZCIsInByb2dyYW0iLCJDb21tYW5kIiwicHJvY2VzcyIsInNyYyIsImJyb3dzZXJzIiwiZmlsdGVyIiwicmVtb3RlQ291bnQiLCJvcHRzIiwiX2Rlc2NyaWJlUHJvZ3JhbSIsIl9wYXJzZVBvcnROdW1iZXIiLCJ2YWx1ZSIsImlzIiwibm9uTmVnYXRpdmVOdW1iZXJTdHJpbmciLCJwYXJzZUludCIsIl9vcHRpb25WYWx1ZVRvUmVnRXhwIiwibmFtZSIsIlJlZ0V4cCIsImVyciIsIkdlbmVyYWxFcnJvciIsIk1FU1NBR0UiLCJvcHRpb25WYWx1ZUlzTm90VmFsaWRSZWdFeHAiLCJfb3B0aW9uVmFsdWVUb0tleVZhbHVlIiwia2V5VmFsdWUiLCJzcGxpdCIsInJlZHVjZSIsIm9iaiIsInBhaXIiLCJrZXkiLCJ2YWwiLCJvcHRpb25WYWx1ZUlzTm90VmFsaWRLZXlWYWx1ZSIsImxlbmd0aCIsIl9nZXREZXNjcmlwdGlvbiIsInN0ZG91dCIsInZlcnNpb24iLCJKU09OIiwicGFyc2UiLCJ1c2FnZSIsImRlc2NyaXB0aW9uIiwib3B0aW9uIiwiX2ZpbHRlckFuZENvdW50UmVtb3RlcyIsImJyb3dzZXIiLCJyZW1vdGVNYXRjaCIsIm1hdGNoIiwiX3BhcnNlRmlsdGVyaW5nT3B0aW9ucyIsInRlc3RHcmVwIiwiZml4dHVyZUdyZXAiLCJ0ZXN0TWV0YSIsImZpeHR1cmVNZXRhIiwidGVzdE5hbWUiLCJmaXh0dXJlTmFtZSIsImZpeHR1cmVQYXRoIiwidGVzdCIsImZpeHR1cmUiLCJfcGFyc2VBcHBJbml0RGVsYXkiLCJhcHBJbml0RGVsYXkiLCJfcGFyc2VTZWxlY3RvclRpbWVvdXQiLCJzZWxlY3RvclRpbWVvdXQiLCJfcGFyc2VBc3NlcnRpb25UaW1lb3V0IiwiYXNzZXJ0aW9uVGltZW91dCIsIl9wYXJzZVBhZ2VMb2FkVGltZW91dCIsInBhZ2VMb2FkVGltZW91dCIsIl9wYXJzZVNwZWVkIiwic3BlZWQiLCJwYXJzZUZsb2F0IiwiX3BhcnNlQ29uY3VycmVuY3kiLCJjb25jdXJyZW5jeSIsIl9wYXJzZVBvcnRzIiwicG9ydHMiLCJtYXAiLCJwb3J0c09wdGlvblJlcXVpcmVzVHdvTnVtYmVycyIsIl9wYXJzZUJyb3dzZXJMaXN0IiwiYnJvd3NlcnNBcmciLCJhcmdzIiwiX3BhcnNlU3NsT3B0aW9ucyIsInNzbCIsIl9wYXJzZVJlcG9ydGVycyIsInJlcG9ydGVyIiwicmVwb3J0ZXJzIiwic2VwYXJhdG9ySW5kZXgiLCJpbmRleE9mIiwic3Vic3RyaW5nIiwib3V0RmlsZSIsIl9wYXJzZUZpbGVMaXN0Iiwic2xpY2UiLCJfZ2V0UHJvdmlkZXJOYW1lIiwicHJvdmlkZXJOYW1lIiwibGlzdEJyb3dzZXJzIiwiYXJndiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7OztBQUNBOztBQUNBOzs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLE1BQU1BLGtCQUFrQixxQkFBeEI7O0FBRUEsTUFBTUMsY0FBYyxzQkFBUTs7Ozs7Ozs7Ozs7OztDQUFSLENBQXBCOztBQWVlLE1BQU1DLGlCQUFOLENBQXdCO0FBQ25DQyxnQkFBYUMsR0FBYixFQUFrQjtBQUNkLGFBQUtDLE9BQUwsR0FBZSxJQUFJQyxrQkFBSixDQUFZLFVBQVosQ0FBZjs7QUFFQSxhQUFLRixHQUFMLEdBQVdBLE9BQU9HLFFBQVFILEdBQVIsRUFBbEI7O0FBRUEsYUFBS0ksR0FBTCxHQUFtQixJQUFuQjtBQUNBLGFBQUtDLFFBQUwsR0FBbUIsSUFBbkI7QUFDQSxhQUFLQyxNQUFMLEdBQW1CLElBQW5CO0FBQ0EsYUFBS0MsV0FBTCxHQUFtQixDQUFuQjtBQUNBLGFBQUtDLElBQUwsR0FBbUIsSUFBbkI7O0FBRUEsYUFBS0MsZ0JBQUw7QUFDSDs7QUFFRCxXQUFPQyxnQkFBUCxDQUF5QkMsS0FBekIsRUFBZ0M7QUFDNUIsd0NBQVdDLG1CQUFHQyx1QkFBZCxFQUF1QyxJQUF2QyxFQUE2QyxhQUE3QyxFQUE0REYsS0FBNUQ7O0FBRUEsZUFBT0csU0FBU0gsS0FBVCxFQUFnQixFQUFoQixDQUFQO0FBQ0g7O0FBRUQsV0FBT0ksb0JBQVAsQ0FBNkJDLElBQTdCLEVBQW1DTCxLQUFuQyxFQUEwQztBQUN0QyxZQUFJQSxVQUFVLEtBQUssQ0FBbkIsRUFDSSxPQUFPQSxLQUFQOztBQUVKLFlBQUk7QUFDQSxtQkFBTyxJQUFJTSxNQUFKLENBQVdOLEtBQVgsQ0FBUDtBQUNILFNBRkQsQ0FHQSxPQUFPTyxHQUFQLEVBQVk7QUFDUixrQkFBTSxJQUFJQyxxQkFBSixDQUFpQkMsa0JBQVFDLDJCQUF6QixFQUFzREwsSUFBdEQsQ0FBTjtBQUNIO0FBQ0o7O0FBRUQsV0FBT00sc0JBQVAsQ0FBK0JOLElBQS9CLEVBQXFDTCxLQUFyQyxFQUE0QztBQUN4QyxZQUFJQSxVQUFVLEtBQUssQ0FBbkIsRUFDSSxPQUFPQSxLQUFQOztBQUVKLGNBQU1ZLFdBQVdaLE1BQU1hLEtBQU4sQ0FBWSxHQUFaLEVBQWlCQyxNQUFqQixDQUF3QixDQUFDQyxHQUFELEVBQU1DLElBQU4sS0FBZTtBQUFBLDhCQUNqQ0EsS0FBS0gsS0FBTCxDQUFXLEdBQVgsQ0FEaUM7O0FBQUEsa0JBQzdDSSxHQUQ2QztBQUFBLGtCQUN4Q0MsR0FEd0M7OztBQUdwRCxnQkFBSSxDQUFDRCxHQUFELElBQVEsQ0FBQ0MsR0FBYixFQUNJLE1BQU0sSUFBSVYscUJBQUosQ0FBaUJDLGtCQUFRVSw2QkFBekIsRUFBd0RkLElBQXhELENBQU47O0FBRUpVLGdCQUFJRSxHQUFKLElBQVdDLEdBQVg7QUFDQSxtQkFBT0gsR0FBUDtBQUNILFNBUmdCLEVBUWQsRUFSYyxDQUFqQjs7QUFVQSxZQUFJLG9CQUFZSCxRQUFaLEVBQXNCUSxNQUF0QixLQUFpQyxDQUFyQyxFQUNJLE1BQU0sSUFBSVoscUJBQUosQ0FBaUJDLGtCQUFRVSw2QkFBekIsRUFBd0RkLElBQXhELENBQU47O0FBRUosZUFBT08sUUFBUDtBQUNIOztBQUVELFdBQU9TLGVBQVAsR0FBMEI7QUFDdEI7QUFDQSxlQUFPLE9BQU8sc0JBQVNuQyxXQUFULEVBQXNCLENBQXRCLEVBQXlCLGdDQUFpQk0sUUFBUThCLE1BQXpCLENBQXpCLENBQWQ7QUFDSDs7QUFFRHhCLHVCQUFvQjtBQUNoQixjQUFNeUIsVUFBVUMsS0FBS0MsS0FBTCxDQUFXLGdDQUFLLG9CQUFMLENBQVgsRUFBdUNGLE9BQXZEOztBQUVBLGFBQUtqQyxPQUFMLENBRUtpQyxPQUZMLENBRWFBLE9BRmIsRUFFc0IsZUFGdEIsRUFHS0csS0FITCxDQUdXLDZEQUhYLEVBSUtDLFdBSkwsQ0FJaUJ4QyxrQkFBa0JrQyxlQUFsQixFQUpqQixFQU1LTyxNQU5MLENBTVksZ0NBTlosRUFNOEMsb0dBTjlDLEVBT0tBLE1BUEwsQ0FPWSwwQ0FQWixFQU93RCxvRUFQeEQsRUFRS0EsTUFSTCxDQVFZLDBCQVJaLEVBUXdDLDZFQVJ4QyxFQVNLQSxNQVRMLENBU1ksNEJBVFosRUFTMEMseUNBVDFDLEVBVUtBLE1BVkwsQ0FVWSx5Q0FWWixFQVV1RCxzR0FWdkQsRUFXS0EsTUFYTCxDQVdZLHVCQVhaLEVBV3FDLDRCQVhyQyxFQVlLQSxNQVpMLENBWVksa0JBWlosRUFZZ0MsZ0VBWmhDLEVBYUtBLE1BYkwsQ0FhWSxzQkFiWixFQWFvQyx1REFicEMsRUFjS0EsTUFkTCxDQWNZLDRCQWRaLEVBYzBDLDRGQWQxQyxFQWVLQSxNQWZMLENBZVksbUJBZlosRUFlaUMsd0NBZmpDLEVBZ0JLQSxNQWhCTCxDQWdCWSwyQkFoQlosRUFnQnlDLCtDQWhCekMsRUFpQktBLE1BakJMLENBaUJZLHNCQWpCWixFQWlCb0MsMkNBakJwQyxFQWtCS0EsTUFsQkwsQ0FrQlksOEJBbEJaLEVBa0I0QyxrREFsQjVDLEVBbUJLQSxNQW5CTCxDQW1CWSxxQkFuQlosRUFtQm1DLHdFQW5CbkMsRUFvQktBLE1BcEJMLENBb0JZLDRCQXBCWixFQW9CMEMsd0JBcEIxQyxFQXFCS0EsTUFyQkwsQ0FxQlksMkNBckJaLEVBcUJ5RCx1Q0FyQnpELEVBc0JLQSxNQXRCTCxDQXNCWSw4Q0F0QlosRUFzQjRELDBDQXRCNUQsRUF1QktBLE1BdkJMLENBdUJZLGlCQXZCWixFQXVCK0IsNEJBdkIvQixFQXdCS0EsTUF4QkwsQ0F3QlksdUJBeEJaLEVBd0JxQyxpRUF4QnJDLEVBeUJLQSxNQXpCTCxDQXlCWSx5QkF6QlosRUF5QnVDLDZGQXpCdkMsRUEwQktBLE1BMUJMLENBMEJZLDBCQTFCWixFQTBCd0MsMkRBMUJ4QyxFQTJCS0EsTUEzQkwsQ0EyQlksMEJBM0JaLEVBMkJ3QywrSUEzQnhDLEVBNEJLQSxNQTVCTCxDQTRCWSxrQkE1QlosRUE0QmdDLDhDQTVCaEMsRUE2QktBLE1BN0JMLENBNkJZLHVCQTdCWixFQTZCcUMsNkJBN0JyQyxFQThCS0EsTUE5QkwsQ0E4QlksbUJBOUJaLEVBOEJpQyxzQkE5QmpDLEVBK0JLQSxNQS9CTCxDQStCWSxnQkEvQlosRUErQjhCLHNDQS9COUIsRUFnQ0tBLE1BaENMLENBZ0NZLHdCQWhDWixFQWdDc0MsOEZBaEN0QyxFQWlDS0EsTUFqQ0wsQ0FpQ1ksaUJBakNaLEVBaUMrQiwwRUFqQy9CLEVBa0NLQSxNQWxDTCxDQWtDWSx3QkFsQ1osRUFrQ3NDLG9DQWxDdEMsRUFtQ0tBLE1BbkNMLENBbUNZLE9BbkNaLEVBbUNxQiwrQ0FuQ3JCLEVBb0NLQSxNQXBDTCxDQW9DWSxXQXBDWixFQW9DeUIsdUVBcEN6QixFQXFDS0EsTUFyQ0wsQ0FxQ1ksNEJBckNaLEVBcUMwQywyQ0FyQzFDLEVBc0NLQSxNQXRDTCxDQXNDWSxrQ0F0Q1osRUFzQ2dELHlGQXRDaEQsRUF1Q0tBLE1BdkNMLENBdUNZLHlCQXZDWixFQXVDdUMsaUNBdkN2Qzs7QUEwQ0k7QUExQ0osU0EyQ0tBLE1BM0NMLENBMkNZLFNBM0NaLEVBMkN1Qiw4QkEzQ3ZCLEVBNENLQSxNQTVDTCxDQTRDWSxZQTVDWixFQTRDMEIsZ0NBNUMxQjtBQTZDSDs7QUFFREMsMkJBQXdCQyxPQUF4QixFQUFpQztBQUM3QixjQUFNQyxjQUFjRCxRQUFRRSxLQUFSLENBQWMvQyxlQUFkLENBQXBCOztBQUVBLFlBQUk4QyxXQUFKLEVBQWlCO0FBQ2IsaUJBQUtuQyxXQUFMLElBQW9CTyxTQUFTNEIsWUFBWSxDQUFaLENBQVQsRUFBeUIsRUFBekIsS0FBZ0MsQ0FBcEQ7QUFDQSxtQkFBTyxLQUFQO0FBQ0g7O0FBRUQsZUFBTyxJQUFQO0FBQ0g7O0FBRURFLDZCQUEwQjtBQUN0QixhQUFLcEMsSUFBTCxDQUFVcUMsUUFBVixHQUF3Qi9DLGtCQUFrQmlCLG9CQUFsQixDQUF1QyxhQUF2QyxFQUFzRCxLQUFLUCxJQUFMLENBQVVxQyxRQUFoRSxDQUF4QjtBQUNBLGFBQUtyQyxJQUFMLENBQVVzQyxXQUFWLEdBQXdCaEQsa0JBQWtCaUIsb0JBQWxCLENBQXVDLGdCQUF2QyxFQUF5RCxLQUFLUCxJQUFMLENBQVVzQyxXQUFuRSxDQUF4QjtBQUNBLGFBQUt0QyxJQUFMLENBQVV1QyxRQUFWLEdBQXdCakQsa0JBQWtCd0Isc0JBQWxCLENBQXlDLGFBQXpDLEVBQXdELEtBQUtkLElBQUwsQ0FBVXVDLFFBQWxFLENBQXhCO0FBQ0EsYUFBS3ZDLElBQUwsQ0FBVXdDLFdBQVYsR0FBd0JsRCxrQkFBa0J3QixzQkFBbEIsQ0FBeUMsZ0JBQXpDLEVBQTJELEtBQUtkLElBQUwsQ0FBVXdDLFdBQXJFLENBQXhCOztBQUVBLGFBQUsxQyxNQUFMLEdBQWMsQ0FBQzJDLFFBQUQsRUFBV0MsV0FBWCxFQUF3QkMsV0FBeEIsRUFBcUNKLFFBQXJDLEVBQStDQyxXQUEvQyxLQUErRDs7QUFFekUsZ0JBQUksS0FBS3hDLElBQUwsQ0FBVTRDLElBQVYsSUFBa0JILGFBQWEsS0FBS3pDLElBQUwsQ0FBVTRDLElBQTdDLEVBQ0ksT0FBTyxLQUFQOztBQUVKLGdCQUFJLEtBQUs1QyxJQUFMLENBQVVxQyxRQUFWLElBQXNCLENBQUMsS0FBS3JDLElBQUwsQ0FBVXFDLFFBQVYsQ0FBbUJPLElBQW5CLENBQXdCSCxRQUF4QixDQUEzQixFQUNJLE9BQU8sS0FBUDs7QUFFSixnQkFBSSxLQUFLekMsSUFBTCxDQUFVNkMsT0FBVixJQUFxQkgsZ0JBQWdCLEtBQUsxQyxJQUFMLENBQVU2QyxPQUFuRCxFQUNJLE9BQU8sS0FBUDs7QUFFSixnQkFBSSxLQUFLN0MsSUFBTCxDQUFVc0MsV0FBVixJQUF5QixDQUFDLEtBQUt0QyxJQUFMLENBQVVzQyxXQUFWLENBQXNCTSxJQUF0QixDQUEyQkYsV0FBM0IsQ0FBOUIsRUFDSSxPQUFPLEtBQVA7O0FBRUosZ0JBQUksS0FBSzFDLElBQUwsQ0FBVXVDLFFBQVYsSUFBc0IsQ0FBQyxxQkFBUUEsUUFBUixFQUFrQixLQUFLdkMsSUFBTCxDQUFVdUMsUUFBNUIsQ0FBM0IsRUFDSSxPQUFPLEtBQVA7O0FBRUosZ0JBQUksS0FBS3ZDLElBQUwsQ0FBVXdDLFdBQVYsSUFBeUIsQ0FBQyxxQkFBUUEsV0FBUixFQUFxQixLQUFLeEMsSUFBTCxDQUFVd0MsV0FBL0IsQ0FBOUIsRUFDSSxPQUFPLEtBQVA7O0FBRUosbUJBQU8sSUFBUDtBQUNILFNBckJEO0FBc0JIOztBQUVETSx5QkFBc0I7QUFDbEIsWUFBSSxLQUFLOUMsSUFBTCxDQUFVK0MsWUFBZCxFQUE0QjtBQUN4Qiw0Q0FBVzNDLG1CQUFHQyx1QkFBZCxFQUF1QyxJQUF2QyxFQUE2QyxpQ0FBN0MsRUFBZ0YsS0FBS0wsSUFBTCxDQUFVK0MsWUFBMUY7O0FBRUEsaUJBQUsvQyxJQUFMLENBQVUrQyxZQUFWLEdBQXlCekMsU0FBUyxLQUFLTixJQUFMLENBQVUrQyxZQUFuQixFQUFpQyxFQUFqQyxDQUF6QjtBQUNIO0FBQ0o7O0FBRURDLDRCQUF5QjtBQUNyQixZQUFJLEtBQUtoRCxJQUFMLENBQVVpRCxlQUFkLEVBQStCO0FBQzNCLDRDQUFXN0MsbUJBQUdDLHVCQUFkLEVBQXVDLElBQXZDLEVBQTZDLGtCQUE3QyxFQUFpRSxLQUFLTCxJQUFMLENBQVVpRCxlQUEzRTs7QUFFQSxpQkFBS2pELElBQUwsQ0FBVWlELGVBQVYsR0FBNEIzQyxTQUFTLEtBQUtOLElBQUwsQ0FBVWlELGVBQW5CLEVBQW9DLEVBQXBDLENBQTVCO0FBQ0g7QUFDSjs7QUFFREMsNkJBQTBCO0FBQ3RCLFlBQUksS0FBS2xELElBQUwsQ0FBVW1ELGdCQUFkLEVBQWdDO0FBQzVCLDRDQUFXL0MsbUJBQUdDLHVCQUFkLEVBQXVDLElBQXZDLEVBQTZDLG1CQUE3QyxFQUFrRSxLQUFLTCxJQUFMLENBQVVtRCxnQkFBNUU7O0FBRUEsaUJBQUtuRCxJQUFMLENBQVVtRCxnQkFBVixHQUE2QjdDLFNBQVMsS0FBS04sSUFBTCxDQUFVbUQsZ0JBQW5CLEVBQXFDLEVBQXJDLENBQTdCO0FBQ0g7QUFDSjs7QUFFREMsNEJBQXlCO0FBQ3JCLFlBQUksS0FBS3BELElBQUwsQ0FBVXFELGVBQWQsRUFBK0I7QUFDM0IsNENBQVdqRCxtQkFBR0MsdUJBQWQsRUFBdUMsSUFBdkMsRUFBNkMsbUJBQTdDLEVBQWtFLEtBQUtMLElBQUwsQ0FBVXFELGVBQTVFOztBQUVBLGlCQUFLckQsSUFBTCxDQUFVcUQsZUFBVixHQUE0Qi9DLFNBQVMsS0FBS04sSUFBTCxDQUFVcUQsZUFBbkIsRUFBb0MsRUFBcEMsQ0FBNUI7QUFDSDtBQUNKOztBQUVEQyxrQkFBZTtBQUNYLFlBQUksS0FBS3RELElBQUwsQ0FBVXVELEtBQWQsRUFDSSxLQUFLdkQsSUFBTCxDQUFVdUQsS0FBVixHQUFrQkMsV0FBVyxLQUFLeEQsSUFBTCxDQUFVdUQsS0FBckIsQ0FBbEI7QUFDUDs7QUFFREUsd0JBQXFCO0FBQ2pCLFlBQUksS0FBS3pELElBQUwsQ0FBVTBELFdBQWQsRUFDSSxLQUFLQSxXQUFMLEdBQW1CcEQsU0FBUyxLQUFLTixJQUFMLENBQVUwRCxXQUFuQixFQUFnQyxFQUFoQyxDQUFuQjtBQUNQOztBQUVEQyxrQkFBZTtBQUNYLFlBQUksS0FBSzNELElBQUwsQ0FBVTRELEtBQWQsRUFBcUI7QUFDakIsaUJBQUs1RCxJQUFMLENBQVU0RCxLQUFWLEdBQWtCLEtBQUs1RCxJQUFMLENBQVU0RCxLQUFWLENBQ2I1QyxLQURhLENBQ1AsR0FETyxFQUViNkMsR0FGYSxDQUVUdkUsa0JBQWtCWSxnQkFGVCxDQUFsQjs7QUFJQSxnQkFBSSxLQUFLRixJQUFMLENBQVU0RCxLQUFWLENBQWdCckMsTUFBaEIsR0FBeUIsQ0FBN0IsRUFDSSxNQUFNLElBQUlaLHFCQUFKLENBQWlCQyxrQkFBUWtELDZCQUF6QixDQUFOO0FBQ1A7QUFDSjs7QUFFREMsd0JBQXFCO0FBQ2pCLGNBQU1DLGNBQWMsS0FBS3ZFLE9BQUwsQ0FBYXdFLElBQWIsQ0FBa0IsQ0FBbEIsS0FBd0IsRUFBNUM7O0FBRUEsYUFBS3BFLFFBQUwsR0FBZ0IsNkJBQWdCbUUsV0FBaEIsRUFBNkIsR0FBN0IsRUFDWGxFLE1BRFcsQ0FDSm1DLFdBQVdBLFdBQVcsS0FBS0Qsc0JBQUwsQ0FBNEJDLE9BQTVCLENBRGxCLENBQWhCO0FBRUg7O0FBRURpQyx1QkFBb0I7QUFDaEIsWUFBSSxLQUFLbEUsSUFBTCxDQUFVbUUsR0FBZCxFQUNJLEtBQUtuRSxJQUFMLENBQVVtRSxHQUFWLEdBQWdCLCtCQUFnQixLQUFLbkUsSUFBTCxDQUFVbUUsR0FBMUIsQ0FBaEI7QUFDUDs7QUFFS0MsbUJBQU4sR0FBeUI7QUFBQTs7QUFBQTtBQUNyQixnQkFBSSxDQUFDLE1BQUtwRSxJQUFMLENBQVVxRSxRQUFmLEVBQXlCO0FBQ3JCLHNCQUFLckUsSUFBTCxDQUFVc0UsU0FBVixHQUFzQixFQUF0QjtBQUNBO0FBQ0g7O0FBRUQsa0JBQU1BLFlBQVksTUFBS3RFLElBQUwsQ0FBVXFFLFFBQVYsQ0FBbUJyRCxLQUFuQixDQUF5QixHQUF6QixDQUFsQjs7QUFFQSxrQkFBS2hCLElBQUwsQ0FBVXNFLFNBQVYsR0FBc0JBLFVBQVVULEdBQVYsQ0FBYyxvQkFBWTtBQUM1QyxzQkFBTVUsaUJBQWlCRixTQUFTRyxPQUFULENBQWlCLEdBQWpCLENBQXZCOztBQUVBLG9CQUFJRCxpQkFBaUIsQ0FBckIsRUFDSSxPQUFPLEVBQUUvRCxNQUFNNkQsUUFBUixFQUFQOztBQUVKLHNCQUFNN0QsT0FBVTZELFNBQVNJLFNBQVQsQ0FBbUIsQ0FBbkIsRUFBc0JGLGNBQXRCLENBQWhCO0FBQ0Esc0JBQU1HLFVBQVVMLFNBQVNJLFNBQVQsQ0FBbUJGLGlCQUFpQixDQUFwQyxDQUFoQjs7QUFFQSx1QkFBTyxFQUFFL0QsSUFBRixFQUFRa0UsT0FBUixFQUFQO0FBQ0gsYUFWcUIsQ0FBdEI7O0FBWUEsaUNBQXVCLE1BQUsxRSxJQUFMLENBQVVzRSxTQUFqQywySEFBNEM7QUFBQTs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUFBLHNCQUFqQ0QsUUFBaUM7O0FBQ3hDLG9CQUFJQSxTQUFTSyxPQUFiLEVBQXNCO0FBQ2xCTCw2QkFBU0ssT0FBVCxHQUFtQixtQkFBUSxNQUFLbEYsR0FBYixFQUFrQjZFLFNBQVNLLE9BQTNCLENBQW5COztBQUVBLDBCQUFNLHVCQUFRLG1CQUFRTCxTQUFTSyxPQUFqQixDQUFSLENBQU47QUFDSDtBQUNKO0FBMUJvQjtBQTJCeEI7O0FBRURDLHFCQUFrQjtBQUNkLGFBQUsvRSxHQUFMLEdBQVcsS0FBS0gsT0FBTCxDQUFhd0UsSUFBYixDQUFrQlcsS0FBbEIsQ0FBd0IsQ0FBeEIsQ0FBWDtBQUNIOztBQUVEQyx1QkFBb0I7QUFDaEIsYUFBSzdFLElBQUwsQ0FBVThFLFlBQVYsR0FBeUIsS0FBSzlFLElBQUwsQ0FBVStFLFlBQVYsS0FBMkIsSUFBM0IsR0FBa0MsS0FBSyxDQUF2QyxHQUEyQyxLQUFLL0UsSUFBTCxDQUFVK0UsWUFBOUU7QUFDSDs7QUFFS25ELFNBQU4sQ0FBYW9ELElBQWIsRUFBbUI7QUFBQTs7QUFBQTtBQUNmLG1CQUFLdkYsT0FBTCxDQUFhbUMsS0FBYixDQUFtQm9ELElBQW5COztBQUVBLG1CQUFLaEYsSUFBTCxHQUFZLE9BQUtQLE9BQUwsQ0FBYU8sSUFBYixFQUFaOztBQUVBO0FBQ0E7QUFDQSxnQkFBSSxPQUFLQSxJQUFMLENBQVUrRSxZQUFkLEVBQTRCO0FBQ3hCLHVCQUFLRixnQkFBTDtBQUNBO0FBQ0g7O0FBRUQsbUJBQUt6QyxzQkFBTDtBQUNBLG1CQUFLWSxxQkFBTDtBQUNBLG1CQUFLRSxzQkFBTDtBQUNBLG1CQUFLRSxxQkFBTDtBQUNBLG1CQUFLTixrQkFBTDtBQUNBLG1CQUFLUSxXQUFMO0FBQ0EsbUJBQUtLLFdBQUw7QUFDQSxtQkFBS0ksaUJBQUw7QUFDQSxtQkFBS04saUJBQUw7QUFDQSxtQkFBS1MsZ0JBQUw7QUFDQSxtQkFBS1MsY0FBTDs7QUFFQSxrQkFBTSxPQUFLUCxlQUFMLEVBQU47QUF4QmU7QUF5QmxCO0FBcFJrQztrQkFBbEI5RSxpQiIsImZpbGUiOiJjbGkvYXJndW1lbnQtcGFyc2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVzb2x2ZSwgZGlybmFtZSB9IGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgZGVkZW50IGZyb20gJ2RlZGVudCc7XG5pbXBvcnQgeyByZWFkU3luYyBhcyByZWFkIH0gZnJvbSAncmVhZC1maWxlLXJlbGF0aXZlJztcbmltcG9ydCBtYWtlRGlyIGZyb20gJ21ha2UtZGlyJztcbmltcG9ydCB7IEdlbmVyYWxFcnJvciB9IGZyb20gJy4uL2Vycm9ycy9ydW50aW1lJztcbmltcG9ydCBNRVNTQUdFIGZyb20gJy4uL2Vycm9ycy9ydW50aW1lL21lc3NhZ2UnO1xuaW1wb3J0IHsgYXNzZXJ0VHlwZSwgaXMgfSBmcm9tICcuLi9lcnJvcnMvcnVudGltZS90eXBlLWFzc2VydGlvbnMnO1xuaW1wb3J0IGdldFZpZXdQb3J0V2lkdGggZnJvbSAnLi4vdXRpbHMvZ2V0LXZpZXdwb3J0LXdpZHRoJztcbmltcG9ydCB7IHdvcmRXcmFwLCBzcGxpdFF1b3RlZFRleHQgfSBmcm9tICcuLi91dGlscy9zdHJpbmcnO1xuaW1wb3J0IHsgaXNNYXRjaCB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgcGFyc2VTc2xPcHRpb25zIGZyb20gJy4vcGFyc2Utc3NsLW9wdGlvbnMnO1xuXG5jb25zdCBSRU1PVEVfQUxJQVNfUkUgPSAvXnJlbW90ZSg/OjooXFxkKikpPyQvO1xuXG5jb25zdCBERVNDUklQVElPTiA9IGRlZGVudChgXG4gICAgSW4gdGhlIGJyb3dzZXIgbGlzdCwgeW91IGNhbiB1c2UgYnJvd3NlciBuYW1lcyAoZS5nLiBcImllXCIsIFwiY2hyb21lXCIsIGV0Yy4pIGFzIHdlbGwgYXMgcGF0aHMgdG8gZXhlY3V0YWJsZXMuXG5cbiAgICBUbyBydW4gdGVzdHMgYWdhaW5zdCBhbGwgaW5zdGFsbGVkIGJyb3dzZXJzLCB1c2UgdGhlIFwiYWxsXCIgYWxpYXMuXG5cbiAgICBUbyB1c2UgYSByZW1vdGUgYnJvd3NlciBjb25uZWN0aW9uIChlLmcuLCB0byBjb25uZWN0IGEgbW9iaWxlIGRldmljZSksIHNwZWNpZnkgXCJyZW1vdGVcIiBhcyB0aGUgYnJvd3NlciBhbGlhcy5cbiAgICBJZiB5b3UgbmVlZCB0byBjb25uZWN0IG11bHRpcGxlIGRldmljZXMsIGFkZCBhIGNvbG9uIGFuZCB0aGUgbnVtYmVyIG9mIGJyb3dzZXJzIHlvdSB3YW50IHRvIGNvbm5lY3QgKGUuZy4sIFwicmVtb3RlOjNcIikuXG5cbiAgICBUbyBydW4gdGVzdHMgaW4gYSBicm93c2VyIGFjY2Vzc2VkIHRocm91Z2ggYSBicm93c2VyIHByb3ZpZGVyIHBsdWdpbiwgc3BlY2lmeSBhIGJyb3dzZXIgYWxpYXMgdGhhdCBjb25zaXN0cyBvZiB0d28gcGFydHMgLSB0aGUgYnJvd3NlciBwcm92aWRlciBuYW1lIHByZWZpeCBhbmQgdGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIgaXRzZWxmOyBmb3IgZXhhbXBsZSwgXCJzYXVjZWxhYnM6Y2hyb21lQDUxXCIuXG5cbiAgICBZb3UgY2FuIHVzZSBvbmUgb3IgbW9yZSBmaWxlIHBhdGhzIG9yIGdsb2IgcGF0dGVybnMgdG8gc3BlY2lmeSB3aGljaCB0ZXN0cyB0byBydW4uXG5cbiAgICBNb3JlIGluZm86IGh0dHBzOi8vZGV2ZXhwcmVzcy5naXRodWIuaW8vdGVzdGNhZmUvZG9jdW1lbnRhdGlvblxuYCk7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENMSUFyZ3VtZW50UGFyc2VyIHtcbiAgICBjb25zdHJ1Y3RvciAoY3dkKSB7XG4gICAgICAgIHRoaXMucHJvZ3JhbSA9IG5ldyBDb21tYW5kKCd0ZXN0Y2FmZScpO1xuXG4gICAgICAgIHRoaXMuY3dkID0gY3dkIHx8IHByb2Nlc3MuY3dkKCk7XG5cbiAgICAgICAgdGhpcy5zcmMgICAgICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMuYnJvd3NlcnMgICAgPSBudWxsO1xuICAgICAgICB0aGlzLmZpbHRlciAgICAgID0gbnVsbDtcbiAgICAgICAgdGhpcy5yZW1vdGVDb3VudCA9IDA7XG4gICAgICAgIHRoaXMub3B0cyAgICAgICAgPSBudWxsO1xuXG4gICAgICAgIHRoaXMuX2Rlc2NyaWJlUHJvZ3JhbSgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBfcGFyc2VQb3J0TnVtYmVyICh2YWx1ZSkge1xuICAgICAgICBhc3NlcnRUeXBlKGlzLm5vbk5lZ2F0aXZlTnVtYmVyU3RyaW5nLCBudWxsLCAnUG9ydCBudW1iZXInLCB2YWx1ZSk7XG5cbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgfVxuXG4gICAgc3RhdGljIF9vcHRpb25WYWx1ZVRvUmVnRXhwIChuYW1lLCB2YWx1ZSkge1xuICAgICAgICBpZiAodmFsdWUgPT09IHZvaWQgMClcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWdFeHAodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBHZW5lcmFsRXJyb3IoTUVTU0FHRS5vcHRpb25WYWx1ZUlzTm90VmFsaWRSZWdFeHAsIG5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIF9vcHRpb25WYWx1ZVRvS2V5VmFsdWUgKG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdm9pZCAwKVxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuXG4gICAgICAgIGNvbnN0IGtleVZhbHVlID0gdmFsdWUuc3BsaXQoJywnKS5yZWR1Y2UoKG9iaiwgcGFpcikgPT4ge1xuICAgICAgICAgICAgY29uc3QgW2tleSwgdmFsXSA9IHBhaXIuc3BsaXQoJz0nKTtcblxuICAgICAgICAgICAgaWYgKCFrZXkgfHwgIXZhbClcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgR2VuZXJhbEVycm9yKE1FU1NBR0Uub3B0aW9uVmFsdWVJc05vdFZhbGlkS2V5VmFsdWUsIG5hbWUpO1xuXG4gICAgICAgICAgICBvYmpba2V5XSA9IHZhbDtcbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIHt9KTtcblxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoa2V5VmFsdWUpLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHRocm93IG5ldyBHZW5lcmFsRXJyb3IoTUVTU0FHRS5vcHRpb25WYWx1ZUlzTm90VmFsaWRLZXlWYWx1ZSwgbmFtZSk7XG5cbiAgICAgICAgcmV0dXJuIGtleVZhbHVlO1xuICAgIH1cblxuICAgIHN0YXRpYyBfZ2V0RGVzY3JpcHRpb24gKCkge1xuICAgICAgICAvLyBOT1RFOiBhZGQgZW1wdHkgbGluZSB0byB3b3JrYXJvdW5kIGNvbW1hbmRlci1mb3JjZWQgaW5kZW50YXRpb24gb24gdGhlIGZpcnN0IGxpbmUuXG4gICAgICAgIHJldHVybiAnXFxuJyArIHdvcmRXcmFwKERFU0NSSVBUSU9OLCAyLCBnZXRWaWV3UG9ydFdpZHRoKHByb2Nlc3Muc3Rkb3V0KSk7XG4gICAgfVxuXG4gICAgX2Rlc2NyaWJlUHJvZ3JhbSAoKSB7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSBKU09OLnBhcnNlKHJlYWQoJy4uLy4uL3BhY2thZ2UuanNvbicpKS52ZXJzaW9uO1xuXG4gICAgICAgIHRoaXMucHJvZ3JhbVxuXG4gICAgICAgICAgICAudmVyc2lvbih2ZXJzaW9uLCAnLXYsIC0tdmVyc2lvbicpXG4gICAgICAgICAgICAudXNhZ2UoJ1tvcHRpb25zXSA8Y29tbWEtc2VwYXJhdGVkLWJyb3dzZXItbGlzdD4gPGZpbGUtb3ItZ2xvYiAuLi4+JylcbiAgICAgICAgICAgIC5kZXNjcmlwdGlvbihDTElBcmd1bWVudFBhcnNlci5fZ2V0RGVzY3JpcHRpb24oKSlcblxuICAgICAgICAgICAgLm9wdGlvbignLWIsIC0tbGlzdC1icm93c2VycyBbcHJvdmlkZXJdJywgJ291dHB1dCB0aGUgYWxpYXNlcyBmb3IgbG9jYWwgYnJvd3NlcnMgb3IgYnJvd3NlcnMgYXZhaWxhYmxlIHRocm91Z2ggdGhlIHNwZWNpZmllZCBicm93c2VyIHByb3ZpZGVyJylcbiAgICAgICAgICAgIC5vcHRpb24oJy1yLCAtLXJlcG9ydGVyIDxuYW1lWzpvdXRwdXRGaWxlXVssLi4uXT4nLCAnc3BlY2lmeSB0aGUgcmVwb3J0ZXJzIGFuZCBvcHRpb25hbGx5IGZpbGVzIHdoZXJlIHJlcG9ydHMgYXJlIHNhdmVkJylcbiAgICAgICAgICAgIC5vcHRpb24oJy1zLCAtLXNjcmVlbnNob3RzIDxwYXRoPicsICdlbmFibGUgc2NyZWVuc2hvdCBjYXB0dXJpbmcgYW5kIHNwZWNpZnkgdGhlIHBhdGggdG8gc2F2ZSB0aGUgc2NyZWVuc2hvdHMgdG8nKVxuICAgICAgICAgICAgLm9wdGlvbignLVMsIC0tc2NyZWVuc2hvdHMtb24tZmFpbHMnLCAndGFrZSBhIHNjcmVlbnNob3Qgd2hlbmV2ZXIgYSB0ZXN0IGZhaWxzJylcbiAgICAgICAgICAgIC5vcHRpb24oJy1wLCAtLXNjcmVlbnNob3QtcGF0aC1wYXR0ZXJuIDxwYXR0ZXJuPicsICd1c2UgcGF0dGVybnMgdG8gY29tcG9zZSBzY3JlZW5zaG90IGZpbGUgbmFtZXMgYW5kIHBhdGhzOiAke0JST1dTRVJ9LCAke0JST1dTRVJfVkVSU0lPTn0sICR7T1N9LCBldGMuJylcbiAgICAgICAgICAgIC5vcHRpb24oJy1xLCAtLXF1YXJhbnRpbmUtbW9kZScsICdlbmFibGUgdGhlIHF1YXJhbnRpbmUgbW9kZScpXG4gICAgICAgICAgICAub3B0aW9uKCctZCwgLS1kZWJ1Zy1tb2RlJywgJ2V4ZWN1dGUgdGVzdCBzdGVwcyBvbmUgYnkgb25lIHBhdXNpbmcgdGhlIHRlc3QgYWZ0ZXIgZWFjaCBzdGVwJylcbiAgICAgICAgICAgIC5vcHRpb24oJy1lLCAtLXNraXAtanMtZXJyb3JzJywgJ21ha2UgdGVzdHMgbm90IGZhaWwgd2hlbiBhIEpTIGVycm9yIGhhcHBlbnMgb24gYSBwYWdlJylcbiAgICAgICAgICAgIC5vcHRpb24oJy11LCAtLXNraXAtdW5jYXVnaHQtZXJyb3JzJywgJ2lnbm9yZSB1bmNhdWdodCBlcnJvcnMgYW5kIHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbnMsIHdoaWNoIG9jY3VyIGR1cmluZyB0ZXN0IGV4ZWN1dGlvbicpXG4gICAgICAgICAgICAub3B0aW9uKCctdCwgLS10ZXN0IDxuYW1lPicsICdydW4gb25seSB0ZXN0cyB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZScpXG4gICAgICAgICAgICAub3B0aW9uKCctVCwgLS10ZXN0LWdyZXAgPHBhdHRlcm4+JywgJ3J1biBvbmx5IHRlc3RzIG1hdGNoaW5nIHRoZSBzcGVjaWZpZWQgcGF0dGVybicpXG4gICAgICAgICAgICAub3B0aW9uKCctZiwgLS1maXh0dXJlIDxuYW1lPicsICdydW4gb25seSBmaXh0dXJlcyB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZScpXG4gICAgICAgICAgICAub3B0aW9uKCctRiwgLS1maXh0dXJlLWdyZXAgPHBhdHRlcm4+JywgJ3J1biBvbmx5IGZpeHR1cmVzIG1hdGNoaW5nIHRoZSBzcGVjaWZpZWQgcGF0dGVybicpXG4gICAgICAgICAgICAub3B0aW9uKCctYSwgLS1hcHAgPGNvbW1hbmQ+JywgJ2xhdW5jaCB0aGUgdGVzdGVkIGFwcCB1c2luZyB0aGUgc3BlY2lmaWVkIGNvbW1hbmQgYmVmb3JlIHJ1bm5pbmcgdGVzdHMnKVxuICAgICAgICAgICAgLm9wdGlvbignLWMsIC0tY29uY3VycmVuY3kgPG51bWJlcj4nLCAncnVuIHRlc3RzIGNvbmN1cnJlbnRseScpXG4gICAgICAgICAgICAub3B0aW9uKCctLXRlc3QtbWV0YSA8a2V5PXZhbHVlWyxrZXkyPXZhbHVlMiwuLi5dPicsICdydW4gb25seSB0ZXN0cyB3aXRoIG1hdGNoaW5nIG1ldGFkYXRhJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tZml4dHVyZS1tZXRhIDxrZXk9dmFsdWVbLGtleTI9dmFsdWUyLC4uLl0+JywgJ3J1biBvbmx5IGZpeHR1cmVzIHdpdGggbWF0Y2hpbmcgbWV0YWRhdGEnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1kZWJ1Zy1vbi1mYWlsJywgJ3BhdXNlIHRoZSB0ZXN0IGlmIGl0IGZhaWxzJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tYXBwLWluaXQtZGVsYXkgPG1zPicsICdzcGVjaWZ5IGhvdyBtdWNoIHRpbWUgaXQgdGFrZXMgZm9yIHRoZSB0ZXN0ZWQgYXBwIHRvIGluaXRpYWxpemUnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1zZWxlY3Rvci10aW1lb3V0IDxtcz4nLCAnc2V0IHRoZSBhbW91bnQgb2YgdGltZSB3aXRoaW4gd2hpY2ggc2VsZWN0b3JzIG1ha2UgYXR0ZW1wdHMgdG8gb2J0YWluIGEgbm9kZSB0byBiZSByZXR1cm5lZCcpXG4gICAgICAgICAgICAub3B0aW9uKCctLWFzc2VydGlvbi10aW1lb3V0IDxtcz4nLCAnc2V0IHRoZSBhbW91bnQgb2YgdGltZSB3aXRoaW4gd2hpY2ggYXNzZXJ0aW9uIHNob3VsZCBwYXNzJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tcGFnZS1sb2FkLXRpbWVvdXQgPG1zPicsICdzZXQgdGhlIGFtb3VudCBvZiB0aW1lIHdpdGhpbiB3aGljaCBUZXN0Q2FmZSB3YWl0cyBmb3IgdGhlIGB3aW5kb3cubG9hZGAgZXZlbnQgdG8gZmlyZSBvbiBwYWdlIGxvYWQgYmVmb3JlIHByb2NlZWRpbmcgdG8gdGhlIG5leHQgdGVzdCBhY3Rpb24nKVxuICAgICAgICAgICAgLm9wdGlvbignLS1zcGVlZCA8ZmFjdG9yPicsICdzZXQgdGhlIHNwZWVkIG9mIHRlc3QgZXhlY3V0aW9uICgwLjAxIC4uLiAxKScpXG4gICAgICAgICAgICAub3B0aW9uKCctLXBvcnRzIDxwb3J0MSxwb3J0Mj4nLCAnc3BlY2lmeSBjdXN0b20gcG9ydCBudW1iZXJzJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0taG9zdG5hbWUgPG5hbWU+JywgJ3NwZWNpZnkgdGhlIGhvc3RuYW1lJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tcHJveHkgPGhvc3Q+JywgJ3NwZWNpZnkgdGhlIGhvc3Qgb2YgdGhlIHByb3h5IHNlcnZlcicpXG4gICAgICAgICAgICAub3B0aW9uKCctLXByb3h5LWJ5cGFzcyA8cnVsZXM+JywgJ3NwZWNpZnkgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBydWxlcyB0aGF0IGRlZmluZSBVUkxzIGFjY2Vzc2VkIGJ5cGFzc2luZyB0aGUgcHJveHkgc2VydmVyJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tc3NsIDxvcHRpb25zPicsICdzcGVjaWZ5IFNTTCBvcHRpb25zIHRvIHJ1biBUZXN0Q2FmZSBwcm94eSBzZXJ2ZXIgb3ZlciB0aGUgSFRUUFMgcHJvdG9jb2wnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1kaXNhYmxlLXBhZ2UtcmVsb2FkcycsICdkaXNhYmxlIHBhZ2UgcmVsb2FkcyBiZXR3ZWVuIHRlc3RzJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tZGV2JywgJ2VuYWJsZXMgbWVjaGFuaXNtcyB0byBsb2cgYW5kIGRpYWdub3NlIGVycm9ycycpXG4gICAgICAgICAgICAub3B0aW9uKCctLXFyLWNvZGUnLCAnb3V0cHV0cyBRUi1jb2RlIHRoYXQgcmVwZWF0cyBVUkxzIHVzZWQgdG8gY29ubmVjdCB0aGUgcmVtb3RlIGJyb3dzZXJzJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tc2YsIC0tc3RvcC1vbi1maXJzdC1mYWlsJywgJ3N0b3AgYW4gZW50aXJlIHRlc3QgcnVuIGlmIGFueSB0ZXN0IGZhaWxzJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tZGlzYWJsZS10ZXN0LXN5bnRheC12YWxpZGF0aW9uJywgJ2Rpc2FibGVzIGNoZWNrcyBmb3IgXFwndGVzdFxcJyBhbmQgXFwnZml4dHVyZVxcJyBkaXJlY3RpdmVzIHRvIHJ1biBkeW5hbWljYWxseSBsb2FkZWQgdGVzdHMnKVxuICAgICAgICAgICAgLm9wdGlvbignLS1yZWNvcmQtc2NyZWVuLWNhcHR1cmUnLCAndGFrZSBzY3JlZW5zaG90cyBvZiBlYWNoIGFjdGlvbicpXG5cblxuICAgICAgICAgICAgLy8gTk9URTogdGhlc2Ugb3B0aW9ucyB3aWxsIGJlIGhhbmRsZWQgYnkgY2hhbGsgaW50ZXJuYWxseVxuICAgICAgICAgICAgLm9wdGlvbignLS1jb2xvcicsICdmb3JjZSBjb2xvcnMgaW4gY29tbWFuZCBsaW5lJylcbiAgICAgICAgICAgIC5vcHRpb24oJy0tbm8tY29sb3InLCAnZGlzYWJsZSBjb2xvcnMgaW4gY29tbWFuZCBsaW5lJyk7XG4gICAgfVxuXG4gICAgX2ZpbHRlckFuZENvdW50UmVtb3RlcyAoYnJvd3Nlcikge1xuICAgICAgICBjb25zdCByZW1vdGVNYXRjaCA9IGJyb3dzZXIubWF0Y2goUkVNT1RFX0FMSUFTX1JFKTtcblxuICAgICAgICBpZiAocmVtb3RlTWF0Y2gpIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ291bnQgKz0gcGFyc2VJbnQocmVtb3RlTWF0Y2hbMV0sIDEwKSB8fCAxO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgX3BhcnNlRmlsdGVyaW5nT3B0aW9ucyAoKSB7XG4gICAgICAgIHRoaXMub3B0cy50ZXN0R3JlcCAgICA9IENMSUFyZ3VtZW50UGFyc2VyLl9vcHRpb25WYWx1ZVRvUmVnRXhwKCctLXRlc3QtZ3JlcCcsIHRoaXMub3B0cy50ZXN0R3JlcCk7XG4gICAgICAgIHRoaXMub3B0cy5maXh0dXJlR3JlcCA9IENMSUFyZ3VtZW50UGFyc2VyLl9vcHRpb25WYWx1ZVRvUmVnRXhwKCctLWZpeHR1cmUtZ3JlcCcsIHRoaXMub3B0cy5maXh0dXJlR3JlcCk7XG4gICAgICAgIHRoaXMub3B0cy50ZXN0TWV0YSAgICA9IENMSUFyZ3VtZW50UGFyc2VyLl9vcHRpb25WYWx1ZVRvS2V5VmFsdWUoJy0tdGVzdC1tZXRhJywgdGhpcy5vcHRzLnRlc3RNZXRhKTtcbiAgICAgICAgdGhpcy5vcHRzLmZpeHR1cmVNZXRhID0gQ0xJQXJndW1lbnRQYXJzZXIuX29wdGlvblZhbHVlVG9LZXlWYWx1ZSgnLS1maXh0dXJlLW1ldGEnLCB0aGlzLm9wdHMuZml4dHVyZU1ldGEpO1xuXG4gICAgICAgIHRoaXMuZmlsdGVyID0gKHRlc3ROYW1lLCBmaXh0dXJlTmFtZSwgZml4dHVyZVBhdGgsIHRlc3RNZXRhLCBmaXh0dXJlTWV0YSkgPT4ge1xuXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRzLnRlc3QgJiYgdGVzdE5hbWUgIT09IHRoaXMub3B0cy50ZXN0KVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy50ZXN0R3JlcCAmJiAhdGhpcy5vcHRzLnRlc3RHcmVwLnRlc3QodGVzdE5hbWUpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5maXh0dXJlICYmIGZpeHR1cmVOYW1lICE9PSB0aGlzLm9wdHMuZml4dHVyZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMuZml4dHVyZUdyZXAgJiYgIXRoaXMub3B0cy5maXh0dXJlR3JlcC50ZXN0KGZpeHR1cmVOYW1lKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdHMudGVzdE1ldGEgJiYgIWlzTWF0Y2godGVzdE1ldGEsIHRoaXMub3B0cy50ZXN0TWV0YSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5vcHRzLmZpeHR1cmVNZXRhICYmICFpc01hdGNoKGZpeHR1cmVNZXRhLCB0aGlzLm9wdHMuZml4dHVyZU1ldGEpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgX3BhcnNlQXBwSW5pdERlbGF5ICgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5hcHBJbml0RGVsYXkpIHtcbiAgICAgICAgICAgIGFzc2VydFR5cGUoaXMubm9uTmVnYXRpdmVOdW1iZXJTdHJpbmcsIG51bGwsICdUZXN0ZWQgYXBwIGluaXRpYWxpemF0aW9uIGRlbGF5JywgdGhpcy5vcHRzLmFwcEluaXREZWxheSk7XG5cbiAgICAgICAgICAgIHRoaXMub3B0cy5hcHBJbml0RGVsYXkgPSBwYXJzZUludCh0aGlzLm9wdHMuYXBwSW5pdERlbGF5LCAxMCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfcGFyc2VTZWxlY3RvclRpbWVvdXQgKCkge1xuICAgICAgICBpZiAodGhpcy5vcHRzLnNlbGVjdG9yVGltZW91dCkge1xuICAgICAgICAgICAgYXNzZXJ0VHlwZShpcy5ub25OZWdhdGl2ZU51bWJlclN0cmluZywgbnVsbCwgJ1NlbGVjdG9yIHRpbWVvdXQnLCB0aGlzLm9wdHMuc2VsZWN0b3JUaW1lb3V0KTtcblxuICAgICAgICAgICAgdGhpcy5vcHRzLnNlbGVjdG9yVGltZW91dCA9IHBhcnNlSW50KHRoaXMub3B0cy5zZWxlY3RvclRpbWVvdXQsIDEwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9wYXJzZUFzc2VydGlvblRpbWVvdXQgKCkge1xuICAgICAgICBpZiAodGhpcy5vcHRzLmFzc2VydGlvblRpbWVvdXQpIHtcbiAgICAgICAgICAgIGFzc2VydFR5cGUoaXMubm9uTmVnYXRpdmVOdW1iZXJTdHJpbmcsIG51bGwsICdBc3NlcnRpb24gdGltZW91dCcsIHRoaXMub3B0cy5hc3NlcnRpb25UaW1lb3V0KTtcblxuICAgICAgICAgICAgdGhpcy5vcHRzLmFzc2VydGlvblRpbWVvdXQgPSBwYXJzZUludCh0aGlzLm9wdHMuYXNzZXJ0aW9uVGltZW91dCwgMTApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3BhcnNlUGFnZUxvYWRUaW1lb3V0ICgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5wYWdlTG9hZFRpbWVvdXQpIHtcbiAgICAgICAgICAgIGFzc2VydFR5cGUoaXMubm9uTmVnYXRpdmVOdW1iZXJTdHJpbmcsIG51bGwsICdQYWdlIGxvYWQgdGltZW91dCcsIHRoaXMub3B0cy5wYWdlTG9hZFRpbWVvdXQpO1xuXG4gICAgICAgICAgICB0aGlzLm9wdHMucGFnZUxvYWRUaW1lb3V0ID0gcGFyc2VJbnQodGhpcy5vcHRzLnBhZ2VMb2FkVGltZW91dCwgMTApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX3BhcnNlU3BlZWQgKCkge1xuICAgICAgICBpZiAodGhpcy5vcHRzLnNwZWVkKVxuICAgICAgICAgICAgdGhpcy5vcHRzLnNwZWVkID0gcGFyc2VGbG9hdCh0aGlzLm9wdHMuc3BlZWQpO1xuICAgIH1cblxuICAgIF9wYXJzZUNvbmN1cnJlbmN5ICgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5jb25jdXJyZW5jeSlcbiAgICAgICAgICAgIHRoaXMuY29uY3VycmVuY3kgPSBwYXJzZUludCh0aGlzLm9wdHMuY29uY3VycmVuY3ksIDEwKTtcbiAgICB9XG5cbiAgICBfcGFyc2VQb3J0cyAoKSB7XG4gICAgICAgIGlmICh0aGlzLm9wdHMucG9ydHMpIHtcbiAgICAgICAgICAgIHRoaXMub3B0cy5wb3J0cyA9IHRoaXMub3B0cy5wb3J0c1xuICAgICAgICAgICAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAgICAgICAgICAgLm1hcChDTElBcmd1bWVudFBhcnNlci5fcGFyc2VQb3J0TnVtYmVyKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMub3B0cy5wb3J0cy5sZW5ndGggPCAyKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBHZW5lcmFsRXJyb3IoTUVTU0FHRS5wb3J0c09wdGlvblJlcXVpcmVzVHdvTnVtYmVycyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfcGFyc2VCcm93c2VyTGlzdCAoKSB7XG4gICAgICAgIGNvbnN0IGJyb3dzZXJzQXJnID0gdGhpcy5wcm9ncmFtLmFyZ3NbMF0gfHwgJyc7XG5cbiAgICAgICAgdGhpcy5icm93c2VycyA9IHNwbGl0UXVvdGVkVGV4dChicm93c2Vyc0FyZywgJywnKVxuICAgICAgICAgICAgLmZpbHRlcihicm93c2VyID0+IGJyb3dzZXIgJiYgdGhpcy5fZmlsdGVyQW5kQ291bnRSZW1vdGVzKGJyb3dzZXIpKTtcbiAgICB9XG5cbiAgICBfcGFyc2VTc2xPcHRpb25zICgpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0cy5zc2wpXG4gICAgICAgICAgICB0aGlzLm9wdHMuc3NsID0gcGFyc2VTc2xPcHRpb25zKHRoaXMub3B0cy5zc2wpO1xuICAgIH1cblxuICAgIGFzeW5jIF9wYXJzZVJlcG9ydGVycyAoKSB7XG4gICAgICAgIGlmICghdGhpcy5vcHRzLnJlcG9ydGVyKSB7XG4gICAgICAgICAgICB0aGlzLm9wdHMucmVwb3J0ZXJzID0gW107XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXBvcnRlcnMgPSB0aGlzLm9wdHMucmVwb3J0ZXIuc3BsaXQoJywnKTtcblxuICAgICAgICB0aGlzLm9wdHMucmVwb3J0ZXJzID0gcmVwb3J0ZXJzLm1hcChyZXBvcnRlciA9PiB7XG4gICAgICAgICAgICBjb25zdCBzZXBhcmF0b3JJbmRleCA9IHJlcG9ydGVyLmluZGV4T2YoJzonKTtcblxuICAgICAgICAgICAgaWYgKHNlcGFyYXRvckluZGV4IDwgMClcbiAgICAgICAgICAgICAgICByZXR1cm4geyBuYW1lOiByZXBvcnRlciB9O1xuXG4gICAgICAgICAgICBjb25zdCBuYW1lICAgID0gcmVwb3J0ZXIuc3Vic3RyaW5nKDAsIHNlcGFyYXRvckluZGV4KTtcbiAgICAgICAgICAgIGNvbnN0IG91dEZpbGUgPSByZXBvcnRlci5zdWJzdHJpbmcoc2VwYXJhdG9ySW5kZXggKyAxKTtcblxuICAgICAgICAgICAgcmV0dXJuIHsgbmFtZSwgb3V0RmlsZSB9O1xuICAgICAgICB9KTtcblxuICAgICAgICBmb3IgKGNvbnN0IHJlcG9ydGVyIG9mIHRoaXMub3B0cy5yZXBvcnRlcnMpIHtcbiAgICAgICAgICAgIGlmIChyZXBvcnRlci5vdXRGaWxlKSB7XG4gICAgICAgICAgICAgICAgcmVwb3J0ZXIub3V0RmlsZSA9IHJlc29sdmUodGhpcy5jd2QsIHJlcG9ydGVyLm91dEZpbGUpO1xuXG4gICAgICAgICAgICAgICAgYXdhaXQgbWFrZURpcihkaXJuYW1lKHJlcG9ydGVyLm91dEZpbGUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9wYXJzZUZpbGVMaXN0ICgpIHtcbiAgICAgICAgdGhpcy5zcmMgPSB0aGlzLnByb2dyYW0uYXJncy5zbGljZSgxKTtcbiAgICB9XG5cbiAgICBfZ2V0UHJvdmlkZXJOYW1lICgpIHtcbiAgICAgICAgdGhpcy5vcHRzLnByb3ZpZGVyTmFtZSA9IHRoaXMub3B0cy5saXN0QnJvd3NlcnMgPT09IHRydWUgPyB2b2lkIDAgOiB0aGlzLm9wdHMubGlzdEJyb3dzZXJzO1xuICAgIH1cblxuICAgIGFzeW5jIHBhcnNlIChhcmd2KSB7XG4gICAgICAgIHRoaXMucHJvZ3JhbS5wYXJzZShhcmd2KTtcblxuICAgICAgICB0aGlzLm9wdHMgPSB0aGlzLnByb2dyYW0ub3B0cygpO1xuXG4gICAgICAgIC8vIE5PVEU6IHRoZSAnLWxpc3QtYnJvd3NlcnMnIG9wdGlvbiBvbmx5IGxpc3RzIGJyb3dzZXJzIGFuZCBpbW1lZGlhdGVseSBleGl0cyB0aGUgYXBwLlxuICAgICAgICAvLyBUaGVyZWZvcmUsIHdlIGRvbid0IG5lZWQgdG8gcHJvY2VzcyBvdGhlciBhcmd1bWVudHMuXG4gICAgICAgIGlmICh0aGlzLm9wdHMubGlzdEJyb3dzZXJzKSB7XG4gICAgICAgICAgICB0aGlzLl9nZXRQcm92aWRlck5hbWUoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3BhcnNlRmlsdGVyaW5nT3B0aW9ucygpO1xuICAgICAgICB0aGlzLl9wYXJzZVNlbGVjdG9yVGltZW91dCgpO1xuICAgICAgICB0aGlzLl9wYXJzZUFzc2VydGlvblRpbWVvdXQoKTtcbiAgICAgICAgdGhpcy5fcGFyc2VQYWdlTG9hZFRpbWVvdXQoKTtcbiAgICAgICAgdGhpcy5fcGFyc2VBcHBJbml0RGVsYXkoKTtcbiAgICAgICAgdGhpcy5fcGFyc2VTcGVlZCgpO1xuICAgICAgICB0aGlzLl9wYXJzZVBvcnRzKCk7XG4gICAgICAgIHRoaXMuX3BhcnNlQnJvd3Nlckxpc3QoKTtcbiAgICAgICAgdGhpcy5fcGFyc2VDb25jdXJyZW5jeSgpO1xuICAgICAgICB0aGlzLl9wYXJzZVNzbE9wdGlvbnMoKTtcbiAgICAgICAgdGhpcy5fcGFyc2VGaWxlTGlzdCgpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuX3BhcnNlUmVwb3J0ZXJzKCk7XG4gICAgfVxufVxuIl19 diff --git a/lib/cli/cli.js b/lib/cli/cli.js new file mode 100644 index 00000000..59934b7f --- /dev/null +++ b/lib/cli/cli.js @@ -0,0 +1,187 @@ +'use strict'; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +let runTests = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (argParser) { + const opts = argParser.opts; + const port1 = opts.ports && opts.ports[0]; + const port2 = opts.ports && opts.ports[1]; + const externalProxyHost = opts.proxy; + const proxyBypass = opts.proxyBypass; + + _log2.default.showSpinner(); + + const testCafe = yield (0, _2.default)(opts.hostname, port1, port2, opts.ssl, opts.dev); + const concurrency = argParser.concurrency || 1; + const remoteBrowsers = yield (0, _remotesWizard2.default)(testCafe, argParser.remoteCount, opts.qrCode); + const browsers = argParser.browsers.concat(remoteBrowsers); + const runner = testCafe.createRunner(); + let failed = 0; + const reporters = argParser.opts.reporters.map(function (r) { + return { + name: r.name, + outStream: r.outFile ? _fs2.default.createWriteStream(r.outFile) : void 0 + }; + }); + + reporters.forEach(function (r) { + return runner.reporter(r.name, r.outStream); + }); + + runner.useProxy(externalProxyHost, proxyBypass).src(argParser.src).browsers(browsers).concurrency(concurrency).filter(argParser.filter).screenshots(opts.screenshots, opts.screenshotsOnFails, opts.screenshotPathPattern, opts.recordScreenCapture).startApp(opts.app, opts.appInitDelay); + + runner.once('done-bootstrapping', function () { + return _log2.default.hideSpinner(); + }); + + try { + failed = yield runner.run(opts); + } finally { + showMessageOnExit = false; + yield testCafe.close(); + } + + exit(failed); + }); + + return function runTests(_x) { + return _ref.apply(this, arguments); + }; +})(); + +let listBrowsers = (() => { + var _ref2 = (0, _asyncToGenerator3.default)(function* (providerName = 'locally-installed') { + // NOTE: Load the provider pool lazily to reduce startup time + const browserProviderPool = require('../browser/provider/pool'); + + const provider = yield browserProviderPool.getProvider(providerName); + + if (!provider) throw new _runtime.GeneralError(_message2.default.browserProviderNotFound, providerName); + + if (provider.isMultiBrowser) { + const browserNames = yield provider.getBrowserList(); + + yield browserProviderPool.dispose(); + + if (providerName === 'locally-installed') console.log(browserNames.join('\n'));else console.log(browserNames.map(function (browserName) { + return `"${providerName}:${browserName}"`; + }).join('\n')); + } else console.log(`"${providerName}"`); + + exit(0); + }); + + return function listBrowsers() { + return _ref2.apply(this, arguments); + }; +})(); + +var _fs = require('fs'); + +var _fs2 = _interopRequireDefault(_fs); + +var _chalk = require('chalk'); + +var _chalk2 = _interopRequireDefault(_chalk); + +var _runtime = require('../errors/runtime'); + +var _message = require('../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +var _argumentParser = require('./argument-parser'); + +var _argumentParser2 = _interopRequireDefault(_argumentParser); + +var _terminationHandler = require('./termination-handler'); + +var _terminationHandler2 = _interopRequireDefault(_terminationHandler); + +var _log = require('./log'); + +var _log2 = _interopRequireDefault(_log); + +var _remotesWizard = require('./remotes-wizard'); + +var _remotesWizard2 = _interopRequireDefault(_remotesWizard); + +var _ = require('../'); + +var _2 = _interopRequireDefault(_); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let showMessageOnExit = true; +let exitMessageShown = false; +let exiting = false; + +function exitHandler(terminationLevel) { + if (showMessageOnExit && !exitMessageShown) { + exitMessageShown = true; + + _log2.default.hideSpinner(); + _log2.default.write('Stopping TestCafe...'); + _log2.default.showSpinner(); + + process.on('exit', () => _log2.default.hideSpinner(true)); + } + + if (exiting || terminationLevel < 2) return; + + exiting = true; + + exit(0); +} + +function exit(code) { + _log2.default.hideSpinner(true); + + // NOTE: give a process time to flush the output. + // It's necessary in some environments. + setTimeout(() => process.exit(code), 0); +} + +function error(err) { + _log2.default.hideSpinner(); + + let message = null; + + // HACK: workaround for the `instanceof` problem + // (see: http://stackoverflow.com/questions/33870684/why-doesnt-instanceof-work-on-instances-of-error-subclasses-under-babel-node) + if (err.constructor === _runtime.GeneralError) message = err.message;else if (err.constructor === _runtime.APIError) message = err.coloredStack;else message = err.stack; + + _log2.default.write(_chalk2.default.red('ERROR ') + message + '\n'); + _log2.default.write(_chalk2.default.gray('Type "testcafe -h" for help.')); + + exit(1); +} + +(() => { + var _ref3 = (0, _asyncToGenerator3.default)(function* () { + const terminationHandler = new _terminationHandler2.default(); + + terminationHandler.on(_terminationHandler2.default.TERMINATION_LEVEL_INCREASED_EVENT, exitHandler); + + try { + const argParser = new _argumentParser2.default(); + + yield argParser.parse(process.argv); + + if (argParser.opts.listBrowsers) yield listBrowsers(argParser.opts.providerName);else yield runTests(argParser); + } catch (err) { + showMessageOnExit = false; + error(err); + } + }); + + function cli() { + return _ref3.apply(this, arguments); + } + + return cli; +})()(); +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvY2xpLmpzIl0sIm5hbWVzIjpbImFyZ1BhcnNlciIsIm9wdHMiLCJwb3J0MSIsInBvcnRzIiwicG9ydDIiLCJleHRlcm5hbFByb3h5SG9zdCIsInByb3h5IiwicHJveHlCeXBhc3MiLCJsb2ciLCJzaG93U3Bpbm5lciIsInRlc3RDYWZlIiwiaG9zdG5hbWUiLCJzc2wiLCJkZXYiLCJjb25jdXJyZW5jeSIsInJlbW90ZUJyb3dzZXJzIiwicmVtb3RlQ291bnQiLCJxckNvZGUiLCJicm93c2VycyIsImNvbmNhdCIsInJ1bm5lciIsImNyZWF0ZVJ1bm5lciIsImZhaWxlZCIsInJlcG9ydGVycyIsIm1hcCIsIm5hbWUiLCJyIiwib3V0U3RyZWFtIiwib3V0RmlsZSIsImZzIiwiY3JlYXRlV3JpdGVTdHJlYW0iLCJmb3JFYWNoIiwicmVwb3J0ZXIiLCJ1c2VQcm94eSIsInNyYyIsImZpbHRlciIsInNjcmVlbnNob3RzIiwic2NyZWVuc2hvdHNPbkZhaWxzIiwic2NyZWVuc2hvdFBhdGhQYXR0ZXJuIiwicmVjb3JkU2NyZWVuQ2FwdHVyZSIsInN0YXJ0QXBwIiwiYXBwIiwiYXBwSW5pdERlbGF5Iiwib25jZSIsImhpZGVTcGlubmVyIiwicnVuIiwic2hvd01lc3NhZ2VPbkV4aXQiLCJjbG9zZSIsImV4aXQiLCJydW5UZXN0cyIsInByb3ZpZGVyTmFtZSIsImJyb3dzZXJQcm92aWRlclBvb2wiLCJyZXF1aXJlIiwicHJvdmlkZXIiLCJnZXRQcm92aWRlciIsIkdlbmVyYWxFcnJvciIsIk1FU1NBR0UiLCJicm93c2VyUHJvdmlkZXJOb3RGb3VuZCIsImlzTXVsdGlCcm93c2VyIiwiYnJvd3Nlck5hbWVzIiwiZ2V0QnJvd3Nlckxpc3QiLCJkaXNwb3NlIiwiY29uc29sZSIsImpvaW4iLCJicm93c2VyTmFtZSIsImxpc3RCcm93c2VycyIsImV4aXRNZXNzYWdlU2hvd24iLCJleGl0aW5nIiwiZXhpdEhhbmRsZXIiLCJ0ZXJtaW5hdGlvbkxldmVsIiwid3JpdGUiLCJwcm9jZXNzIiwib24iLCJjb2RlIiwic2V0VGltZW91dCIsImVycm9yIiwiZXJyIiwibWVzc2FnZSIsImNvbnN0cnVjdG9yIiwiQVBJRXJyb3IiLCJjb2xvcmVkU3RhY2siLCJzdGFjayIsImNoYWxrIiwicmVkIiwiZ3JheSIsInRlcm1pbmF0aW9uSGFuZGxlciIsIlRlcm1pbmF0aW9uSGFuZGxlciIsIlRFUk1JTkFUSU9OX0xFVkVMX0lOQ1JFQVNFRF9FVkVOVCIsIkNsaUFyZ3VtZW50UGFyc2VyIiwicGFyc2UiLCJhcmd2IiwiY2xpIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OytDQWdFQSxXQUF5QkEsU0FBekIsRUFBb0M7QUFDaEMsY0FBTUMsT0FBb0JELFVBQVVDLElBQXBDO0FBQ0EsY0FBTUMsUUFBb0JELEtBQUtFLEtBQUwsSUFBY0YsS0FBS0UsS0FBTCxDQUFXLENBQVgsQ0FBeEM7QUFDQSxjQUFNQyxRQUFvQkgsS0FBS0UsS0FBTCxJQUFjRixLQUFLRSxLQUFMLENBQVcsQ0FBWCxDQUF4QztBQUNBLGNBQU1FLG9CQUFvQkosS0FBS0ssS0FBL0I7QUFDQSxjQUFNQyxjQUFvQk4sS0FBS00sV0FBL0I7O0FBRUFDLHNCQUFJQyxXQUFKOztBQUVBLGNBQU1DLFdBQWUsTUFBTSxnQkFBZVQsS0FBS1UsUUFBcEIsRUFBOEJULEtBQTlCLEVBQXFDRSxLQUFyQyxFQUE0Q0gsS0FBS1csR0FBakQsRUFBc0RYLEtBQUtZLEdBQTNELENBQTNCO0FBQ0EsY0FBTUMsY0FBaUJkLFVBQVVjLFdBQVYsSUFBeUIsQ0FBaEQ7QUFDQSxjQUFNQyxpQkFBaUIsTUFBTSw2QkFBY0wsUUFBZCxFQUF3QlYsVUFBVWdCLFdBQWxDLEVBQStDZixLQUFLZ0IsTUFBcEQsQ0FBN0I7QUFDQSxjQUFNQyxXQUFpQmxCLFVBQVVrQixRQUFWLENBQW1CQyxNQUFuQixDQUEwQkosY0FBMUIsQ0FBdkI7QUFDQSxjQUFNSyxTQUFpQlYsU0FBU1csWUFBVCxFQUF2QjtBQUNBLFlBQUlDLFNBQWlCLENBQXJCO0FBQ0EsY0FB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QUFFQSxnQkFBSTFGLFVBQVVDLElBQVYsQ0FBZWdFLFlBQW5CLEVBQ0ksTUFBTUEsYUFBYWpFLFVBQVVDLElBQVYsQ0FBZWlELFlBQTVCLENBQU4sQ0FESixLQUdJLE1BQU1ELFNBQVNqRCxTQUFULENBQU47QUFDUCxTQVRELENBVUEsT0FBTzRFLEdBQVAsRUFBWTtBQUNSOUIsZ0NBQW9CLEtBQXBCO0FBQ0E2QixrQkFBTUMsR0FBTjtBQUNIO0FBQ0osS0FuQkQ7O0FBQUEsYUFBZ0JlLEdBQWhCO0FBQUE7QUFBQTs7QUFBQSxXQUFnQkEsR0FBaEI7QUFBQSIsImZpbGUiOiJjbGkvY2xpLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBjaGFsayBmcm9tICdjaGFsayc7XG5pbXBvcnQgeyBHZW5lcmFsRXJyb3IsIEFQSUVycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3J1bnRpbWUnO1xuaW1wb3J0IE1FU1NBR0UgZnJvbSAnLi4vZXJyb3JzL3J1bnRpbWUvbWVzc2FnZSc7XG5pbXBvcnQgQ2xpQXJndW1lbnRQYXJzZXIgZnJvbSAnLi9hcmd1bWVudC1wYXJzZXInO1xuaW1wb3J0IFRlcm1pbmF0aW9uSGFuZGxlciBmcm9tICcuL3Rlcm1pbmF0aW9uLWhhbmRsZXInO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZyc7XG5pbXBvcnQgcmVtb3Rlc1dpemFyZCBmcm9tICcuL3JlbW90ZXMtd2l6YXJkJztcbmltcG9ydCBjcmVhdGVUZXN0Q2FmZSBmcm9tICcuLi8nO1xuXG5cbmxldCBzaG93TWVzc2FnZU9uRXhpdCA9IHRydWU7XG5sZXQgZXhpdE1lc3NhZ2VTaG93biAgPSBmYWxzZTtcbmxldCBleGl0aW5nICAgICAgICAgICA9IGZhbHNlO1xuXG5mdW5jdGlvbiBleGl0SGFuZGxlciAodGVybWluYXRpb25MZXZlbCkge1xuICAgIGlmIChzaG93TWVzc2FnZU9uRXhpdCAmJiAhZXhpdE1lc3NhZ2VTaG93bikge1xuICAgICAgICBleGl0TWVzc2FnZVNob3duID0gdHJ1ZTtcblxuICAgICAgICBsb2cuaGlkZVNwaW5uZXIoKTtcbiAgICAgICAgbG9nLndyaXRlKCdTdG9wcGluZyBUZXN0Q2FmZS4uLicpO1xuICAgICAgICBsb2cuc2hvd1NwaW5uZXIoKTtcblxuICAgICAgICBwcm9jZXNzLm9uKCdleGl0JywgKCkgPT4gbG9nLmhpZGVTcGlubmVyKHRydWUpKTtcbiAgICB9XG5cbiAgICBpZiAoZXhpdGluZyB8fCB0ZXJtaW5hdGlvbkxldmVsIDwgMilcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgZXhpdGluZyA9IHRydWU7XG5cbiAgICBleGl0KDApO1xufVxuXG5mdW5jdGlvbiBleGl0IChjb2RlKSB7XG4gICAgbG9nLmhpZGVTcGlubmVyKHRydWUpO1xuXG4gICAgLy8gTk9URTogZ2l2ZSBhIHByb2Nlc3MgdGltZSB0byBmbHVzaCB0aGUgb3V0cHV0LlxuICAgIC8vIEl0J3MgbmVjZXNzYXJ5IGluIHNvbWUgZW52aXJvbm1lbnRzLlxuICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvY2Vzcy5leGl0KGNvZGUpLCAwKTtcbn1cblxuZnVuY3Rpb24gZXJyb3IgKGVycikge1xuICAgIGxvZy5oaWRlU3Bpbm5lcigpO1xuXG4gICAgbGV0IG1lc3NhZ2UgPSBudWxsO1xuXG4gICAgLy8gSEFDSzogd29ya2Fyb3VuZCBmb3IgdGhlIGBpbnN0YW5jZW9mYCBwcm9ibGVtXG4gICAgLy8gKHNlZTogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zMzg3MDY4NC93aHktZG9lc250LWluc3RhbmNlb2Ytd29yay1vbi1pbnN0YW5jZXMtb2YtZXJyb3Itc3ViY2xhc3Nlcy11bmRlci1iYWJlbC1ub2RlKVxuICAgIGlmIChlcnIuY29uc3RydWN0b3IgPT09IEdlbmVyYWxFcnJvcilcbiAgICAgICAgbWVzc2FnZSA9IGVyci5tZXNzYWdlO1xuXG4gICAgZWxzZSBpZiAoZXJyLmNvbnN0cnVjdG9yID09PSBBUElFcnJvcilcbiAgICAgICAgbWVzc2FnZSA9IGVyci5jb2xvcmVkU3RhY2s7XG5cbiAgICBlbHNlXG4gICAgICAgIG1lc3NhZ2UgPSBlcnIuc3RhY2s7XG5cbiAgICBsb2cud3JpdGUoY2hhbGsucmVkKCdFUlJPUiAnKSArIG1lc3NhZ2UgKyAnXFxuJyk7XG4gICAgbG9nLndyaXRlKGNoYWxrLmdyYXkoJ1R5cGUgXCJ0ZXN0Y2FmZSAtaFwiIGZvciBoZWxwLicpKTtcblxuICAgIGV4aXQoMSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1blRlc3RzIChhcmdQYXJzZXIpIHtcbiAgICBjb25zdCBvcHRzICAgICAgICAgICAgICA9IGFyZ1BhcnNlci5vcHRzO1xuICAgIGNvbnN0IHBvcnQxICAgICAgICAgICAgID0gb3B0cy5wb3J0cyAmJiBvcHRzLnBvcnRzWzBdO1xuICAgIGNvbnN0IHBvcnQyICAgICAgICAgICAgID0gb3B0cy5wb3J0cyAmJiBvcHRzLnBvcnRzWzFdO1xuICAgIGNvbnN0IGV4dGVybmFsUHJveHlIb3N0ID0gb3B0cy5wcm94eTtcbiAgICBjb25zdCBwcm94eUJ5cGFzcyAgICAgICA9IG9wdHMucHJveHlCeXBhc3M7XG5cbiAgICBsb2cuc2hvd1NwaW5uZXIoKTtcblxuICAgIGNvbnN0IHRlc3RDYWZlICAgICA9IGF3YWl0IGNyZWF0ZVRlc3RDYWZlKG9wdHMuaG9zdG5hbWUsIHBvcnQxLCBwb3J0Miwgb3B0cy5zc2wsIG9wdHMuZGV2KTtcbiAgICBjb25zdCBjb25jdXJyZW5jeSAgICA9IGFyZ1BhcnNlci5jb25jdXJyZW5jeSB8fCAxO1xuICAgIGNvbnN0IHJlbW90ZUJyb3dzZXJzID0gYXdhaXQgcmVtb3Rlc1dpemFyZCh0ZXN0Q2FmZSwgYXJnUGFyc2VyLnJlbW90ZUNvdW50LCBvcHRzLnFyQ29kZSk7XG4gICAgY29uc3QgYnJvd3NlcnMgICAgICAgPSBhcmdQYXJzZXIuYnJvd3NlcnMuY29uY2F0KHJlbW90ZUJyb3dzZXJzKTtcbiAgICBjb25zdCBydW5uZXIgICAgICAgICA9IHRlc3RDYWZlLmNyZWF0ZVJ1bm5lcigpO1xuICAgIGxldCBmYWlsZWQgICAgICAgICA9IDA7XG4gICAgY29uc3QgcmVwb3J0ZXJzICAgICAgPSBhcmdQYXJzZXIub3B0cy5yZXBvcnRlcnMubWFwKHIgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZTogICAgICByLm5hbWUsXG4gICAgICAgICAgICBvdXRTdHJlYW06IHIub3V0RmlsZSA/IGZzLmNyZWF0ZVdyaXRlU3RyZWFtKHIub3V0RmlsZSkgOiB2b2lkIDBcbiAgICAgICAgfTtcbiAgICB9KTtcblxuICAgIHJlcG9ydGVycy5mb3JFYWNoKHIgPT4gcnVubmVyLnJlcG9ydGVyKHIubmFtZSwgci5vdXRTdHJlYW0pKTtcblxuICAgIHJ1bm5lclxuICAgICAgICAudXNlUHJveHkoZXh0ZXJuYWxQcm94eUhvc3QsIHByb3h5QnlwYXNzKVxuICAgICAgICAuc3JjKGFyZ1BhcnNlci5zcmMpXG4gICAgICAgIC5icm93c2Vycyhicm93c2VycylcbiAgICAgICAgLmNvbmN1cnJlbmN5KGNvbmN1cnJlbmN5KVxuICAgICAgICAuZmlsdGVyKGFyZ1BhcnNlci5maWx0ZXIpXG4gICAgICAgIC5zY3JlZW5zaG90cyhvcHRzLnNjcmVlbnNob3RzLCBvcHRzLnNjcmVlbnNob3RzT25GYWlscywgb3B0cy5zY3JlZW5zaG90UGF0aFBhdHRlcm4sIG9wdHMucmVjb3JkU2NyZWVuQ2FwdHVyZSlcbiAgICAgICAgLnN0YXJ0QXBwKG9wdHMuYXBwLCBvcHRzLmFwcEluaXREZWxheSk7XG5cbiAgICBydW5uZXIub25jZSgnZG9uZS1ib290c3RyYXBwaW5nJywgKCkgPT4gbG9nLmhpZGVTcGlubmVyKCkpO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgZmFpbGVkID0gYXdhaXQgcnVubmVyLnJ1bihvcHRzKTtcbiAgICB9XG5cbiAgICBmaW5hbGx5IHtcbiAgICAgICAgc2hvd01lc3NhZ2VPbkV4aXQgPSBmYWxzZTtcbiAgICAgICAgYXdhaXQgdGVzdENhZmUuY2xvc2UoKTtcbiAgICB9XG5cbiAgICBleGl0KGZhaWxlZCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGxpc3RCcm93c2VycyAocHJvdmlkZXJOYW1lID0gJ2xvY2FsbHktaW5zdGFsbGVkJykge1xuICAgIC8vIE5PVEU6IExvYWQgdGhlIHByb3ZpZGVyIHBvb2wgbGF6aWx5IHRvIHJlZHVjZSBzdGFydHVwIHRpbWVcbiAgICBjb25zdCBicm93c2VyUHJvdmlkZXJQb29sID0gcmVxdWlyZSgnLi4vYnJvd3Nlci9wcm92aWRlci9wb29sJyk7XG5cbiAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IGJyb3dzZXJQcm92aWRlclBvb2wuZ2V0UHJvdmlkZXIocHJvdmlkZXJOYW1lKTtcblxuICAgIGlmICghcHJvdmlkZXIpXG4gICAgICAgIHRocm93IG5ldyBHZW5lcmFsRXJyb3IoTUVTU0FHRS5icm93c2VyUHJvdmlkZXJOb3RGb3VuZCwgcHJvdmlkZXJOYW1lKTtcblxuICAgIGlmIChwcm92aWRlci5pc011bHRpQnJvd3Nlcikge1xuICAgICAgICBjb25zdCBicm93c2VyTmFtZXMgPSBhd2FpdCBwcm92aWRlci5nZXRCcm93c2VyTGlzdCgpO1xuXG4gICAgICAgIGF3YWl0IGJyb3dzZXJQcm92aWRlclBvb2wuZGlzcG9zZSgpO1xuXG4gICAgICAgIGlmIChwcm92aWRlck5hbWUgPT09ICdsb2NhbGx5LWluc3RhbGxlZCcpXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhicm93c2VyTmFtZXMuam9pbignXFxuJykpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhicm93c2VyTmFtZXMubWFwKGJyb3dzZXJOYW1lID0+IGBcIiR7cHJvdmlkZXJOYW1lfToke2Jyb3dzZXJOYW1lfVwiYCkuam9pbignXFxuJykpO1xuICAgIH1cbiAgICBlbHNlXG4gICAgICAgIGNvbnNvbGUubG9nKGBcIiR7cHJvdmlkZXJOYW1lfVwiYCk7XG5cbiAgICBleGl0KDApO1xufVxuXG4oYXN5bmMgZnVuY3Rpb24gY2xpICgpIHtcbiAgICBjb25zdCB0ZXJtaW5hdGlvbkhhbmRsZXIgPSBuZXcgVGVybWluYXRpb25IYW5kbGVyKCk7XG5cbiAgICB0ZXJtaW5hdGlvbkhhbmRsZXIub24oVGVybWluYXRpb25IYW5kbGVyLlRFUk1JTkFUSU9OX0xFVkVMX0lOQ1JFQVNFRF9FVkVOVCwgZXhpdEhhbmRsZXIpO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYXJnUGFyc2VyID0gbmV3IENsaUFyZ3VtZW50UGFyc2VyKCk7XG5cbiAgICAgICAgYXdhaXQgYXJnUGFyc2VyLnBhcnNlKHByb2Nlc3MuYXJndik7XG5cbiAgICAgICAgaWYgKGFyZ1BhcnNlci5vcHRzLmxpc3RCcm93c2VycylcbiAgICAgICAgICAgIGF3YWl0IGxpc3RCcm93c2VycyhhcmdQYXJzZXIub3B0cy5wcm92aWRlck5hbWUpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBhd2FpdCBydW5UZXN0cyhhcmdQYXJzZXIpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHNob3dNZXNzYWdlT25FeGl0ID0gZmFsc2U7XG4gICAgICAgIGVycm9yKGVycik7XG4gICAgfVxufSkoKTtcblxuIl19 diff --git a/lib/cli/index.js b/lib/cli/index.js new file mode 100644 index 00000000..e98da1ee --- /dev/null +++ b/lib/cli/index.js @@ -0,0 +1,29 @@ +'use strict'; + +var _resolveCwd = require('resolve-cwd'); + +var _resolveCwd2 = _interopRequireDefault(_resolveCwd); + +var _log = require('./log'); + +var _log2 = _interopRequireDefault(_log); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function getLocalInstallation() { + const local = (0, _resolveCwd2.default)('testcafe/lib/cli'); + + if (local && local !== __filename) { + _log2.default.write('Using locally installed version of TestCafe.'); + return local; + } + + return ''; +} + +(function loader() { + const cliPath = getLocalInstallation() || require.resolve('./cli'); + + require(cliPath); +})(); +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvaW5kZXguanMiXSwibmFtZXMiOlsiZ2V0TG9jYWxJbnN0YWxsYXRpb24iLCJsb2NhbCIsIl9fZmlsZW5hbWUiLCJsb2ciLCJ3cml0ZSIsImxvYWRlciIsImNsaVBhdGgiLCJyZXF1aXJlIiwicmVzb2x2ZSJdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7OztBQUNBOzs7Ozs7QUFHQSxTQUFTQSxvQkFBVCxHQUFpQztBQUM3QixVQUFNQyxRQUFRLDBCQUFXLGtCQUFYLENBQWQ7O0FBRUEsUUFBSUEsU0FBU0EsVUFBVUMsVUFBdkIsRUFBbUM7QUFDL0JDLHNCQUFJQyxLQUFKLENBQVUsOENBQVY7QUFDQSxlQUFPSCxLQUFQO0FBQ0g7O0FBRUQsV0FBTyxFQUFQO0FBQ0g7O0FBRUQsQ0FBQyxTQUFTSSxNQUFULEdBQW1CO0FBQ2hCLFVBQU1DLFVBQVVOLDBCQUEwQk8sUUFBUUMsT0FBUixDQUFnQixPQUFoQixDQUExQzs7QUFFQUQsWUFBUUQsT0FBUjtBQUNILENBSkQiLCJmaWxlIjoiY2xpL2luZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlc29sdmVDd2QgZnJvbSAncmVzb2x2ZS1jd2QnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZyc7XG5cblxuZnVuY3Rpb24gZ2V0TG9jYWxJbnN0YWxsYXRpb24gKCkge1xuICAgIGNvbnN0IGxvY2FsID0gcmVzb2x2ZUN3ZCgndGVzdGNhZmUvbGliL2NsaScpO1xuXG4gICAgaWYgKGxvY2FsICYmIGxvY2FsICE9PSBfX2ZpbGVuYW1lKSB7XG4gICAgICAgIGxvZy53cml0ZSgnVXNpbmcgbG9jYWxseSBpbnN0YWxsZWQgdmVyc2lvbiBvZiBUZXN0Q2FmZS4nKTtcbiAgICAgICAgcmV0dXJuIGxvY2FsO1xuICAgIH1cblxuICAgIHJldHVybiAnJztcbn1cblxuKGZ1bmN0aW9uIGxvYWRlciAoKSB7XG4gICAgY29uc3QgY2xpUGF0aCA9IGdldExvY2FsSW5zdGFsbGF0aW9uKCkgfHwgcmVxdWlyZS5yZXNvbHZlKCcuL2NsaScpO1xuXG4gICAgcmVxdWlyZShjbGlQYXRoKTtcbn0pKCk7XG4iXX0= diff --git a/lib/cli/log.js b/lib/cli/log.js new file mode 100644 index 00000000..e701225b --- /dev/null +++ b/lib/cli/log.js @@ -0,0 +1,63 @@ +'use strict'; + +exports.__esModule = true; + +var _tty = require('tty'); + +var _tty2 = _interopRequireDefault(_tty); + +var _elegantSpinner = require('elegant-spinner'); + +var _elegantSpinner2 = _interopRequireDefault(_elegantSpinner); + +var _logUpdateAsyncHook = require('log-update-async-hook'); + +var _logUpdateAsyncHook2 = _interopRequireDefault(_logUpdateAsyncHook); + +var _chalk = require('chalk'); + +var _chalk2 = _interopRequireDefault(_chalk); + +var _isCi = require('is-ci'); + +var _isCi2 = _interopRequireDefault(_isCi); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// NOTE: To support piping, we use stderr as the log output +// stream, while stdout is used for the report output. +exports.default = { + animation: null, + isAnimated: _tty2.default.isatty(1) && !_isCi2.default, + + showSpinner() { + // NOTE: we can use the spinner only if stderr is a TTY and we are not in CI environment (e.g. TravisCI), + // otherwise we can't repaint animation frames. Thanks https://github.com/sindresorhus/ora for insight. + if (this.isAnimated) { + const spinnerFrame = (0, _elegantSpinner2.default)(); + + this.animation = setInterval(() => { + const frame = _chalk2.default.cyan(spinnerFrame()); + + _logUpdateAsyncHook2.default.stderr(frame); + }, 50); + } + }, + + hideSpinner(isExit) { + if (this.animation) { + clearInterval(this.animation); + _logUpdateAsyncHook2.default.stderr.clear(); + + if (isExit) _logUpdateAsyncHook2.default.stderr.done(); + + this.animation = null; + } + }, + + write(text) { + console.error(text); + } +}; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvbG9nLmpzIl0sIm5hbWVzIjpbImFuaW1hdGlvbiIsImlzQW5pbWF0ZWQiLCJ0dHkiLCJpc2F0dHkiLCJpc0NJIiwic2hvd1NwaW5uZXIiLCJzcGlubmVyRnJhbWUiLCJzZXRJbnRlcnZhbCIsImZyYW1lIiwiY2hhbGsiLCJjeWFuIiwibG9nVXBkYXRlIiwic3RkZXJyIiwiaGlkZVNwaW5uZXIiLCJpc0V4aXQiLCJjbGVhckludGVydmFsIiwiY2xlYXIiLCJkb25lIiwid3JpdGUiLCJ0ZXh0IiwiY29uc29sZSIsImVycm9yIl0sIm1hcHBpbmdzIjoiOzs7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBRUE7QUFDQTtrQkFDZTtBQUNYQSxlQUFZLElBREQ7QUFFWEMsZ0JBQVlDLGNBQUlDLE1BQUosQ0FBVyxDQUFYLEtBQWlCLENBQUNDLGNBRm5COztBQUlYQyxrQkFBZTtBQUNYO0FBQ0E7QUFDQSxZQUFJLEtBQUtKLFVBQVQsRUFBcUI7QUFDakIsa0JBQU1LLGVBQWUsK0JBQXJCOztBQUVBLGlCQUFLTixTQUFMLEdBQWlCTyxZQUFZLE1BQU07QUFDL0Isc0JBQU1DLFFBQVFDLGdCQUFNQyxJQUFOLENBQVdKLGNBQVgsQ0FBZDs7QUFFQUssNkNBQVVDLE1BQVYsQ0FBaUJKLEtBQWpCO0FBQ0gsYUFKZ0IsRUFJZCxFQUpjLENBQWpCO0FBS0g7QUFDSixLQWhCVTs7QUFrQlhLLGdCQUFhQyxNQUFiLEVBQXFCO0FBQ2pCLFlBQUksS0FBS2QsU0FBVCxFQUFvQjtBQUNoQmUsMEJBQWMsS0FBS2YsU0FBbkI7QUFDQVcseUNBQVVDLE1BQVYsQ0FBaUJJLEtBQWpCOztBQUVBLGdCQUFJRixNQUFKLEVBQ0lILDZCQUFVQyxNQUFWLENBQWlCSyxJQUFqQjs7QUFFSixpQkFBS2pCLFNBQUwsR0FBaUIsSUFBakI7QUFDSDtBQUNKLEtBNUJVOztBQThCWGtCLFVBQU9DLElBQVAsRUFBYTtBQUNUQyxnQkFBUUMsS0FBUixDQUFjRixJQUFkO0FBQ0g7QUFoQ1UsQyIsImZpbGUiOiJjbGkvbG9nLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR0eSBmcm9tICd0dHknO1xuaW1wb3J0IGVsZWdhbnRTcGlubmVyIGZyb20gJ2VsZWdhbnQtc3Bpbm5lcic7XG5pbXBvcnQgbG9nVXBkYXRlIGZyb20gJ2xvZy11cGRhdGUtYXN5bmMtaG9vayc7XG5pbXBvcnQgY2hhbGsgZnJvbSAnY2hhbGsnO1xuaW1wb3J0IGlzQ0kgZnJvbSAnaXMtY2knO1xuXG4vLyBOT1RFOiBUbyBzdXBwb3J0IHBpcGluZywgd2UgdXNlIHN0ZGVyciBhcyB0aGUgbG9nIG91dHB1dFxuLy8gc3RyZWFtLCB3aGlsZSBzdGRvdXQgaXMgdXNlZCBmb3IgdGhlIHJlcG9ydCBvdXRwdXQuXG5leHBvcnQgZGVmYXVsdCB7XG4gICAgYW5pbWF0aW9uOiAgbnVsbCxcbiAgICBpc0FuaW1hdGVkOiB0dHkuaXNhdHR5KDEpICYmICFpc0NJLFxuXG4gICAgc2hvd1NwaW5uZXIgKCkge1xuICAgICAgICAvLyBOT1RFOiB3ZSBjYW4gdXNlIHRoZSBzcGlubmVyIG9ubHkgaWYgc3RkZXJyIGlzIGEgVFRZIGFuZCB3ZSBhcmUgbm90IGluIENJIGVudmlyb25tZW50IChlLmcuIFRyYXZpc0NJKSxcbiAgICAgICAgLy8gb3RoZXJ3aXNlIHdlIGNhbid0IHJlcGFpbnQgYW5pbWF0aW9uIGZyYW1lcy4gVGhhbmtzIGh0dHBzOi8vZ2l0aHViLmNvbS9zaW5kcmVzb3JodXMvb3JhIGZvciBpbnNpZ2h0LlxuICAgICAgICBpZiAodGhpcy5pc0FuaW1hdGVkKSB7XG4gICAgICAgICAgICBjb25zdCBzcGlubmVyRnJhbWUgPSBlbGVnYW50U3Bpbm5lcigpO1xuXG4gICAgICAgICAgICB0aGlzLmFuaW1hdGlvbiA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmcmFtZSA9IGNoYWxrLmN5YW4oc3Bpbm5lckZyYW1lKCkpO1xuXG4gICAgICAgICAgICAgICAgbG9nVXBkYXRlLnN0ZGVycihmcmFtZSk7XG4gICAgICAgICAgICB9LCA1MCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgaGlkZVNwaW5uZXIgKGlzRXhpdCkge1xuICAgICAgICBpZiAodGhpcy5hbmltYXRpb24pIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5hbmltYXRpb24pO1xuICAgICAgICAgICAgbG9nVXBkYXRlLnN0ZGVyci5jbGVhcigpO1xuXG4gICAgICAgICAgICBpZiAoaXNFeGl0KVxuICAgICAgICAgICAgICAgIGxvZ1VwZGF0ZS5zdGRlcnIuZG9uZSgpO1xuXG4gICAgICAgICAgICB0aGlzLmFuaW1hdGlvbiA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgd3JpdGUgKHRleHQpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcih0ZXh0KTtcbiAgICB9XG59O1xuXG4iXX0= diff --git a/lib/cli/parse-ssl-options.js b/lib/cli/parse-ssl-options.js new file mode 100644 index 00000000..264e6993 --- /dev/null +++ b/lib/cli/parse-ssl-options.js @@ -0,0 +1,59 @@ +'use strict'; + +exports.__esModule = true; + +exports.default = function (optionsStr = '') { + const splittedOptions = optionsStr.split(OPTIONS_SEPARATOR); + + if (!splittedOptions.length) return null; + + const parsedOptions = {}; + + splittedOptions.forEach(item => { + const keyValuePair = item.split(OPTION_KEY_VALUE_SEPARATOR); + const key = keyValuePair[0]; + let value = keyValuePair[1]; + + if (!key || !value) return; + + value = convertToBestFitType(value); + + if (FILE_OPTION_NAMES.includes(key) && value.length < OS_MAX_PATH_LENGTH && _fs2.default.existsSync(value)) value = _fs2.default.readFileSync(value); + + parsedOptions[key] = value; + }); + + return parsedOptions; +}; + +var _fs = require('fs'); + +var _fs2 = _interopRequireDefault(_fs); + +var _os = require('os'); + +var _os2 = _interopRequireDefault(_os); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const MAX_PATH_LENGTH = { + 'Linux': 4096, + 'Windows_NT': 260, + 'Darwin': 1024 +}; + +const OS_MAX_PATH_LENGTH = MAX_PATH_LENGTH[_os2.default.type()]; + +const OPTIONS_SEPARATOR = ';'; +const OPTION_KEY_VALUE_SEPARATOR = '='; +const FILE_OPTION_NAMES = ['cert', 'key', 'pfx']; +const NUMBER_REG_EX = /^[0-9-.,]+$/; +const BOOLEAN_STRING_VALUES = ['true', 'false']; + +function convertToBestFitType(valueStr) { + if (typeof valueStr !== 'string') return void 0;else if (NUMBER_REG_EX.test(valueStr)) return parseFloat(valueStr);else if (BOOLEAN_STRING_VALUES.includes(valueStr)) return valueStr === 'true';else if (!valueStr.length) return void 0; + + return valueStr; +} +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcGFyc2Utc3NsLW9wdGlvbnMuanMiXSwibmFtZXMiOlsib3B0aW9uc1N0ciIsInNwbGl0dGVkT3B0aW9ucyIsInNwbGl0IiwiT1BUSU9OU19TRVBBUkFUT1IiLCJsZW5ndGgiLCJwYXJzZWRPcHRpb25zIiwiZm9yRWFjaCIsIml0ZW0iLCJrZXlWYWx1ZVBhaXIiLCJPUFRJT05fS0VZX1ZBTFVFX1NFUEFSQVRPUiIsImtleSIsInZhbHVlIiwiY29udmVydFRvQmVzdEZpdFR5cGUiLCJGSUxFX09QVElPTl9OQU1FUyIsImluY2x1ZGVzIiwiT1NfTUFYX1BBVEhfTEVOR1RIIiwiZnMiLCJleGlzdHNTeW5jIiwicmVhZEZpbGVTeW5jIiwiTUFYX1BBVEhfTEVOR1RIIiwib3MiLCJ0eXBlIiwiTlVNQkVSX1JFR19FWCIsIkJPT0xFQU5fU1RSSU5HX1ZBTFVFUyIsInZhbHVlU3RyIiwidGVzdCIsInBhcnNlRmxvYXQiXSwibWFwcGluZ3MiOiI7Ozs7a0JBaUJlLFVBQVVBLGFBQWEsRUFBdkIsRUFBMkI7QUFDdEMsVUFBTUMsa0JBQWtCRCxXQUFXRSxLQUFYLENBQWlCQyxpQkFBakIsQ0FBeEI7O0FBRUEsUUFBSSxDQUFDRixnQkFBZ0JHLE1BQXJCLEVBQ0ksT0FBTyxJQUFQOztBQUVKLFVBQU1DLGdCQUFnQixFQUF0Qjs7QUFFQUosb0JBQWdCSyxPQUFoQixDQUF3QkMsUUFBUTtBQUM1QixjQUFNQyxlQUFlRCxLQUFLTCxLQUFMLENBQVdPLDBCQUFYLENBQXJCO0FBQ0EsY0FBTUMsTUFBZUYsYUFBYSxDQUFiLENBQXJCO0FBQ0EsWUFBSUcsUUFBaUJILGFBQWEsQ0FBYixDQUFyQjs7QUFFQSxZQUFJLENBQUNFLEdBQUQsSUFBUSxDQUFDQyxLQUFiLEVBQ0k7O0FBRUpBLGdCQUFRQyxxQkFBcUJELEtBQXJCLENBQVI7O0FBRUEsWUFBSUUsa0JBQWtCQyxRQUFsQixDQUEyQkosR0FBM0IsS0FBbUNDLE1BQU1QLE1BQU4sR0FBZVcsa0JBQWxELElBQXdFQyxhQUFHQyxVQUFILENBQWNOLEtBQWQsQ0FBNUUsRUFDSUEsUUFBUUssYUFBR0UsWUFBSCxDQUFnQlAsS0FBaEIsQ0FBUjs7QUFFSk4sc0JBQWNLLEdBQWQsSUFBcUJDLEtBQXJCO0FBQ0gsS0FkRDs7QUFnQkEsV0FBT04sYUFBUDtBQUNILEM7O0FBMUNEOzs7O0FBQ0E7Ozs7OztBQUVBLE1BQU1jLGtCQUFrQjtBQUNwQixhQUFjLElBRE07QUFFcEIsa0JBQWMsR0FGTTtBQUdwQixjQUFjO0FBSE0sQ0FBeEI7O0FBTUEsTUFBTUoscUJBQXFCSSxnQkFBZ0JDLGFBQUdDLElBQUgsRUFBaEIsQ0FBM0I7O0FBRUEsTUFBTWxCLG9CQUE2QixHQUFuQztBQUNBLE1BQU1NLDZCQUE2QixHQUFuQztBQUNBLE1BQU1JLG9CQUE2QixDQUFDLE1BQUQsRUFBUyxLQUFULEVBQWdCLEtBQWhCLENBQW5DO0FBQ0EsTUFBTVMsZ0JBQTZCLGFBQW5DO0FBQ0EsTUFBTUMsd0JBQTZCLENBQUMsTUFBRCxFQUFTLE9BQVQsQ0FBbkM7O0FBNkJBLFNBQVNYLG9CQUFULENBQStCWSxRQUEvQixFQUF5QztBQUNyQyxRQUFJLE9BQU9BLFFBQVAsS0FBb0IsUUFBeEIsRUFDSSxPQUFPLEtBQUssQ0FBWixDQURKLEtBR0ssSUFBSUYsY0FBY0csSUFBZCxDQUFtQkQsUUFBbkIsQ0FBSixFQUNELE9BQU9FLFdBQVdGLFFBQVgsQ0FBUCxDQURDLEtBR0EsSUFBSUQsc0JBQXNCVCxRQUF0QixDQUErQlUsUUFBL0IsQ0FBSixFQUNELE9BQU9BLGFBQWEsTUFBcEIsQ0FEQyxLQUdBLElBQUksQ0FBQ0EsU0FBU3BCLE1BQWQsRUFDRCxPQUFPLEtBQUssQ0FBWjs7QUFFSixXQUFPb0IsUUFBUDtBQUNIIiwiZmlsZSI6ImNsaS9wYXJzZS1zc2wtb3B0aW9ucy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgb3MgZnJvbSAnb3MnO1xuXG5jb25zdCBNQVhfUEFUSF9MRU5HVEggPSB7XG4gICAgJ0xpbnV4JzogICAgICA0MDk2LFxuICAgICdXaW5kb3dzX05UJzogMjYwLFxuICAgICdEYXJ3aW4nOiAgICAgMTAyNFxufTtcblxuY29uc3QgT1NfTUFYX1BBVEhfTEVOR1RIID0gTUFYX1BBVEhfTEVOR1RIW29zLnR5cGUoKV07XG5cbmNvbnN0IE9QVElPTlNfU0VQQVJBVE9SICAgICAgICAgID0gJzsnO1xuY29uc3QgT1BUSU9OX0tFWV9WQUxVRV9TRVBBUkFUT1IgPSAnPSc7XG5jb25zdCBGSUxFX09QVElPTl9OQU1FUyAgICAgICAgICA9IFsnY2VydCcsICdrZXknLCAncGZ4J107XG5jb25zdCBOVU1CRVJfUkVHX0VYICAgICAgICAgICAgICA9IC9eWzAtOS0uLF0rJC87XG5jb25zdCBCT09MRUFOX1NUUklOR19WQUxVRVMgICAgICA9IFsndHJ1ZScsICdmYWxzZSddO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAob3B0aW9uc1N0ciA9ICcnKSB7XG4gICAgY29uc3Qgc3BsaXR0ZWRPcHRpb25zID0gb3B0aW9uc1N0ci5zcGxpdChPUFRJT05TX1NFUEFSQVRPUik7XG5cbiAgICBpZiAoIXNwbGl0dGVkT3B0aW9ucy5sZW5ndGgpXG4gICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgcGFyc2VkT3B0aW9ucyA9IHt9O1xuXG4gICAgc3BsaXR0ZWRPcHRpb25zLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgIGNvbnN0IGtleVZhbHVlUGFpciA9IGl0ZW0uc3BsaXQoT1BUSU9OX0tFWV9WQUxVRV9TRVBBUkFUT1IpO1xuICAgICAgICBjb25zdCBrZXkgICAgICAgICAgPSBrZXlWYWx1ZVBhaXJbMF07XG4gICAgICAgIGxldCB2YWx1ZSAgICAgICAgICA9IGtleVZhbHVlUGFpclsxXTtcblxuICAgICAgICBpZiAoIWtleSB8fCAhdmFsdWUpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdmFsdWUgPSBjb252ZXJ0VG9CZXN0Rml0VHlwZSh2YWx1ZSk7XG5cbiAgICAgICAgaWYgKEZJTEVfT1BUSU9OX05BTUVTLmluY2x1ZGVzKGtleSkgJiYgdmFsdWUubGVuZ3RoIDwgT1NfTUFYX1BBVEhfTEVOR1RIICYmIGZzLmV4aXN0c1N5bmModmFsdWUpKVxuICAgICAgICAgICAgdmFsdWUgPSBmcy5yZWFkRmlsZVN5bmModmFsdWUpO1xuXG4gICAgICAgIHBhcnNlZE9wdGlvbnNba2V5XSA9IHZhbHVlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHBhcnNlZE9wdGlvbnM7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUb0Jlc3RGaXRUeXBlICh2YWx1ZVN0cikge1xuICAgIGlmICh0eXBlb2YgdmFsdWVTdHIgIT09ICdzdHJpbmcnKVxuICAgICAgICByZXR1cm4gdm9pZCAwO1xuXG4gICAgZWxzZSBpZiAoTlVNQkVSX1JFR19FWC50ZXN0KHZhbHVlU3RyKSlcbiAgICAgICAgcmV0dXJuIHBhcnNlRmxvYXQodmFsdWVTdHIpO1xuXG4gICAgZWxzZSBpZiAoQk9PTEVBTl9TVFJJTkdfVkFMVUVTLmluY2x1ZGVzKHZhbHVlU3RyKSlcbiAgICAgICAgcmV0dXJuIHZhbHVlU3RyID09PSAndHJ1ZSc7XG5cbiAgICBlbHNlIGlmICghdmFsdWVTdHIubGVuZ3RoKVxuICAgICAgICByZXR1cm4gdm9pZCAwO1xuXG4gICAgcmV0dXJuIHZhbHVlU3RyO1xufVxuXG4iXX0= diff --git a/lib/cli/remotes-wizard.js b/lib/cli/remotes-wizard.js new file mode 100644 index 00000000..b0406ac9 --- /dev/null +++ b/lib/cli/remotes-wizard.js @@ -0,0 +1,82 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _pinkie = require('pinkie'); + +var _pinkie2 = _interopRequireDefault(_pinkie); + +var _qrcodeTerminal = require('qrcode-terminal'); + +var _qrcodeTerminal2 = _interopRequireDefault(_qrcodeTerminal); + +var _chalk = require('chalk'); + +var _chalk2 = _interopRequireDefault(_chalk); + +var _log = require('./log'); + +var _log2 = _interopRequireDefault(_log); + +var _promisifyEvent = require('promisify-event'); + +var _promisifyEvent2 = _interopRequireDefault(_promisifyEvent); + +var _dedent = require('dedent'); + +var _dedent2 = _interopRequireDefault(_dedent); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.default = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (testCafe, remoteCount, showQRCode) { + const connectionPromises = []; + + if (remoteCount) { + _log2.default.hideSpinner(); + + const description = (0, _dedent2.default)(` + Connecting ${remoteCount} remote browser(s)... + Navigate to the following URL from each remote browser. + `); + + _log2.default.write(description); + + if (showQRCode) _log2.default.write('You can either enter the URL or scan the QR-code.'); + + const connectionUrl = testCafe.browserConnectionGateway.connectUrl; + + _log2.default.write(`Connect URL: ${_chalk2.default.underline.blue(connectionUrl)}`); + + if (showQRCode) _qrcodeTerminal2.default.generate(connectionUrl); + + for (let i = 0; i < remoteCount; i++) { + connectionPromises.push(testCafe.createBrowserConnection().then(function (bc) { + return (0, _promisifyEvent2.default)(bc, 'ready').then(function () { + return bc; + }); + }).then(function (bc) { + _log2.default.hideSpinner(); + _log2.default.write(`${_chalk2.default.green('CONNECTED')} ${bc.userAgent}`); + _log2.default.showSpinner(); + return bc; + })); + } + + _log2.default.showSpinner(); + } + + return yield _pinkie2.default.all(connectionPromises); + }); + + return function (_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +})(); + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcmVtb3Rlcy13aXphcmQuanMiXSwibmFtZXMiOlsidGVzdENhZmUiLCJyZW1vdGVDb3VudCIsInNob3dRUkNvZGUiLCJjb25uZWN0aW9uUHJvbWlzZXMiLCJsb2ciLCJoaWRlU3Bpbm5lciIsImRlc2NyaXB0aW9uIiwid3JpdGUiLCJjb25uZWN0aW9uVXJsIiwiYnJvd3NlckNvbm5lY3Rpb25HYXRld2F5IiwiY29ubmVjdFVybCIsImNoYWxrIiwidW5kZXJsaW5lIiwiYmx1ZSIsInFyY29kZSIsImdlbmVyYXRlIiwiaSIsInB1c2giLCJjcmVhdGVCcm93c2VyQ29ubmVjdGlvbiIsInRoZW4iLCJiYyIsImdyZWVuIiwidXNlckFnZW50Iiwic2hvd1NwaW5uZXIiLCJQcm9taXNlIiwiYWxsIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7OzsrQ0FHZSxXQUFnQkEsUUFBaEIsRUFBMEJDLFdBQTFCLEVBQXVDQyxVQUF2QyxFQUFtRDtBQUM5RCxjQUFNQyxxQkFBcUIsRUFBM0I7O0FBRUEsWUFBSUYsV0FBSixFQUFpQjtBQUNiRywwQkFBSUMsV0FBSjs7QUFFQSxrQkFBTUMsY0FBYyxzQkFBUTt5QkFDWEwsV0FBWTs7U0FEVCxDQUFwQjs7QUFLQUcsMEJBQUlHLEtBQUosQ0FBVUQsV0FBVjs7QUFFQSxnQkFBSUosVUFBSixFQUNJRSxjQUFJRyxLQUFKLENBQVUsbURBQVY7O0FBRUosa0JBQU1DLGdCQUFnQlIsU0FBU1Msd0JBQVQsQ0FBa0NDLFVBQXhEOztBQUVBTiwwQkFBSUcsS0FBSixDQUFXLGdCQUFlSSxnQkFBTUMsU0FBTixDQUFnQkMsSUFBaEIsQ0FBcUJMLGFBQXJCLENBQW9DLEVBQTlEOztBQUVBLGdCQUFJTixVQUFKLEVBQ0lZLHlCQUFPQyxRQUFQLENBQWdCUCxhQUFoQjs7QUFFSixpQkFBSyxJQUFJUSxJQUFJLENBQWIsRUFBZ0JBLElBQUlmLFdBQXBCLEVBQWlDZSxHQUFqQyxFQUFzQztBQUNsQ2IsbUNBQW1CYyxJQUFuQixDQUF3QmpCLFNBQ25Ca0IsdUJBRG1CLEdBRW5CQyxJQUZtQixDQUVkO0FBQUEsMkJBQU0sOEJBQWVDLEVBQWYsRUFBbUIsT0FBbkIsRUFBNEJELElBQTVCLENBQWlDO0FBQUEsK0JBQU1DLEVBQU47QUFBQSxxQkFBakMsQ0FBTjtBQUFBLGlCQUZjLEVBR25CRCxJQUhtQixDQUdkLGNBQU07QUFDUmYsa0NBQUlDLFdBQUo7QUFDQUQsa0NBQUlHLEtBQUosQ0FBVyxHQUFFSSxnQkFBTVUsS0FBTixDQUFZLFdBQVosQ0FBeUIsSUFBR0QsR0FBR0UsU0FBVSxFQUF0RDtBQUNBbEIsa0NBQUltQixXQUFKO0FBQ0EsMkJBQU9ILEVBQVA7QUFDSCxpQkFSbUIsQ0FBeEI7QUFVSDs7QUFFRGhCLDBCQUFJbUIsV0FBSjtBQUNIOztBQUVELGVBQU8sTUFBTUMsaUJBQVFDLEdBQVIsQ0FBWXRCLGtCQUFaLENBQWI7QUFDSCxLIiwiZmlsZSI6ImNsaS9yZW1vdGVzLXdpemFyZC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlIGZyb20gJ3BpbmtpZSc7XG5pbXBvcnQgcXJjb2RlIGZyb20gJ3FyY29kZS10ZXJtaW5hbCc7XG5pbXBvcnQgY2hhbGsgZnJvbSAnY2hhbGsnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZyc7XG5pbXBvcnQgcHJvbWlzaWZ5RXZlbnQgZnJvbSAncHJvbWlzaWZ5LWV2ZW50JztcbmltcG9ydCBkZWRlbnQgZnJvbSAnZGVkZW50JztcblxuXG5leHBvcnQgZGVmYXVsdCBhc3luYyBmdW5jdGlvbiAodGVzdENhZmUsIHJlbW90ZUNvdW50LCBzaG93UVJDb2RlKSB7XG4gICAgY29uc3QgY29ubmVjdGlvblByb21pc2VzID0gW107XG5cbiAgICBpZiAocmVtb3RlQ291bnQpIHtcbiAgICAgICAgbG9nLmhpZGVTcGlubmVyKCk7XG5cbiAgICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSBkZWRlbnQoYFxuICAgICAgICAgICAgQ29ubmVjdGluZyAke3JlbW90ZUNvdW50fSByZW1vdGUgYnJvd3NlcihzKS4uLlxuICAgICAgICAgICAgTmF2aWdhdGUgdG8gdGhlIGZvbGxvd2luZyBVUkwgZnJvbSBlYWNoIHJlbW90ZSBicm93c2VyLlxuICAgICAgICBgKTtcblxuICAgICAgICBsb2cud3JpdGUoZGVzY3JpcHRpb24pO1xuXG4gICAgICAgIGlmIChzaG93UVJDb2RlKVxuICAgICAgICAgICAgbG9nLndyaXRlKCdZb3UgY2FuIGVpdGhlciBlbnRlciB0aGUgVVJMIG9yIHNjYW4gdGhlIFFSLWNvZGUuJyk7XG5cbiAgICAgICAgY29uc3QgY29ubmVjdGlvblVybCA9IHRlc3RDYWZlLmJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5jb25uZWN0VXJsO1xuXG4gICAgICAgIGxvZy53cml0ZShgQ29ubmVjdCBVUkw6ICR7Y2hhbGsudW5kZXJsaW5lLmJsdWUoY29ubmVjdGlvblVybCl9YCk7XG5cbiAgICAgICAgaWYgKHNob3dRUkNvZGUpXG4gICAgICAgICAgICBxcmNvZGUuZ2VuZXJhdGUoY29ubmVjdGlvblVybCk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZW1vdGVDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICBjb25uZWN0aW9uUHJvbWlzZXMucHVzaCh0ZXN0Q2FmZVxuICAgICAgICAgICAgICAgIC5jcmVhdGVCcm93c2VyQ29ubmVjdGlvbigpXG4gICAgICAgICAgICAgICAgLnRoZW4oYmMgPT4gcHJvbWlzaWZ5RXZlbnQoYmMsICdyZWFkeScpLnRoZW4oKCkgPT4gYmMpKVxuICAgICAgICAgICAgICAgIC50aGVuKGJjID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nLmhpZGVTcGlubmVyKCk7XG4gICAgICAgICAgICAgICAgICAgIGxvZy53cml0ZShgJHtjaGFsay5ncmVlbignQ09OTkVDVEVEJyl9ICR7YmMudXNlckFnZW50fWApO1xuICAgICAgICAgICAgICAgICAgICBsb2cuc2hvd1NwaW5uZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJjO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgbG9nLnNob3dTcGlubmVyKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKGNvbm5lY3Rpb25Qcm9taXNlcyk7XG59XG4iXX0= diff --git a/lib/cli/termination-handler.js b/lib/cli/termination-handler.js new file mode 100644 index 00000000..3c300764 --- /dev/null +++ b/lib/cli/termination-handler.js @@ -0,0 +1,55 @@ +'use strict'; + +exports.__esModule = true; + +var _events = require('events'); + +var _events2 = _interopRequireDefault(_events); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const TERMINATION_TYPES = { + sigint: 'sigint', + sigbreak: 'sigbreak', + shutdown: 'shutdown' +}; + +const TERMINATION_LEVEL_INCREASED_EVENT = 'termination-level-increased'; + +class TerminationHandler extends _events2.default { + constructor() { + super(); + + this.handledSignalsCount = { + [TERMINATION_TYPES.sigint]: 0, + [TERMINATION_TYPES.sigbreak]: 0, + [TERMINATION_TYPES.shutdown]: 0 + }; + + this.terminationLevel = 0; + + this._setupHandlers(); + } + + _exitEventHandler(terminationType) { + this.handledSignalsCount[terminationType]++; + + if (this.handledSignalsCount[terminationType] > this.terminationLevel) { + this.terminationLevel = this.handledSignalsCount[terminationType]; + + this.emit(TERMINATION_LEVEL_INCREASED_EVENT, this.terminationLevel); + } + } + + _setupHandlers() { + process.on('SIGINT', () => this._exitEventHandler(TERMINATION_TYPES.sigint)); + process.on('SIGBREAK', () => this._exitEventHandler(TERMINATION_TYPES.sigbreak)); + + process.on('message', message => message === 'shutdown' && this._exitEventHandler(TERMINATION_TYPES.shutdown)); + } +} + +exports.default = TerminationHandler; +TerminationHandler.TERMINATION_LEVEL_INCREASED_EVENT = TERMINATION_LEVEL_INCREASED_EVENT; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvdGVybWluYXRpb24taGFuZGxlci5qcyJdLCJuYW1lcyI6WyJURVJNSU5BVElPTl9UWVBFUyIsInNpZ2ludCIsInNpZ2JyZWFrIiwic2h1dGRvd24iLCJURVJNSU5BVElPTl9MRVZFTF9JTkNSRUFTRURfRVZFTlQiLCJUZXJtaW5hdGlvbkhhbmRsZXIiLCJFdmVudEVtaXR0ZXIiLCJjb25zdHJ1Y3RvciIsImhhbmRsZWRTaWduYWxzQ291bnQiLCJ0ZXJtaW5hdGlvbkxldmVsIiwiX3NldHVwSGFuZGxlcnMiLCJfZXhpdEV2ZW50SGFuZGxlciIsInRlcm1pbmF0aW9uVHlwZSIsImVtaXQiLCJwcm9jZXNzIiwib24iLCJtZXNzYWdlIl0sIm1hcHBpbmdzIjoiOzs7O0FBQUE7Ozs7OztBQUdBLE1BQU1BLG9CQUFvQjtBQUN0QkMsWUFBVSxRQURZO0FBRXRCQyxjQUFVLFVBRlk7QUFHdEJDLGNBQVU7QUFIWSxDQUExQjs7QUFNQSxNQUFNQyxvQ0FBb0MsNkJBQTFDOztBQUVlLE1BQU1DLGtCQUFOLFNBQWlDQyxnQkFBakMsQ0FBOEM7QUFDekRDLGtCQUFlO0FBQ1g7O0FBRUEsYUFBS0MsbUJBQUwsR0FBMkI7QUFDdkIsYUFBQ1Isa0JBQWtCQyxNQUFuQixHQUE4QixDQURQO0FBRXZCLGFBQUNELGtCQUFrQkUsUUFBbkIsR0FBOEIsQ0FGUDtBQUd2QixhQUFDRixrQkFBa0JHLFFBQW5CLEdBQThCO0FBSFAsU0FBM0I7O0FBTUEsYUFBS00sZ0JBQUwsR0FBd0IsQ0FBeEI7O0FBRUEsYUFBS0MsY0FBTDtBQUNIOztBQUVEQyxzQkFBbUJDLGVBQW5CLEVBQW9DO0FBQ2hDLGFBQUtKLG1CQUFMLENBQXlCSSxlQUF6Qjs7QUFFQSxZQUFJLEtBQUtKLG1CQUFMLENBQXlCSSxlQUF6QixJQUE0QyxLQUFLSCxnQkFBckQsRUFBdUU7QUFDbkUsaUJBQUtBLGdCQUFMLEdBQXdCLEtBQUtELG1CQUFMLENBQXlCSSxlQUF6QixDQUF4Qjs7QUFFQSxpQkFBS0MsSUFBTCxDQUFVVCxpQ0FBVixFQUE2QyxLQUFLSyxnQkFBbEQ7QUFDSDtBQUNKOztBQUVEQyxxQkFBa0I7QUFDZEksZ0JBQVFDLEVBQVIsQ0FBVyxRQUFYLEVBQXFCLE1BQU0sS0FBS0osaUJBQUwsQ0FBdUJYLGtCQUFrQkMsTUFBekMsQ0FBM0I7QUFDQWEsZ0JBQVFDLEVBQVIsQ0FBVyxVQUFYLEVBQXVCLE1BQU0sS0FBS0osaUJBQUwsQ0FBdUJYLGtCQUFrQkUsUUFBekMsQ0FBN0I7O0FBRUFZLGdCQUFRQyxFQUFSLENBQVcsU0FBWCxFQUFzQkMsV0FBV0EsWUFBWSxVQUFaLElBQTBCLEtBQUtMLGlCQUFMLENBQXVCWCxrQkFBa0JHLFFBQXpDLENBQTNEO0FBQ0g7QUE5QndEOztrQkFBeENFLGtCO0FBaUNyQkEsbUJBQW1CRCxpQ0FBbkIsR0FBdURBLGlDQUF2RCIsImZpbGUiOiJjbGkvdGVybWluYXRpb24taGFuZGxlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBFdmVudEVtaXR0ZXIgZnJvbSAnZXZlbnRzJztcblxuXG5jb25zdCBURVJNSU5BVElPTl9UWVBFUyA9IHtcbiAgICBzaWdpbnQ6ICAgJ3NpZ2ludCcsXG4gICAgc2lnYnJlYWs6ICdzaWdicmVhaycsXG4gICAgc2h1dGRvd246ICdzaHV0ZG93bidcbn07XG5cbmNvbnN0IFRFUk1JTkFUSU9OX0xFVkVMX0lOQ1JFQVNFRF9FVkVOVCA9ICd0ZXJtaW5hdGlvbi1sZXZlbC1pbmNyZWFzZWQnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXJtaW5hdGlvbkhhbmRsZXIgZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzLmhhbmRsZWRTaWduYWxzQ291bnQgPSB7XG4gICAgICAgICAgICBbVEVSTUlOQVRJT05fVFlQRVMuc2lnaW50XTogICAwLFxuICAgICAgICAgICAgW1RFUk1JTkFUSU9OX1RZUEVTLnNpZ2JyZWFrXTogMCxcbiAgICAgICAgICAgIFtURVJNSU5BVElPTl9UWVBFUy5zaHV0ZG93bl06IDBcbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnRlcm1pbmF0aW9uTGV2ZWwgPSAwO1xuXG4gICAgICAgIHRoaXMuX3NldHVwSGFuZGxlcnMoKTtcbiAgICB9XG5cbiAgICBfZXhpdEV2ZW50SGFuZGxlciAodGVybWluYXRpb25UeXBlKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlZFNpZ25hbHNDb3VudFt0ZXJtaW5hdGlvblR5cGVdKys7XG5cbiAgICAgICAgaWYgKHRoaXMuaGFuZGxlZFNpZ25hbHNDb3VudFt0ZXJtaW5hdGlvblR5cGVdID4gdGhpcy50ZXJtaW5hdGlvbkxldmVsKSB7XG4gICAgICAgICAgICB0aGlzLnRlcm1pbmF0aW9uTGV2ZWwgPSB0aGlzLmhhbmRsZWRTaWduYWxzQ291bnRbdGVybWluYXRpb25UeXBlXTtcblxuICAgICAgICAgICAgdGhpcy5lbWl0KFRFUk1JTkFUSU9OX0xFVkVMX0lOQ1JFQVNFRF9FVkVOVCwgdGhpcy50ZXJtaW5hdGlvbkxldmVsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9zZXR1cEhhbmRsZXJzICgpIHtcbiAgICAgICAgcHJvY2Vzcy5vbignU0lHSU5UJywgKCkgPT4gdGhpcy5fZXhpdEV2ZW50SGFuZGxlcihURVJNSU5BVElPTl9UWVBFUy5zaWdpbnQpKTtcbiAgICAgICAgcHJvY2Vzcy5vbignU0lHQlJFQUsnLCAoKSA9PiB0aGlzLl9leGl0RXZlbnRIYW5kbGVyKFRFUk1JTkFUSU9OX1RZUEVTLnNpZ2JyZWFrKSk7XG5cbiAgICAgICAgcHJvY2Vzcy5vbignbWVzc2FnZScsIG1lc3NhZ2UgPT4gbWVzc2FnZSA9PT0gJ3NodXRkb3duJyAmJiB0aGlzLl9leGl0RXZlbnRIYW5kbGVyKFRFUk1JTkFUSU9OX1RZUEVTLnNodXRkb3duKSk7XG4gICAgfVxufVxuXG5UZXJtaW5hdGlvbkhhbmRsZXIuVEVSTUlOQVRJT05fTEVWRUxfSU5DUkVBU0VEX0VWRU5UID0gVEVSTUlOQVRJT05fTEVWRUxfSU5DUkVBU0VEX0VWRU5UO1xuIl19 diff --git a/lib/client-functions/builder-symbol.js b/lib/client-functions/builder-symbol.js new file mode 100644 index 00000000..d7defec4 --- /dev/null +++ b/lib/client-functions/builder-symbol.js @@ -0,0 +1,14 @@ +'use strict'; + +exports.__esModule = true; + +var _symbol = require('babel-runtime/core-js/symbol'); + +var _symbol2 = _interopRequireDefault(_symbol); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/*global Symbol*/ +exports.default = (0, _symbol2.default)('functionBuilder'); +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQtZnVuY3Rpb25zL2J1aWxkZXItc3ltYm9sLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTtrQkFDZSxzQkFBTyxpQkFBUCxDIiwiZmlsZSI6ImNsaWVudC1mdW5jdGlvbnMvYnVpbGRlci1zeW1ib2wuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKmdsb2JhbCBTeW1ib2wqL1xuZXhwb3J0IGRlZmF1bHQgU3ltYm9sKCdmdW5jdGlvbkJ1aWxkZXInKTtcbiJdfQ== diff --git a/lib/client-functions/client-function-builder.js b/lib/client-functions/client-function-builder.js new file mode 100644 index 00000000..44542e97 --- /dev/null +++ b/lib/client-functions/client-function-builder.js @@ -0,0 +1,192 @@ +'use strict'; + +exports.__esModule = true; + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +var _lodash = require('lodash'); + +var _testRunTracker = require('../api/test-run-tracker'); + +var _testRunTracker2 = _interopRequireDefault(_testRunTracker); + +var _builderSymbol = require('./builder-symbol'); + +var _builderSymbol2 = _interopRequireDefault(_builderSymbol); + +var _replicator = require('./replicator'); + +var _observation = require('../test-run/commands/observation'); + +var _compileClientFunction = require('../compiler/compile-client-function'); + +var _compileClientFunction2 = _interopRequireDefault(_compileClientFunction); + +var _runtime = require('../errors/runtime'); + +var _typeAssertions = require('../errors/runtime/type-assertions'); + +var _message = require('../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +var _getCallsite = require('../errors/get-callsite'); + +var _reExecutablePromise = require('../utils/re-executable-promise'); + +var _reExecutablePromise2 = _interopRequireDefault(_reExecutablePromise); + +var _markerSymbol = require('../test-run/marker-symbol'); + +var _markerSymbol2 = _interopRequireDefault(_markerSymbol); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DEFAULT_EXECUTION_CALLSITE_NAME = '__$$clientFunction$$'; + +class ClientFunctionBuilder { + constructor(fn, options, callsiteNames = {}) { + this.callsiteNames = { + instantiation: callsiteNames.instantiation, + execution: callsiteNames.execution || DEFAULT_EXECUTION_CALLSITE_NAME + }; + + if ((0, _lodash.isNil)(options)) options = {}; + + this._validateOptions(options); + + this.fn = fn; + this.options = options; + this.compiledFnCode = this._getCompiledFnCode(); + + if (!this.compiledFnCode) throw this._createInvalidFnTypeError(); + + this.replicator = (0, _replicator.createReplicator)(this._getReplicatorTransforms()); + } + + _decorateFunction(clientFn) { + clientFn[_builderSymbol2.default] = this; + + clientFn.with = options => { + if (typeof options === 'object') options = (0, _lodash.assign)({}, this.options, options); + + const builder = new this.constructor(this.fn, options, { + instantiation: 'with', + execution: this.callsiteNames.execution + }); + + return builder.getFunction(); + }; + } + + getBoundTestRun() { + // NOTE: `boundTestRun` can be either TestController or TestRun instance. + if (this.options.boundTestRun) return this.options.boundTestRun.testRun || this.options.boundTestRun; + + return null; + } + + _getTestRun() { + return this.getBoundTestRun() || _testRunTracker2.default.resolveContextTestRun(); + } + + getFunction() { + const builder = this; + + const clientFn = function __$$clientFunction$$() { + const testRun = builder._getTestRun(); + const callsite = (0, _getCallsite.getCallsiteForMethod)(builder.callsiteNames.execution); + const args = []; + + // OPTIMIZATION: don't leak `arguments` object. + for (let i = 0; i < arguments.length; i++) args.push(arguments[i]); + + return builder._executeCommand(args, testRun, callsite); + }; + + this._decorateFunction(clientFn); + + return clientFn; + } + + getCommand(args) { + const encodedArgs = this.replicator.encode(args); + const encodedDependencies = this.replicator.encode(this.getFunctionDependencies()); + + return this._createTestRunCommand(encodedArgs, encodedDependencies); + } + + // Overridable methods + getFunctionDependencies() { + return this.options.dependencies || {}; + } + + _createTestRunCommand(encodedArgs, encodedDependencies) { + return new _observation.ExecuteClientFunctionCommand({ + instantiationCallsiteName: this.callsiteNames.instantiation, + fnCode: this.compiledFnCode, + args: encodedArgs, + dependencies: encodedDependencies + }, this._getTestRun()); + } + + _getCompiledFnCode() { + if (typeof this.fn === 'function') return (0, _compileClientFunction2.default)(this.fn.toString(), this.options.dependencies, this.callsiteNames.instantiation, this.callsiteNames.instantiation); + + return null; + } + + _createInvalidFnTypeError() { + return new _runtime.ClientFunctionAPIError(this.callsiteNames.instantiation, this.callsiteNames.instantiation, _message2.default.clientFunctionCodeIsNotAFunction, typeof this.fn); + } + + _executeCommand(args, testRun, callsite) { + var _this = this; + + // NOTE: should be kept outside of lazy promise to preserve + // correct callsite in case of replicator error. + const command = this.getCommand(args); + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + if (!testRun) { + const err = new _runtime.ClientFunctionAPIError(_this.callsiteNames.execution, _this.callsiteNames.instantiation, _message2.default.clientFunctionCantResolveTestRun); + + // NOTE: force callsite here, because more likely it will + // be impossible to resolve it by method name from a lazy promise. + err.callsite = callsite; + + throw err; + } + + const result = yield testRun.executeCommand(command, callsite); + + return _this._processResult(result, args); + })); + } + + _processResult(result) { + return this.replicator.decode(result); + } + + _validateOptions(options) { + (0, _typeAssertions.assertType)(_typeAssertions.is.nonNullObject, this.callsiteNames.instantiation, '"options" argument', options); + + if (!(0, _lodash.isNil)(options.boundTestRun)) { + // NOTE: `boundTestRun` can be either TestController or TestRun instance. + const boundTestRun = options.boundTestRun.testRun || options.boundTestRun; + + if (!boundTestRun[_markerSymbol2.default]) throw new _runtime.APIError(this.callsiteNames.instantiation, _message2.default.invalidClientFunctionTestRunBinding); + } + + if (!(0, _lodash.isNil)(options.dependencies)) (0, _typeAssertions.assertType)(_typeAssertions.is.nonNullObject, this.callsiteNames.instantiation, '"dependencies" option', options.dependencies); + } + + _getReplicatorTransforms() { + return [new _replicator.FunctionTransform(this.callsiteNames)]; + } +} +exports.default = ClientFunctionBuilder; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQtZnVuY3Rpb25zL2NsaWVudC1mdW5jdGlvbi1idWlsZGVyLmpzIl0sIm5hbWVzIjpbIkRFRkFVTFRfRVhFQ1VUSU9OX0NBTExTSVRFX05BTUUiLCJDbGllbnRGdW5jdGlvbkJ1aWxkZXIiLCJjb25zdHJ1Y3RvciIsImZuIiwib3B0aW9ucyIsImNhbGxzaXRlTmFtZXMiLCJpbnN0YW50aWF0aW9uIiwiZXhlY3V0aW9uIiwiX3ZhbGlkYXRlT3B0aW9ucyIsImNvbXBpbGVkRm5Db2RlIiwiX2dldENvbXBpbGVkRm5Db2RlIiwiX2NyZWF0ZUludmFsaWRGblR5cGVFcnJvciIsInJlcGxpY2F0b3IiLCJfZ2V0UmVwbGljYXRvclRyYW5zZm9ybXMiLCJfZGVjb3JhdGVGdW5jdGlvbiIsImNsaWVudEZuIiwiZnVuY3Rpb25CdWlsZGVyU3ltYm9sIiwid2l0aCIsImJ1aWxkZXIiLCJnZXRGdW5jdGlvbiIsImdldEJvdW5kVGVzdFJ1biIsImJvdW5kVGVzdFJ1biIsInRlc3RSdW4iLCJfZ2V0VGVzdFJ1biIsInRlc3RSdW5UcmFja2VyIiwicmVzb2x2ZUNvbnRleHRUZXN0UnVuIiwiX18kJGNsaWVudEZ1bmN0aW9uJCQiLCJjYWxsc2l0ZSIsImFyZ3MiLCJpIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwicHVzaCIsIl9leGVjdXRlQ29tbWFuZCIsImdldENvbW1hbmQiLCJlbmNvZGVkQXJncyIsImVuY29kZSIsImVuY29kZWREZXBlbmRlbmNpZXMiLCJnZXRGdW5jdGlvbkRlcGVuZGVuY2llcyIsIl9jcmVhdGVUZXN0UnVuQ29tbWFuZCIsImRlcGVuZGVuY2llcyIsIkV4ZWN1dGVDbGllbnRGdW5jdGlvbkNvbW1hbmQiLCJpbnN0YW50aWF0aW9uQ2FsbHNpdGVOYW1lIiwiZm5Db2RlIiwidG9TdHJpbmciLCJDbGllbnRGdW5jdGlvbkFQSUVycm9yIiwiTUVTU0FHRSIsImNsaWVudEZ1bmN0aW9uQ29kZUlzTm90QUZ1bmN0aW9uIiwiY29tbWFuZCIsIlJlRXhlY3V0YWJsZVByb21pc2UiLCJmcm9tRm4iLCJlcnIiLCJjbGllbnRGdW5jdGlvbkNhbnRSZXNvbHZlVGVzdFJ1biIsInJlc3VsdCIsImV4ZWN1dGVDb21tYW5kIiwiX3Byb2Nlc3NSZXN1bHQiLCJkZWNvZGUiLCJpcyIsIm5vbk51bGxPYmplY3QiLCJ0ZXN0UnVuTWFya2VyIiwiQVBJRXJyb3IiLCJpbnZhbGlkQ2xpZW50RnVuY3Rpb25UZXN0UnVuQmluZGluZyIsIkZ1bmN0aW9uVHJhbnNmb3JtIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOztBQUNBOztBQUNBOzs7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsa0NBQWtDLHNCQUF4Qzs7QUFFZSxNQUFNQyxxQkFBTixDQUE0QjtBQUN2Q0MsZ0JBQWFDLEVBQWIsRUFBaUJDLE9BQWpCLEVBQTBCQyxnQkFBZ0IsRUFBMUMsRUFBOEM7QUFDMUMsYUFBS0EsYUFBTCxHQUFxQjtBQUNqQkMsMkJBQWVELGNBQWNDLGFBRFo7QUFFakJDLHVCQUFlRixjQUFjRSxTQUFkLElBQTJCUDtBQUZ6QixTQUFyQjs7QUFLQSxZQUFJLG1CQUFrQkksT0FBbEIsQ0FBSixFQUNJQSxVQUFVLEVBQVY7O0FBRUosYUFBS0ksZ0JBQUwsQ0FBc0JKLE9BQXRCOztBQUVBLGFBQUtELEVBQUwsR0FBc0JBLEVBQXRCO0FBQ0EsYUFBS0MsT0FBTCxHQUFzQkEsT0FBdEI7QUFDQSxhQUFLSyxjQUFMLEdBQXNCLEtBQUtDLGtCQUFMLEVBQXRCOztBQUVBLFlBQUksQ0FBQyxLQUFLRCxjQUFWLEVBQ0ksTUFBTSxLQUFLRSx5QkFBTCxFQUFOOztBQUVKLGFBQUtDLFVBQUwsR0FBa0Isa0NBQWlCLEtBQUtDLHdCQUFMLEVBQWpCLENBQWxCO0FBQ0g7O0FBRURDLHNCQUFtQkMsUUFBbkIsRUFBNkI7QUFDekJBLGlCQUFTQyx1QkFBVCxJQUFrQyxJQUFsQzs7QUFFQUQsaUJBQVNF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aUJBQUosQ0FBYSxLQUFLdkQsYUFBTCxDQUFtQkMsYUFBaEMsRUFBK0N3QyxrQkFBUWUsbUNBQXZELENBQU47QUFDUDs7QUFFRCxZQUFJLENBQUMsbUJBQWtCekQsUUFBUW9DLFlBQTFCLENBQUwsRUFDSSxnQ0FBV2lCLG1CQUFHQyxhQUFkLEVBQTZCLEtBQUtyRCxhQUFMLENBQW1CQyxhQUFoRCxFQUErRCx1QkFBL0QsRUFBd0ZGLFFBQVFvQyxZQUFoRztBQUNQOztBQUVEM0IsK0JBQTRCO0FBQ3hCLGVBQU8sQ0FDSCxJQUFJaUQsNkJBQUosQ0FBc0IsS0FBS3pELGFBQTNCLENBREcsQ0FBUDtBQUdIO0FBcEpzQztrQkFBdEJKLHFCIiwiZmlsZSI6ImNsaWVudC1mdW5jdGlvbnMvY2xpZW50LWZ1bmN0aW9uLWJ1aWxkZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc05pbCBhcyBpc051bGxPclVuZGVmaW5lZCwgYXNzaWduIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB0ZXN0UnVuVHJhY2tlciBmcm9tICcuLi9hcGkvdGVzdC1ydW4tdHJhY2tlcic7XG5pbXBvcnQgZnVuY3Rpb25CdWlsZGVyU3ltYm9sIGZyb20gJy4vYnVpbGRlci1zeW1ib2wnO1xuaW1wb3J0IHsgY3JlYXRlUmVwbGljYXRvciwgRnVuY3Rpb25UcmFuc2Zvcm0gfSBmcm9tICcuL3JlcGxpY2F0b3InO1xuaW1wb3J0IHsgRXhlY3V0ZUNsaWVudEZ1bmN0aW9uQ29tbWFuZCB9IGZyb20gJy4uL3Rlc3QtcnVuL2NvbW1hbmRzL29ic2VydmF0aW9uJztcbmltcG9ydCBjb21waWxlQ2xpZW50RnVuY3Rpb24gZnJvbSAnLi4vY29tcGlsZXIvY29tcGlsZS1jbGllbnQtZnVuY3Rpb24nO1xuaW1wb3J0IHsgQVBJRXJyb3IsIENsaWVudEZ1bmN0aW9uQVBJRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgeyBhc3NlcnRUeXBlLCBpcyB9IGZyb20gJy4uL2Vycm9ycy9ydW50aW1lL3R5cGUtYXNzZXJ0aW9ucyc7XG5pbXBvcnQgTUVTU0FHRSBmcm9tICcuLi9lcnJvcnMvcnVudGltZS9tZXNzYWdlJztcbmltcG9ydCB7IGdldENhbGxzaXRlRm9yTWV0aG9kIH0gZnJvbSAnLi4vZXJyb3JzL2dldC1jYWxsc2l0ZSc7XG5pbXBvcnQgUmVFeGVjdXRhYmxlUHJvbWlzZSBmcm9tICcuLi91dGlscy9yZS1leGVjdXRhYmxlLXByb21pc2UnO1xuaW1wb3J0IHRlc3RSdW5NYXJrZXIgZnJvbSAnLi4vdGVzdC1ydW4vbWFya2VyLXN5bWJvbCc7XG5cbmNvbnN0IERFRkFVTFRfRVhFQ1VUSU9OX0NBTExTSVRFX05BTUUgPSAnX18kJGNsaWVudEZ1bmN0aW9uJCQnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDbGllbnRGdW5jdGlvbkJ1aWxkZXIge1xuICAgIGNvbnN0cnVjdG9yIChmbiwgb3B0aW9ucywgY2FsbHNpdGVOYW1lcyA9IHt9KSB7XG4gICAgICAgIHRoaXMuY2FsbHNpdGVOYW1lcyA9IHtcbiAgICAgICAgICAgIGluc3RhbnRpYXRpb246IGNhbGxzaXRlTmFtZXMuaW5zdGFudGlhdGlvbixcbiAgICAgICAgICAgIGV4ZWN1dGlvbjogICAgIGNhbGxzaXRlTmFtZXMuZXhlY3V0aW9uIHx8IERFRkFVTFRfRVhFQ1VUSU9OX0NBTExTSVRFX05BTUVcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoaXNOdWxsT3JVbmRlZmluZWQob3B0aW9ucykpXG4gICAgICAgICAgICBvcHRpb25zID0ge307XG5cbiAgICAgICAgdGhpcy5fdmFsaWRhdGVPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgICAgIHRoaXMuZm4gICAgICAgICAgICAgPSBmbjtcbiAgICAgICAgdGhpcy5vcHRpb25zICAgICAgICA9IG9wdGlvbnM7XG4gICAgICAgIHRoaXMuY29tcGlsZWRGbkNvZGUgPSB0aGlzLl9nZXRDb21waWxlZEZuQ29kZSgpO1xuXG4gICAgICAgIGlmICghdGhpcy5jb21waWxlZEZuQ29kZSlcbiAgICAgICAgICAgIHRocm93IHRoaXMuX2NyZWF0ZUludmFsaWRGblR5cGVFcnJvcigpO1xuXG4gICAgICAgIHRoaXMucmVwbGljYXRvciA9IGNyZWF0ZVJlcGxpY2F0b3IodGhpcy5fZ2V0UmVwbGljYXRvclRyYW5zZm9ybXMoKSk7XG4gICAgfVxuXG4gICAgX2RlY29yYXRlRnVuY3Rpb24gKGNsaWVudEZuKSB7XG4gICAgICAgIGNsaWVudEZuW2Z1bmN0aW9uQnVpbGRlclN5bWJvbF0gPSB0aGlzO1xuXG4gICAgICAgIGNsaWVudEZuLndpdGggPSBvcHRpb25zID0+IHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IGFzc2lnbih7fSwgdGhpcy5vcHRpb25zLCBvcHRpb25zKTtcblxuICAgICAgICAgICAgY29uc3QgYnVpbGRlciA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuZm4sIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICBpbnN0YW50aWF0aW9uOiAnd2l0aCcsXG4gICAgICAgICAgICAgICAgZXhlY3V0aW9uOiAgICAgdGhpcy5jYWxsc2l0ZU5hbWVzLmV4ZWN1dGlvblxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmdldEZ1bmN0aW9uKCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZ2V0Qm91bmRUZXN0UnVuICgpIHtcbiAgICAgICAgLy8gTk9URTogYGJvdW5kVGVzdFJ1bmAgY2FuIGJlIGVpdGhlciBUZXN0Q29udHJvbGxlciBvciBUZXN0UnVuIGluc3RhbmNlLlxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmJvdW5kVGVzdFJ1bilcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuYm91bmRUZXN0UnVuLnRlc3RSdW4gfHwgdGhpcy5vcHRpb25zLmJvdW5kVGVzdFJ1bjtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBfZ2V0VGVzdFJ1biAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJvdW5kVGVzdFJ1bigpIHx8IHRlc3RSdW5UcmFja2VyLnJlc29sdmVDb250ZXh0VGVzdFJ1bigpO1xuICAgIH1cblxuICAgIGdldEZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgYnVpbGRlciA9IHRoaXM7XG5cbiAgICAgICAgY29uc3QgY2xpZW50Rm4gPSBmdW5jdGlvbiBfXyQkY2xpZW50RnVuY3Rpb24kJCAoKSB7XG4gICAgICAgICAgICBjb25zdCB0ZXN0UnVuICA9IGJ1aWxkZXIuX2dldFRlc3RSdW4oKTtcbiAgICAgICAgICAgIGNvbnN0IGNhbGxzaXRlID0gZ2V0Q2FsbHNpdGVGb3JNZXRob2QoYnVpbGRlci5jYWxsc2l0ZU5hbWVzLmV4ZWN1dGlvbik7XG4gICAgICAgICAgICBjb25zdCBhcmdzICAgICA9IFtdO1xuXG4gICAgICAgICAgICAvLyBPUFRJTUlaQVRJT046IGRvbid0IGxlYWsgYGFyZ3VtZW50c2Agb2JqZWN0LlxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7XG5cbiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLl9leGVjdXRlQ29tbWFuZChhcmdzLCB0ZXN0UnVuLCBjYWxsc2l0ZSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fZGVjb3JhdGVGdW5jdGlvbihjbGllbnRGbik7XG5cbiAgICAgICAgcmV0dXJuIGNsaWVudEZuO1xuICAgIH1cblxuICAgIGdldENvbW1hbmQgKGFyZ3MpIHtcbiAgICAgICAgY29uc3QgZW5jb2RlZEFyZ3MgICAgICAgICA9IHRoaXMucmVwbGljYXRvci5lbmNvZGUoYXJncyk7XG4gICAgICAgIGNvbnN0IGVuY29kZWREZXBlbmRlbmNpZXMgPSB0aGlzLnJlcGxpY2F0b3IuZW5jb2RlKHRoaXMuZ2V0RnVuY3Rpb25EZXBlbmRlbmNpZXMoKSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2NyZWF0ZVRlc3RSdW5Db21tYW5kKGVuY29kZWRBcmdzLCBlbmNvZGVkRGVwZW5kZW5jaWVzKTtcbiAgICB9XG5cblxuICAgIC8vIE92ZXJyaWRhYmxlIG1ldGhvZHNcbiAgICBnZXRGdW5jdGlvbkRlcGVuZGVuY2llcyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZGVwZW5kZW5jaWVzIHx8IHt9O1xuICAgIH1cblxuICAgIF9jcmVhdGVUZXN0UnVuQ29tbWFuZCAoZW5jb2RlZEFyZ3MsIGVuY29kZWREZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBFeGVjdXRlQ2xpZW50RnVuY3Rpb25Db21tYW5kKHtcbiAgICAgICAgICAgIGluc3RhbnRpYXRpb25DYWxsc2l0ZU5hbWU6IHRoaXMuY2FsbHNpdGVOYW1lcy5pbnN0YW50aWF0aW9uLFxuICAgICAgICAgICAgZm5Db2RlOiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21waWxlZEZuQ29kZSxcbiAgICAgICAgICAgIGFyZ3M6ICAgICAgICAgICAgICAgICAgICAgIGVuY29kZWRBcmdzLFxuICAgICAgICAgICAgZGVwZW5kZW5jaWVzOiAgICAgICAgICAgICAgZW5jb2RlZERlcGVuZGVuY2llc1xuICAgICAgICB9LCB0aGlzLl9nZXRUZXN0UnVuKCkpO1xuICAgIH1cblxuICAgIF9nZXRDb21waWxlZEZuQ29kZSAoKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5mbiA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICAgIHJldHVybiBjb21waWxlQ2xpZW50RnVuY3Rpb24odGhpcy5mbi50b1N0cmluZygpLCB0aGlzLm9wdGlvbnMuZGVwZW5kZW5jaWVzLCB0aGlzLmNhbGxzaXRlTmFtZXMuaW5zdGFudGlhdGlvbiwgdGhpcy5jYWxsc2l0ZU5hbWVzLmluc3RhbnRpYXRpb24pO1xuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIF9jcmVhdGVJbnZhbGlkRm5UeXBlRXJyb3IgKCkge1xuICAgICAgICByZXR1cm4gbmV3IENsaWVudEZ1bmN0aW9uQVBJRXJyb3IodGhpcy5jYWxsc2l0ZU5hbWVzLmluc3RhbnRpYXRpb24sIHRoaXMuY2FsbHNpdGVOYW1lcy5pbnN0YW50aWF0aW9uLCBNRVNTQUdFLmNsaWVudEZ1bmN0aW9uQ29kZUlzTm90QUZ1bmN0aW9uLCB0eXBlb2YgdGhpcy5mbik7XG4gICAgfVxuXG4gICAgX2V4ZWN1dGVDb21tYW5kIChhcmdzLCB0ZXN0UnVuLCBjYWxsc2l0ZSkge1xuICAgICAgICAvLyBOT1RFOiBzaG91bGQgYmUga2VwdCBvdXRzaWRlIG9mIGxhenkgcHJvbWlzZSB0byBwcmVzZXJ2ZVxuICAgICAgICAvLyBjb3JyZWN0IGNhbGxzaXRlIGluIGNhc2Ugb2YgcmVwbGljYXRvciBlcnJvci5cbiAgICAgICAgY29uc3QgY29tbWFuZCA9IHRoaXMuZ2V0Q29tbWFuZChhcmdzKTtcblxuICAgICAgICByZXR1cm4gUmVFeGVjdXRhYmxlUHJvbWlzZS5mcm9tRm4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0ZXN0UnVuKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IENsaWVudEZ1bmN0aW9uQVBJRXJyb3IodGhpcy5jYWxsc2l0ZU5hbWVzLmV4ZWN1dGlvbiwgdGhpcy5jYWxsc2l0ZU5hbWVzLmluc3RhbnRpYXRpb24sIE1FU1NBR0UuY2xpZW50RnVuY3Rpb25DYW50UmVzb2x2ZVRlc3RSdW4pO1xuXG4gICAgICAgICAgICAgICAgLy8gTk9URTogZm9yY2UgY2FsbHNpdGUgaGVyZSwgYmVjYXVzZSBtb3JlIGxpa2VseSBpdCB3aWxsXG4gICAgICAgICAgICAgICAgLy8gYmUgaW1wb3NzaWJsZSB0byByZXNvbHZlIGl0IGJ5IG1ldGhvZCBuYW1lIGZyb20gYSBsYXp5IHByb21pc2UuXG4gICAgICAgICAgICAgICAgZXJyLmNhbGxzaXRlID0gY2FsbHNpdGU7XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRlc3RSdW4uZXhlY3V0ZUNvbW1hbmQoY29tbWFuZCwgY2FsbHNpdGUpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJvY2Vzc1Jlc3VsdChyZXN1bHQsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfcHJvY2Vzc1Jlc3VsdCAocmVzdWx0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcGxpY2F0b3IuZGVjb2RlKHJlc3VsdCk7XG4gICAgfVxuXG4gICAgX3ZhbGlkYXRlT3B0aW9ucyAob3B0aW9ucykge1xuICAgICAgICBhc3NlcnRUeXBlKGlzLm5vbk51bGxPYmplY3QsIHRoaXMuY2FsbHNpdGVOYW1lcy5pbnN0YW50aWF0aW9uLCAnXCJvcHRpb25zXCIgYXJndW1lbnQnLCBvcHRpb25zKTtcblxuICAgICAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKG9wdGlvbnMuYm91bmRUZXN0UnVuKSkge1xuICAgICAgICAgICAgLy8gTk9URTogYGJvdW5kVGVzdFJ1bmAgY2FuIGJlIGVpdGhlciBUZXN0Q29udHJvbGxlciBvciBUZXN0UnVuIGluc3RhbmNlLlxuICAgICAgICAgICAgY29uc3QgYm91bmRUZXN0UnVuID0gb3B0aW9ucy5ib3VuZFRlc3RSdW4udGVzdFJ1biB8fCBvcHRpb25zLmJvdW5kVGVzdFJ1bjtcblxuICAgICAgICAgICAgaWYgKCFib3VuZFRlc3RSdW5bdGVzdFJ1bk1hcmtlcl0pXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKHRoaXMuY2FsbHNpdGVOYW1lcy5pbnN0YW50aWF0aW9uLCBNRVNTQUdFLmludmFsaWRDbGllbnRGdW5jdGlvblRlc3RSdW5CaW5kaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNOdWxsT3JVbmRlZmluZWQob3B0aW9ucy5kZXBlbmRlbmNpZXMpKVxuICAgICAgICAgICAgYXNzZXJ0VHlwZShpcy5ub25OdWxsT2JqZWN0LCB0aGlzLmNhbGxzaXRlTmFtZXMuaW5zdGFudGlhdGlvbiwgJ1wiZGVwZW5kZW5jaWVzXCIgb3B0aW9uJywgb3B0aW9ucy5kZXBlbmRlbmNpZXMpO1xuICAgIH1cblxuICAgIF9nZXRSZXBsaWNhdG9yVHJhbnNmb3JtcyAoKSB7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBuZXcgRnVuY3Rpb25UcmFuc2Zvcm0odGhpcy5jYWxsc2l0ZU5hbWVzKVxuICAgICAgICBdO1xuICAgIH1cbn1cbiJdfQ== diff --git a/lib/client-functions/replicator.js b/lib/client-functions/replicator.js new file mode 100644 index 00000000..0be0e2a1 --- /dev/null +++ b/lib/client-functions/replicator.js @@ -0,0 +1,83 @@ +'use strict'; + +exports.__esModule = true; +exports.SelectorNodeTransform = exports.FunctionTransform = undefined; +exports.createReplicator = createReplicator; + +var _lodash = require('lodash'); + +var _replicator = require('replicator'); + +var _replicator2 = _interopRequireDefault(_replicator); + +var _builderSymbol = require('./builder-symbol'); + +var _builderSymbol2 = _interopRequireDefault(_builderSymbol); + +var _compileClientFunction = require('../compiler/compile-client-function'); + +var _compileClientFunction2 = _interopRequireDefault(_compileClientFunction); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function createReplicator(transforms) { + // NOTE: we will serialize replicator results + // to JSON with a command or command result. + // Therefore there is no need to do additional job here, + // so we use identity functions for serialization. + const replicator = new _replicator2.default({ + serialize: _lodash.identity, + deserialize: _lodash.identity + }); + + return replicator.addTransforms(transforms); +} + +// Replicator transforms +class FunctionTransform { + constructor(callsiteNames) { + this.type = 'Function'; + this.callsiteNames = callsiteNames; + } + + shouldTransform(type) { + return type === 'function'; + } + + toSerializable(fn) { + const clientFnBuilder = fn[_builderSymbol2.default]; + + if (clientFnBuilder) { + return { + fnCode: clientFnBuilder.compiledFnCode, + dependencies: clientFnBuilder.getFunctionDependencies() + }; + } + + return { + fnCode: (0, _compileClientFunction2.default)(fn.toString(), null, this.callsiteNames.instantiation, this.callsiteNames.execution), + dependencies: {} + }; + } + + fromSerializable() { + return void 0; + } +} + +exports.FunctionTransform = FunctionTransform; +class SelectorNodeTransform { + constructor() { + this.type = 'Node'; + } + + shouldTransform() { + return false; + } + + fromSerializable(nodeSnapshot) { + return nodeSnapshot; + } +} +exports.SelectorNodeTransform = SelectorNodeTransform; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQtZnVuY3Rpb25zL3JlcGxpY2F0b3IuanMiXSwibmFtZXMiOlsiY3JlYXRlUmVwbGljYXRvciIsInRyYW5zZm9ybXMiLCJyZXBsaWNhdG9yIiwiUmVwbGljYXRvciIsInNlcmlhbGl6ZSIsImlkZW50aXR5IiwiZGVzZXJpYWxpemUiLCJhZGRUcmFuc2Zvcm1zIiwiRnVuY3Rpb25UcmFuc2Zvcm0iLCJjb25zdHJ1Y3RvciIsImNhbGxzaXRlTmFtZXMiLCJ0eXBlIiwic2hvdWxkVHJhbnNmb3JtIiwidG9TZXJpYWxpemFibGUiLCJmbiIsImNsaWVudEZuQnVpbGRlciIsImZ1bmN0aW9uQnVpbGRlclN5bWJvbCIsImZuQ29kZSIsImNvbXBpbGVkRm5Db2RlIiwiZGVwZW5kZW5jaWVzIiwiZ2V0RnVuY3Rpb25EZXBlbmRlbmNpZXMiLCJ0b1N0cmluZyIsImluc3RhbnRpYXRpb24iLCJleGVjdXRpb24iLCJmcm9tU2VyaWFsaXphYmxlIiwiU2VsZWN0b3JOb2RlVHJhbnNmb3JtIiwibm9kZVNuYXBzaG90Il0sIm1hcHBpbmdzIjoiOzs7O1FBS2dCQSxnQixHQUFBQSxnQjs7QUFMaEI7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7QUFFTyxTQUFTQSxnQkFBVCxDQUEyQkMsVUFBM0IsRUFBdUM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFNQyxhQUFhLElBQUlDLG9CQUFKLENBQWU7QUFDOUJDLG1CQUFhQyxnQkFEaUI7QUFFOUJDLHFCQUFhRDtBQUZpQixLQUFmLENBQW5COztBQUtBLFdBQU9ILFdBQVdLLGFBQVgsQ0FBeUJOLFVBQXpCLENBQVA7QUFDSDs7QUFFRDtBQUNPLE1BQU1PLGlCQUFOLENBQXdCO0FBQzNCQyxnQkFBYUMsYUFBYixFQUE0QjtBQUN4QixhQUFLQyxJQUFMLEdBQXFCLFVBQXJCO0FBQ0EsYUFBS0QsYUFBTCxHQUFxQkEsYUFBckI7QUFDSDs7QUFFREUsb0JBQWlCRCxJQUFqQixFQUF1QjtBQUNuQixlQUFPQSxTQUFTLFVBQWhCO0FBQ0g7O0FBRURFLG1CQUFnQkMsRUFBaEIsRUFBb0I7QUFDaEIsY0FBTUMsa0JBQWtCRCxHQUFHRSx1QkFBSCxDQUF4Qjs7QUFFQSxZQUFJRCxlQUFKLEVBQXFCO0FBQ2pCLG1CQUFPO0FBQ0hFLHdCQUFjRixnQkFBZ0JHLGNBRDNCO0FBRUhDLDhCQUFjSixnQkFBZ0JLLHVCQUFoQjtBQUZYLGFBQVA7QUFJSDs7QUFFRCxlQUFPO0FBQ0hILG9CQUFjLHFDQUFzQkgsR0FBR08sUUFBSCxFQUF0QixFQUFxQyxJQUFyQyxFQUEyQyxLQUFLWCxhQUFMLENBQW1CWSxhQUE5RCxFQUE2RSxLQUFLWixhQUFMLENBQW1CYSxTQUFoRyxDQURYO0FBRUhKLDBCQUFjO0FBRlgsU0FBUDtBQUlIOztBQUVESyx1QkFBb0I7QUFDaEIsZUFBTyxLQUFLLENBQVo7QUFDSDtBQTVCMEI7O1FBQWxCaEIsaUIsR0FBQUEsaUI7QUErQk4sTUFBTWlCLHFCQUFOLENBQTRCO0FBQy9CaEIsa0JBQWU7QUFDWCxhQUFLRSxJQUFMLEdBQVksTUFBWjtBQUNIOztBQUVEQyxzQkFBbUI7QUFDZixlQUFPLEtBQVA7QUFDSDs7QUFFRFkscUJBQWtCRSxZQUFsQixFQUFnQztBQUM1QixlQUFPQSxZQUFQO0FBQ0g7QUFYOEI7UUFBdEJELHFCLEdBQUFBLHFCIiwiZmlsZSI6ImNsaWVudC1mdW5jdGlvbnMvcmVwbGljYXRvci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlkZW50aXR5IH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBSZXBsaWNhdG9yIGZyb20gJ3JlcGxpY2F0b3InO1xuaW1wb3J0IGZ1bmN0aW9uQnVpbGRlclN5bWJvbCBmcm9tICcuL2J1aWxkZXItc3ltYm9sJztcbmltcG9ydCBjb21waWxlQ2xpZW50RnVuY3Rpb24gZnJvbSAnLi4vY29tcGlsZXIvY29tcGlsZS1jbGllbnQtZnVuY3Rpb24nO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUmVwbGljYXRvciAodHJhbnNmb3Jtcykge1xuICAgIC8vIE5PVEU6IHdlIHdpbGwgc2VyaWFsaXplIHJlcGxpY2F0b3IgcmVzdWx0c1xuICAgIC8vIHRvIEpTT04gd2l0aCBhIGNvbW1hbmQgb3IgY29tbWFuZCByZXN1bHQuXG4gICAgLy8gVGhlcmVmb3JlIHRoZXJlIGlzIG5vIG5lZWQgdG8gZG8gYWRkaXRpb25hbCBqb2IgaGVyZSxcbiAgICAvLyBzbyB3ZSB1c2UgaWRlbnRpdHkgZnVuY3Rpb25zIGZvciBzZXJpYWxpemF0aW9uLlxuICAgIGNvbnN0IHJlcGxpY2F0b3IgPSBuZXcgUmVwbGljYXRvcih7XG4gICAgICAgIHNlcmlhbGl6ZTogICBpZGVudGl0eSxcbiAgICAgICAgZGVzZXJpYWxpemU6IGlkZW50aXR5XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVwbGljYXRvci5hZGRUcmFuc2Zvcm1zKHRyYW5zZm9ybXMpO1xufVxuXG4vLyBSZXBsaWNhdG9yIHRyYW5zZm9ybXNcbmV4cG9ydCBjbGFzcyBGdW5jdGlvblRyYW5zZm9ybSB7XG4gICAgY29uc3RydWN0b3IgKGNhbGxzaXRlTmFtZXMpIHtcbiAgICAgICAgdGhpcy50eXBlICAgICAgICAgID0gJ0Z1bmN0aW9uJztcbiAgICAgICAgdGhpcy5jYWxsc2l0ZU5hbWVzID0gY2FsbHNpdGVOYW1lcztcbiAgICB9XG5cbiAgICBzaG91bGRUcmFuc2Zvcm0gKHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIHR5cGUgPT09ICdmdW5jdGlvbic7XG4gICAgfVxuXG4gICAgdG9TZXJpYWxpemFibGUgKGZuKSB7XG4gICAgICAgIGNvbnN0IGNsaWVudEZuQnVpbGRlciA9IGZuW2Z1bmN0aW9uQnVpbGRlclN5bWJvbF07XG5cbiAgICAgICAgaWYgKGNsaWVudEZuQnVpbGRlcikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmbkNvZGU6ICAgICAgIGNsaWVudEZuQnVpbGRlci5jb21waWxlZEZuQ29kZSxcbiAgICAgICAgICAgICAgICBkZXBlbmRlbmNpZXM6IGNsaWVudEZuQnVpbGRlci5nZXRGdW5jdGlvbkRlcGVuZGVuY2llcygpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZuQ29kZTogICAgICAgY29tcGlsZUNsaWVudEZ1bmN0aW9uKGZuLnRvU3RyaW5nKCksIG51bGwsIHRoaXMuY2FsbHNpdGVOYW1lcy5pbnN0YW50aWF0aW9uLCB0aGlzLmNhbGxzaXRlTmFtZXMuZXhlY3V0aW9uKSxcbiAgICAgICAgICAgIGRlcGVuZGVuY2llczoge31cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmcm9tU2VyaWFsaXphYmxlICgpIHtcbiAgICAgICAgcmV0dXJuIHZvaWQgMDtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTZWxlY3Rvck5vZGVUcmFuc2Zvcm0ge1xuICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ05vZGUnO1xuICAgIH1cblxuICAgIHNob3VsZFRyYW5zZm9ybSAoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmcm9tU2VyaWFsaXphYmxlIChub2RlU25hcHNob3QpIHtcbiAgICAgICAgcmV0dXJuIG5vZGVTbmFwc2hvdDtcbiAgICB9XG59XG4iXX0= diff --git a/lib/client-functions/selectors/add-api.js b/lib/client-functions/selectors/add-api.js new file mode 100644 index 00000000..f40476f8 --- /dev/null +++ b/lib/client-functions/selectors/add-api.js @@ -0,0 +1,745 @@ +'use strict'; + +exports.__esModule = true; + +var _defineProperty = require('babel-runtime/core-js/object/define-property'); + +var _defineProperty2 = _interopRequireDefault(_defineProperty); + +var _assign = require('babel-runtime/core-js/object/assign'); + +var _assign2 = _interopRequireDefault(_assign); + +var _keys = require('babel-runtime/core-js/object/keys'); + +var _keys2 = _interopRequireDefault(_keys); + +var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); + +var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); + +let getSnapshot = (() => { + var _ref = (0, _asyncToGenerator3.default)(function* (getSelector, callsite, SelectorBuilder) { + let node = null; + const selector = new SelectorBuilder(getSelector(), { needError: true }, { instantiation: 'Selector' }).getFunction(); + + try { + node = yield selector(); + } catch (err) { + err.callsite = callsite; + throw err; + } + + return node; + }); + + return function getSnapshot(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +})(); + +exports.addCustomMethods = addCustomMethods; +exports.addAPI = addAPI; + +var _lodash = require('lodash'); + +var _builderSymbol = require('../builder-symbol'); + +var _builderSymbol2 = _interopRequireDefault(_builderSymbol); + +var _snapshotProperties = require('./snapshot-properties'); + +var _getCallsite = require('../../errors/get-callsite'); + +var _clientFunctionBuilder = require('../client-function-builder'); + +var _clientFunctionBuilder2 = _interopRequireDefault(_clientFunctionBuilder); + +var _reExecutablePromise = require('../../utils/re-executable-promise'); + +var _reExecutablePromise2 = _interopRequireDefault(_reExecutablePromise); + +var _typeAssertions = require('../../errors/runtime/type-assertions'); + +var _makeRegExp = require('../../utils/make-reg-exp'); + +var _makeRegExp2 = _interopRequireDefault(_makeRegExp); + +var _selectorTextFilter = require('./selector-text-filter'); + +var _selectorTextFilter2 = _interopRequireDefault(_selectorTextFilter); + +var _selectorAttributeFilter = require('./selector-attribute-filter'); + +var _selectorAttributeFilter2 = _interopRequireDefault(_selectorAttributeFilter); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const filterNodes = new _clientFunctionBuilder2.default((nodes, filter, querySelectorRoot, originNode, ...filterArgs) => { + if (typeof filter === 'number') { + const matchingNode = filter < 0 ? nodes[nodes.length + filter] : nodes[filter]; + + return matchingNode ? [matchingNode] : []; + } + + const result = []; + + if (typeof filter === 'string') { + // NOTE: we can search for elements only in document or element. + if (querySelectorRoot.nodeType !== 1 && querySelectorRoot.nodeType !== 9) return null; + + const matching = querySelectorRoot.querySelectorAll(filter); + const matchingArr = []; + + for (let i = 0; i < matching.length; i++) matchingArr.push(matching[i]); + + filter = node => matchingArr.indexOf(node) > -1; + } + + if (typeof filter === 'function') { + for (let j = 0; j < nodes.length; j++) { + if (filter(nodes[j], j, originNode, ...filterArgs)) result.push(nodes[j]); + } + } + + return result; +}).getFunction(); + +const expandSelectorResults = new _clientFunctionBuilder2.default((selector, populateDerivativeNodes) => { + const nodes = selector(); + + if (!nodes.length) return null; + + const result = []; + + for (let i = 0; i < nodes.length; i++) { + const derivativeNodes = populateDerivativeNodes(nodes[i]); + + if (derivativeNodes) { + for (let j = 0; j < derivativeNodes.length; j++) { + if (result.indexOf(derivativeNodes[j]) < 0) result.push(derivativeNodes[j]); + } + } + } + + return result; +}).getFunction(); + +function assertAddCustomDOMPropertiesOptions(properties) { + (0, _typeAssertions.assertType)(_typeAssertions.is.nonNullObject, 'addCustomDOMProperties', '"addCustomDOMProperties" option', properties); + + (0, _keys2.default)(properties).forEach(prop => { + (0, _typeAssertions.assertType)(_typeAssertions.is.function, 'addCustomDOMProperties', `Custom DOM properties method '${prop}'`, properties[prop]); + }); +} + +function assertAddCustomMethods(properties, opts) { + (0, _typeAssertions.assertType)(_typeAssertions.is.nonNullObject, 'addCustomMethods', '"addCustomMethods" option', properties); + + if (opts !== void 0) (0, _typeAssertions.assertType)(_typeAssertions.is.nonNullObject, 'addCustomMethods', '"addCustomMethods" option', opts); + + (0, _keys2.default)(properties).forEach(prop => { + (0, _typeAssertions.assertType)(_typeAssertions.is.function, 'addCustomMethods', `Custom method '${prop}'`, properties[prop]); + }); +} + +function prepareApiFnArgs(fnName, ...args) { + args = args.map(arg => { + if (typeof arg === 'string') return `'${arg}'`; + if (typeof arg === 'function') return '[function]'; + return arg; + }); + args = args.join(', '); + + return `.${fnName}(${args})`; +} + +function getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, additionalDependencies) { + return (0, _assign2.default)({}, options, { selectorFn, apiFn, filter, additionalDependencies }); +} + +function addSnapshotProperties(obj, getSelector, SelectorBuilder, properties) { + properties.forEach(prop => { + (0, _defineProperty2.default)(obj, prop, { + get: () => { + const callsite = (0, _getCallsite.getCallsiteForMethod)('get'); + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + const snapshot = yield getSnapshot(getSelector, callsite, SelectorBuilder); + + return snapshot[prop]; + })); + } + }); + }); +} + +function addCustomMethods(obj, getSelector, SelectorBuilder, customMethods) { + const customMethodProps = customMethods ? (0, _keys2.default)(customMethods) : []; + + customMethodProps.forEach(prop => { + var _customMethods$prop = customMethods[prop], + _customMethods$prop$r = _customMethods$prop.returnDOMNodes; + const returnDOMNodes = _customMethods$prop$r === undefined ? false : _customMethods$prop$r, + method = _customMethods$prop.method; + + + const dependencies = { + customMethod: method, + selector: getSelector() + }; + + const callsiteNames = { instantiation: prop }; + + if (returnDOMNodes) { + obj[prop] = (...args) => { + const selectorFn = () => { + /* eslint-disable no-undef */ + const nodes = selector(); + + return customMethod.apply(customMethod, [nodes].concat(args)); + /* eslint-enable no-undef */ + }; + + const apiFn = prepareApiFnArgs(prop, ...args); + const filter = () => true; + + const additionalDependencies = { + args, + customMethod: method + }; + + return createDerivativeSelectorWithFilter({ getSelector, SelectorBuilder, selectorFn, apiFn, filter, additionalDependencies }); + }; + } else { + obj[prop] = new _clientFunctionBuilder2.default((...args) => { + /* eslint-disable no-undef */ + const node = selector(); + + return customMethod.apply(customMethod, [node].concat(args)); + /* eslint-enable no-undef */ + }, { dependencies }, callsiteNames).getFunction(); + } + }); +} + +function addSnapshotPropertyShorthands({ obj, getSelector, SelectorBuilder, customDOMProperties, customMethods }) { + let properties = _snapshotProperties.SNAPSHOT_PROPERTIES; + + if (customDOMProperties) properties = properties.concat((0, _keys2.default)(customDOMProperties)); + + addSnapshotProperties(obj, getSelector, SelectorBuilder, properties); + addCustomMethods(obj, getSelector, SelectorBuilder, customMethods); + + obj.getStyleProperty = prop => { + const callsite = (0, _getCallsite.getCallsiteForMethod)('getStyleProperty'); + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + const snapshot = yield getSnapshot(getSelector, callsite, SelectorBuilder); + + return snapshot.style ? snapshot.style[prop] : void 0; + })); + }; + + obj.getAttribute = attrName => { + const callsite = (0, _getCallsite.getCallsiteForMethod)('getAttribute'); + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + const snapshot = yield getSnapshot(getSelector, callsite, SelectorBuilder); + + return snapshot.attributes ? snapshot.attributes[attrName] : void 0; + })); + }; + + obj.hasAttribute = attrName => { + const callsite = (0, _getCallsite.getCallsiteForMethod)('hasAttribute'); + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + const snapshot = yield getSnapshot(getSelector, callsite, SelectorBuilder); + + return snapshot.attributes ? snapshot.attributes.hasOwnProperty(attrName) : false; + })); + }; + + obj.getBoundingClientRectProperty = prop => { + const callsite = (0, _getCallsite.getCallsiteForMethod)('getBoundingClientRectProperty'); + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + const snapshot = yield getSnapshot(getSelector, callsite, SelectorBuilder); + + return snapshot.boundingClientRect ? snapshot.boundingClientRect[prop] : void 0; + })); + }; + + obj.hasClass = name => { + const callsite = (0, _getCallsite.getCallsiteForMethod)('hasClass'); + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + const snapshot = yield getSnapshot(getSelector, callsite, SelectorBuilder); + + return snapshot.classNames ? snapshot.classNames.indexOf(name) > -1 : false; + })); + }; +} + +function createCounter(getSelector, SelectorBuilder) { + const builder = new SelectorBuilder(getSelector(), { counterMode: true }, { instantiation: 'Selector' }); + const counter = builder.getFunction(); + const callsite = (0, _getCallsite.getCallsiteForMethod)('get'); + + return (0, _asyncToGenerator3.default)(function* () { + try { + return yield counter(); + } catch (err) { + err.callsite = callsite; + throw err; + } + }); +} + +function addCounterProperties({ obj, getSelector, SelectorBuilder }) { + Object.defineProperty(obj, 'count', { + get: () => { + const counter = createCounter(getSelector, SelectorBuilder); + + return _reExecutablePromise2.default.fromFn(() => counter()); + } + }); + + Object.defineProperty(obj, 'exists', { + get: () => { + const counter = createCounter(getSelector, SelectorBuilder); + + return _reExecutablePromise2.default.fromFn((0, _asyncToGenerator3.default)(function* () { + return (yield counter()) > 0; + })); + } + }); +} + +function convertFilterToClientFunctionIfNecessary(callsiteName, filter, dependencies) { + if (typeof filter === 'function') { + const builder = filter[_builderSymbol2.default]; + const fn = builder ? builder.fn : filter; + const options = builder ? (0, _lodash.assign)({}, builder.options, { dependencies }) : { dependencies }; + + return new _clientFunctionBuilder2.default(fn, options, { instantiation: callsiteName }).getFunction(); + } + + return filter; +} + +function createDerivativeSelectorWithFilter({ getSelector, SelectorBuilder, selectorFn, apiFn, filter, additionalDependencies }) { + const collectionModeSelectorBuilder = new SelectorBuilder(getSelector(), { collectionMode: true }); + const customDOMProperties = collectionModeSelectorBuilder.options.customDOMProperties; + const customMethods = collectionModeSelectorBuilder.options.customMethods; + + let dependencies = { + selector: collectionModeSelectorBuilder.getFunction(), + filter: filter, + filterNodes: filterNodes + }; + + var _collectionModeSelect = collectionModeSelectorBuilder.options; + const boundTestRun = _collectionModeSelect.boundTestRun, + timeout = _collectionModeSelect.timeout, + visibilityCheck = _collectionModeSelect.visibilityCheck, + apiFnChain = _collectionModeSelect.apiFnChain; + + + dependencies = (0, _lodash.assign)(dependencies, additionalDependencies); + + const builder = new SelectorBuilder(selectorFn, { + dependencies, + customDOMProperties, + customMethods, + boundTestRun, + timeout, + visibilityCheck, + apiFnChain, + apiFn + }, { instantiation: 'Selector' }); + + return builder.getFunction(); +} + +const filterByText = convertFilterToClientFunctionIfNecessary('filter', _selectorTextFilter2.default); +const filterByAttr = convertFilterToClientFunctionIfNecessary('filter', _selectorAttributeFilter2.default); + +function ensureRegExpContext(str) { + // NOTE: if a regexp is created in a separate context (via the 'vm' module) we + // should wrap it with new RegExp() to make the `instanceof RegExp` check successful. + if (typeof str !== 'string' && !(str instanceof RegExp)) return new RegExp(str); + + return str; +} + +function addFilterMethods(options) { + const obj = options.obj, + getSelector = options.getSelector, + SelectorBuilder = options.SelectorBuilder; + + + obj.nth = index => { + (0, _typeAssertions.assertType)(_typeAssertions.is.number, 'nth', '"index" argument', index); + + const apiFn = prepareApiFnArgs('nth', index); + const builder = new SelectorBuilder(getSelector(), { index, apiFn }, { instantiation: 'Selector' }); + + return builder.getFunction(); + }; + + obj.withText = text => { + (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.regExp], 'withText', '"text" argument', text); + + const apiFn = prepareApiFnArgs('withText', text); + + text = ensureRegExpContext(text); + + const selectorFn = () => { + /* eslint-disable no-undef */ + const nodes = selector(); + + if (!nodes.length) return null; + + return filterNodes(nodes, filter, document, void 0, textRe); + /* eslint-enable no-undef */ + }; + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filterByText, { textRe: (0, _makeRegExp2.default)(text) }); + + return createDerivativeSelectorWithFilter(args); + }; + + obj.withExactText = text => { + (0, _typeAssertions.assertType)(_typeAssertions.is.string, 'withExactText', '"text" argument', text); + + const selectorFn = () => { + /* eslint-disable no-undef */ + const nodes = selector(); + + if (!nodes.length) return null; + + return filterNodes(nodes, filter, document, void 0, exactText); + /* eslint-enable no-undef */ + }; + + const apiFn = prepareApiFnArgs('withExactText', text); + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filterByText, { exactText: text }); + + return createDerivativeSelectorWithFilter(args); + }; + + obj.withAttribute = (attrName, attrValue) => { + (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.regExp], 'withAttribute', '"attrName" argument', attrName); + + const apiFn = prepareApiFnArgs('withAttribute', attrName, attrValue); + + attrName = ensureRegExpContext(attrName); + + if (attrValue !== void 0) { + (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.regExp], 'withAttribute', '"attrValue" argument', attrValue); + attrValue = ensureRegExpContext(attrValue); + } + + const selectorFn = () => { + /* eslint-disable no-undef */ + const nodes = selector(); + + if (!nodes.length) return null; + + return filterNodes(nodes, filter, document, void 0, attrName, attrValue); + /* eslint-enable no-undef */ + }; + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filterByAttr, { + attrName, + attrValue + }); + + return createDerivativeSelectorWithFilter(args); + }; + + obj.filter = (filter, dependencies) => { + (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.function], 'filter', '"filter" argument', filter); + + const apiFn = prepareApiFnArgs('filter', filter); + + filter = convertFilterToClientFunctionIfNecessary('filter', filter, dependencies); + + const selectorFn = () => { + /* eslint-disable no-undef */ + const nodes = selector(); + + if (!nodes.length) return null; + + return filterNodes(nodes, filter, document, void 0); + /* eslint-enable no-undef */ + }; + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter); + + return createDerivativeSelectorWithFilter(args); + }; + + obj.filterVisible = () => { + const apiFn = prepareApiFnArgs('filterVisible'); + const builder = new SelectorBuilder(getSelector(), { filterVisible: true, apiFn }, { instantiation: 'Selector' }); + + return builder.getFunction(); + }; + + obj.filterHidden = () => { + const apiFn = prepareApiFnArgs('filterHidden'); + const builder = new SelectorBuilder(getSelector(), { filterHidden: true, apiFn }, { instantiation: 'Selector' }); + + return builder.getFunction(); + }; +} + +function addCustomDOMPropertiesMethod({ obj, getSelector, SelectorBuilder }) { + obj.addCustomDOMProperties = customDOMProperties => { + assertAddCustomDOMPropertiesOptions(customDOMProperties); + + const builder = new SelectorBuilder(getSelector(), { customDOMProperties }, { instantiation: 'Selector' }); + + return builder.getFunction(); + }; +} + +function addCustomMethodsMethod({ obj, getSelector, SelectorBuilder }) { + obj.addCustomMethods = function (methods, opts) { + assertAddCustomMethods(methods, opts); + + const customMethods = {}; + + (0, _keys2.default)(methods).forEach(methodName => { + customMethods[methodName] = { + method: methods[methodName], + returnDOMNodes: opts && !!opts.returnDOMNodes + }; + }); + + const builder = new SelectorBuilder(getSelector(), { customMethods }, { instantiation: 'Selector' }); + + return builder.getFunction(); + }; +} + +function addHierarchicalSelectors(options) { + const obj = options.obj; + + // Find + + obj.find = (filter, dependencies) => { + (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.function], 'find', '"filter" argument', filter); + + const apiFn = prepareApiFnArgs('find', filter); + + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); + + const selectorFn = () => { + /* eslint-disable no-undef */ + return expandSelectorResults(selector, node => { + if (typeof filter === 'string') { + return typeof node.querySelectorAll === 'function' ? node.querySelectorAll(filter) : null; + } + + const results = []; + + const visitNode = currentNode => { + const cnLength = currentNode.childNodes.length; + + for (let i = 0; i < cnLength; i++) { + const child = currentNode.childNodes[i]; + + results.push(child); + + visitNode(child); + } + }; + + visitNode(node); + + return filterNodes(results, filter, null, node); + }); + /* eslint-enable no-undef */ + }; + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); + }; + + // Parent + obj.parent = (filter, dependencies) => { + if (filter !== void 0) (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.function, _typeAssertions.is.number], 'parent', '"filter" argument', filter); + + const apiFn = prepareApiFnArgs('parent', filter); + + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); + + const selectorFn = () => { + /* eslint-disable no-undef */ + return expandSelectorResults(selector, node => { + const parents = []; + + for (let parent = node.parentNode; parent; parent = parent.parentNode) parents.push(parent); + + return filter !== void 0 ? filterNodes(parents, filter, document, node) : parents; + }); + /* eslint-enable no-undef */ + }; + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); + }; + + // Child + obj.child = (filter, dependencies) => { + if (filter !== void 0) (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.function, _typeAssertions.is.number], 'child', '"filter" argument', filter); + + const apiFn = prepareApiFnArgs('child', filter); + + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); + + const selectorFn = () => { + /* eslint-disable no-undef */ + return expandSelectorResults(selector, node => { + const childElements = []; + const cnLength = node.childNodes.length; + + for (let i = 0; i < cnLength; i++) { + const child = node.childNodes[i]; + + if (child.nodeType === 1) childElements.push(child); + } + + return filter !== void 0 ? filterNodes(childElements, filter, node, node) : childElements; + }); + /* eslint-enable no-undef */ + }; + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); + }; + + // Sibling + obj.sibling = (filter, dependencies) => { + if (filter !== void 0) (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.function, _typeAssertions.is.number], 'sibling', '"filter" argument', filter); + + const apiFn = prepareApiFnArgs('sibling', filter); + + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); + + const selectorFn = () => { + /* eslint-disable no-undef */ + return expandSelectorResults(selector, node => { + const parent = node.parentNode; + + if (!parent) return null; + + const siblings = []; + const cnLength = parent.childNodes.length; + + for (let i = 0; i < cnLength; i++) { + const child = parent.childNodes[i]; + + if (child.nodeType === 1 && child !== node) siblings.push(child); + } + + return filter !== void 0 ? filterNodes(siblings, filter, parent, node) : siblings; + }); + /* eslint-enable no-undef */ + }; + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); + }; + + // Next sibling + obj.nextSibling = (filter, dependencies) => { + if (filter !== void 0) (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.function, _typeAssertions.is.number], 'nextSibling', '"filter" argument', filter); + + const apiFn = prepareApiFnArgs('nextSibling', filter); + + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); + + const selectorFn = () => { + /* eslint-disable no-undef */ + return expandSelectorResults(selector, node => { + const parent = node.parentNode; + + if (!parent) return null; + + const siblings = []; + const cnLength = parent.childNodes.length; + let afterNode = false; + + for (let i = 0; i < cnLength; i++) { + const child = parent.childNodes[i]; + + if (child === node) afterNode = true;else if (afterNode && child.nodeType === 1) siblings.push(child); + } + + return filter !== void 0 ? filterNodes(siblings, filter, parent, node) : siblings; + }); + /* eslint-enable no-undef */ + }; + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); + }; + + // Prev sibling + obj.prevSibling = (filter, dependencies) => { + if (filter !== void 0) (0, _typeAssertions.assertType)([_typeAssertions.is.string, _typeAssertions.is.function, _typeAssertions.is.number], 'prevSibling', '"filter" argument', filter); + + const apiFn = prepareApiFnArgs('prevSibling', filter); + + filter = convertFilterToClientFunctionIfNecessary('find', filter, dependencies); + + const selectorFn = () => { + /* eslint-disable no-undef */ + return expandSelectorResults(selector, node => { + const parent = node.parentNode; + + if (!parent) return null; + + const siblings = []; + const cnLength = parent.childNodes.length; + + for (let i = 0; i < cnLength; i++) { + const child = parent.childNodes[i]; + + if (child === node) break; + + if (child.nodeType === 1) siblings.push(child); + } + + return filter !== void 0 ? filterNodes(siblings, filter, parent, node) : siblings; + }); + /* eslint-enable no-undef */ + }; + + const args = getDerivativeSelectorArgs(options, selectorFn, apiFn, filter, { expandSelectorResults }); + + return createDerivativeSelectorWithFilter(args); + }; +} + +function addAPI(selector, getSelector, SelectorBuilder, customDOMProperties, customMethods) { + const options = { obj: selector, getSelector, SelectorBuilder, customDOMProperties, customMethods }; + + addFilterMethods(options); + addHierarchicalSelectors(options); + addSnapshotPropertyShorthands(options); + addCustomDOMPropertiesMethod(options); + addCustomMethodsMethod(options); + addCounterProperties(options); +} +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGllbnQtZnVuY3Rpb25zL3NlbGVjdG9ycy9hZGQtYXBpLmpzIl0sIm5hbWVzIjpbImdldFNlbGVjdG9yIiwiY2FsbHNpdGUiLCJTZWxlY3RvckJ1aWxkZXIiLCJub2RlIiwic2VsZWN0b3IiLCJuZWVkRXJyb3IiLCJpbnN0YW50aWF0aW9uIiwiZ2V0RnVuY3Rpb24iLCJlcnIiLCJnZXRTbmFwc2hvdCIsImFkZEN1c3RvbU1ldGhvZHMiLCJhZGRBUEkiLCJmaWx0ZXJOb2RlcyIsIkNsaWVudEZ1bmN0aW9uQnVpbGRlciIsIm5vZGVzIiwiZmlsdGVyIiwicXVlcnlTZWxlY3RvclJvb3QiLCJvcmlnaW5Ob2RlIiwiZmlsdGVyQXJncyIsIm1hdGNoaW5nTm9kZSIsImxlbmd0aCIsInJlc3VsdCIsIm5vZGVUeXBlIiwibWF0Y2hpbmciLCJxdWVyeVNlbGVjdG9yQWxsIiwibWF0Y2hpbmdBcnIiLCJpIiwicHVzaCIsImluZGV4T2YiLCJqIiwiZXhwYW5kU2VsZWN0b3JSZXN1bHRzIiwicG9wdWxhdGVEZXJpdmF0aXZlTm9kZXMiLCJkZXJpdmF0aXZlTm9kZXMiLCJhc3NlcnRBZGRDdXN0b21ET01Qcm9wZXJ0aWVzT3B0aW9ucyIsInByb3BlcnRpZXMiLCJpcyIsIm5vbk51bGxPYmplY3QiLCJmb3JFYWNoIiwicHJvcCIsImZ1bmN0aW9uIiwiYXNzZXJ0QWRkQ3VzdG9tTWV0aG9kcyIsIm9wdHMiLCJwcmVwYXJlQXBpRm5BcmdzIiwiZm5OYW1lIiwiYXJncyIsIm1hcCIsImFyZyIsImpvaW4iLCJnZXREZXJpdmF0aXZlU2VsZWN0b3JBcmdzIiwib3B0aW9ucyIsInNlbGVjdG9yRm4iLCJhcGlGbiIsImFkZGl0aW9uYWxEZXBlbmRlbmNpZXMiLCJhZGRTbmFwc2hvdFByb3BlcnRpZXMiLCJvYmoiLCJnZXQiLCJSZUV4ZWN1dGFibGVQcm9taXNlIiwiZnJvbUZuIiwic25hcHNob3QiLCJjdXN0b21NZXRob2RzIiwiY3VzdG9tTWV0aG9kUHJvcHMiLCJyZXR1cm5ET01Ob2RlcyIsIm1ldGhvZCIsImRlcGVuZGVuY2llcyIsImN1c3RvbU1ldGhvZCIsImNhbGxzaXRlTmFtZXMiLCJhcHBseSIsImNvbmNhdCIsImNyZWF0ZURlcml2YXRpdmVTZWxlY3RvcldpdGhGaWx0ZXIiLCJhZGRTbmFwc2hvdFByb3BlcnR5U2hvcnRoYW5kcyIsImN1c3RvbURPTVByb3BlcnRpZXMiLCJTTkFQU0hPVF9QUk9QRVJUSUVTIiwiZ2V0U3R5bGVQcm9wZXJ0eSIsInN0eWxlIiwiZ2V0QXR0cmlidXRlIiwiYXR0ck5hbWUiLCJhdHRyaWJ1dGVzIiwiaGFzQXR0cmlidXRlIiwiaGFzT3duUHJvcGVydHkiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3RQcm9wZXJ0eSIsImJvdW5kaW5nQ2xpZW50UmVjdCIsImhhc0NsYXNzIiwibmFtZSIsImNsYXNzTmFtZXMiLCJjcmVhdGVDb3VudGVyIiwiYnVpbGRlciIsImNvdW50ZXJNb2RlIiwiY291bnRlciIsImFkZENvdW50ZXJQcm9wZXJ0aWVzIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJjb252ZXJ0RmlsdGVyVG9DbGllbnRGdW5jdGlvbklmTmVjZXNzYXJ5IiwiY2FsbHNpdGVOYW1lIiwiY2xpZW50RnVuY3Rpb25CdWlsZGVyU3ltYm9sIiwiZm4iLCJjb2xsZWN0aW9uTW9kZVNlbGVjdG9yQnVpbGRlciIsImNvbGxlY3Rpb25Nb2RlIiwiYm91bmRUZXN0UnVuIiwidGltZW91dCIsInZpc2liaWxpdHlDaGVjayIsImFwaUZuQ2hhaW4iLCJmaWx0ZXJCeVRleHQiLCJzZWxlY3RvclRleHRGaWx0ZXIiLCJmaWx0ZXJCeUF0dHIiLCJzZWxlY3RvckF0dHJpYnV0ZUZpbHRlciIsImVuc3VyZVJlZ0V4cENvbnRleHQiLCJzdHIiLCJSZWdFeHAiLCJhZGRGaWx0ZXJNZXRob2RzIiwibnRoIiwiaW5kZXgiLCJudW1iZXIiLCJ3aXRoVGV4dCIsInRleHQiLCJzdHJpbmciLCJyZWdFeHAiLCJkb2N1bWVudCIsInRleHRSZSIsIndpdGhFeGFjdFRleHQiLCJleGFjdFRleHQiLCJ3aXRoQXR0cmlidXRlIiwiYXR0clZhbHVlIiwiZmlsdGVyVmlzaWJsZSIsImZpbHRlckhpZGRlbiIsImFkZEN1c3RvbURPTVByb3BlcnRpZXNNZXRob2QiLCJhZGRDdXN0b21ET01Qcm9wZXJ0aWVzIiwiYWRkQ3VzdG9tTWV0aG9kc01ldGhvZCIsIm1ldGhvZHMiLCJtZXRob2ROYW1lIiwiYWRkSGllcmFyY2hpY2FsU2VsZWN0b3JzIiwiZmluZCIsInJlc3VsdHMiLCJ2aXNpdE5vZGUiLCJjdXJyZW50Tm9kZSIsImNuTGVuZ3RoIiwiY2hpbGROb2RlcyIsImNoaWxkIiwicGFyZW50IiwicGFyZW50cyIsInBhcmVudE5vZGUiLCJjaGlsZEVsZW1lbnRzIiwic2libGluZyIsInNpYmxpbmdzIiwibmV4dFNpYmxpbmciLCJhZnRlck5vZGUiLCJwcmV2U2libGluZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytDQW1FQSxXQUE0QkEsV0FBNUIsRUFBeUNDLFFBQXpDLEVBQW1EQyxlQUFuRCxFQUFvRTtBQUNoRSxZQUFJQyxPQUFhLElBQWpCO0FBQ0EsY0FBTUMsV0FBVyxJQUFJRixlQUFKLENBQW9CRixhQUFwQixFQUFtQyxFQUFFSyxXQUFXLElBQWIsRUFBbkMsRUFBd0QsRUFBRUMsZUFBZSxVQUFqQixFQUF4RCxFQUF1RkMsV0FBdkYsRUFBakI7O0FBRUEsWUFBSTtBQUNBSixtQkFBTyxNQUFNQyxVQUFiO0FBQ0gsU0FGRCxDQUlBLE9BQU9JLEdBQVAsRUFBWTtBQUNSQSxnQkFBSVAsUUFBSixHQUFlQSxRQUFmO0FBQ0Esa0JBQU1PLEdBQU47QUFDSDs7QUFFRCxlQUFPTCxJQUFQO0FBQ0gsSzs7b0JBZGNNLFc7Ozs7O1FBb0VDQyxnQixHQUFBQSxnQjtRQTRqQkFDLE0sR0FBQUEsTTs7QUFuc0JoQjs7QUFDQTs7OztBQUNBOztBQUNBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7OztBQUVBLE1B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dW5jdGlvbnMvc2VsZWN0b3JzL2FkZC1hcGkuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhc3NpZ24gfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGNsaWVudEZ1bmN0aW9uQnVpbGRlclN5bWJvbCBmcm9tICcuLi9idWlsZGVyLXN5bWJvbCc7XG5pbXBvcnQgeyBTTkFQU0hPVF9QUk9QRVJUSUVTIH0gZnJvbSAnLi9zbmFwc2hvdC1wcm9wZXJ0aWVzJztcbmltcG9ydCB7IGdldENhbGxzaXRlRm9yTWV0aG9kIH0gZnJvbSAnLi4vLi4vZXJyb3JzL2dldC1jYWxsc2l0ZSc7XG5pbXBvcnQgQ2xpZW50RnVuY3Rpb25CdWlsZGVyIGZyb20gJy4uL2NsaWVudC1mdW5jdGlvbi1idWlsZGVyJztcbmltcG9ydCBSZUV4ZWN1dGFibGVQcm9taXNlIGZyb20gJy4uLy4uL3V0aWxzL3JlLWV4ZWN1dGFibGUtcHJvbWlzZSc7XG5pbXBvcnQgeyBhc3NlcnRUeXBlLCBpcyB9IGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lL3R5cGUtYXNzZXJ0aW9ucyc7XG5pbXBvcnQgbWFrZVJlZ0V4cCBmcm9tICcuLi8uLi91dGlscy9tYWtlLXJlZy1leHAnO1xuaW1wb3J0IHNlbGVjdG9yVGV4dEZpbHRlciBmcm9tICcuL3NlbGVjdG9yLXRleHQtZmlsdGVyJztcbmltcG9ydCBzZWxlY3RvckF0dHJpYnV0ZUZpbHRlciBmcm9tICcuL3NlbGVjdG9yLWF0dHJpYnV0ZS1maWx0ZXInO1xuXG5jb25zdCBmaWx0ZXJOb2RlcyA9IChuZXcgQ2xpZW50RnVuY3Rpb25CdWlsZGVyKChub2RlcywgZmlsdGVyLCBxdWVyeVNlbGVjdG9yUm9vdCwgb3JpZ2luTm9kZSwgLi4uZmlsdGVyQXJncykgPT4ge1xuICAgIGlmICh0eXBlb2YgZmlsdGVyID09PSAnbnVtYmVyJykge1xuICAgICAgICBjb25zdCBtYXRjaGluZ05vZGUgPSBmaWx0ZXIgPCAwID8gbm9kZXNbbm9kZXMubGVuZ3RoICsgZmlsdGVyXSA6IG5vZGVzW2ZpbHRlcl07XG5cbiAgICAgICAgcmV0dXJuIG1hdGNoaW5nTm9kZSA/IFttYXRjaGluZ05vZGVdIDogW107XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gW107XG5cbiAgICBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgLy8gTk9URTogd2UgY2FuIHNlYXJjaCBmb3IgZWxlbWVudHMgb25seSBpbiBkb2N1bWVudCBvciBlbGVtZW50LlxuICAgICAgICBpZiAocXVlcnlTZWxlY3RvclJvb3Qubm9kZVR5cGUgIT09IDEgJiYgcXVlcnlTZWxlY3RvclJvb3Qubm9kZVR5cGUgIT09IDkpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCBtYXRjaGluZyAgICA9IHF1ZXJ5U2VsZWN0b3JSb290LnF1ZXJ5U2VsZWN0b3JBbGwoZmlsdGVyKTtcbiAgICAgICAgY29uc3QgbWF0Y2hpbmdBcnIgPSBbXTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hdGNoaW5nLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgbWF0Y2hpbmdBcnIucHVzaChtYXRjaGluZ1tpXSk7XG5cbiAgICAgICAgZmlsdGVyID0gbm9kZSA9PiBtYXRjaGluZ0Fyci5pbmRleE9mKG5vZGUpID4gLTE7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBmaWx0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBub2Rlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgaWYgKGZpbHRlcihub2Rlc1tqXSwgaiwgb3JpZ2luTm9kZSwgLi4uZmlsdGVyQXJncykpXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gobm9kZXNbal0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbn0pKS5nZXRGdW5jdGlvbigpO1xuXG5jb25zdCBleHBhbmRTZWxlY3RvclJlc3VsdHMgPSAobmV3IENsaWVudEZ1bmN0aW9uQnVpbGRlcigoc2VsZWN0b3IsIHBvcHVsYXRlRGVyaXZhdGl2ZU5vZGVzKSA9PiB7XG4gICAgY29uc3Qgbm9kZXMgPSBzZWxlY3RvcigpO1xuXG4gICAgaWYgKCFub2Rlcy5sZW5ndGgpXG4gICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gW107XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGRlcml2YXRpdmVOb2RlcyA9IHBvcHVsYXRlRGVyaXZhdGl2ZU5vZGVzKG5vZGVzW2ldKTtcblxuICAgICAgICBpZiAoZGVyaXZhdGl2ZU5vZGVzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGRlcml2YXRpdmVOb2Rlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuaW5kZXhPZihkZXJpdmF0aXZlTm9kZXNbal0pIDwgMClcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goZGVyaXZhdGl2ZU5vZGVzW2pdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG5cbn0pKS5nZXRGdW5jdGlvbigpO1xuXG5hc3luYyBmdW5jdGlvbiBnZXRTbmFwc2hvdCAoZ2V0U2VsZWN0b3IsIGNhbGxzaXRlLCBTZWxlY3RvckJ1aWxkZXIpIHtcbiAgICBsZXQgbm9kZSAgICAgICA9IG51bGw7XG4gICAgY29uc3Qgc2VsZWN0b3IgPSBuZXcgU2VsZWN0b3JCdWlsZGVyKGdldFNlbGVjdG9yKCksIHsgbmVlZEVycm9yOiB0cnVlIH0sIHsgaW5zdGFudGlhdGlvbjogJ1NlbGVjdG9yJyB9KS5nZXRGdW5jdGlvbigpO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgbm9kZSA9IGF3YWl0IHNlbGVjdG9yKCk7XG4gICAgfVxuXG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBlcnIuY2FsbHNpdGUgPSBjYWxsc2l0ZTtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgIH1cblxuICAgIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBhc3NlcnRBZGRDdXN0b21ET01Qcm9wZXJ0aWVzT3B0aW9ucyAocHJvcGVydGllcykge1xuICAgIGFzc2VydFR5cGUoaXMubm9uTnVsbE9iamVjdCwgJ2FkZEN1c3RvbURPTVByb3BlcnRpZXMnLCAnXCJhZGRDdXN0b21ET01Qcm9wZXJ0aWVzXCIgb3B0aW9uJywgcHJvcGVydGllcyk7XG5cbiAgICBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKS5mb3JFYWNoKHByb3AgPT4ge1xuICAgICAgICBhc3NlcnRUeXBlKGlzLmZ1bmN0aW9uLCAnYWRkQ3VzdG9tRE9NUHJvcGVydGllcycsIGBDdXN0b20gRE9NIHByb3BlcnRpZXMgbWV0aG9kICcke3Byb3B9J2AsIHByb3BlcnRpZXNbcHJvcF0pO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBhc3NlcnRBZGRDdXN0b21NZXRob2RzIChwcm9wZXJ0aWVzLCBvcHRzKSB7XG4gICAgYXNzZXJ0VHlwZShpcy5ub25OdWxsT2JqZWN0LCAnYWRkQ3VzdG9tTWV0aG9kcycsICdcImFkZEN1c3RvbU1ldGhvZHNcIiBvcHRpb24nLCBwcm9wZXJ0aWVzKTtcblxuICAgIGlmIChvcHRzICE9PSB2b2lkIDApXG4gICAgICAgIGFzc2VydFR5cGUoaXMubm9uTnVsbE9iamVjdCwgJ2FkZEN1c3RvbU1ldGhvZHMnLCAnXCJhZGRDdXN0b21NZXRob2RzXCIgb3B0aW9uJywgb3B0cyk7XG5cbiAgICBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKS5mb3JFYWNoKHByb3AgPT4ge1xuICAgICAgICBhc3NlcnRUeXBlKGlzLmZ1bmN0aW9uLCAnYWRkQ3VzdG9tTWV0aG9kcycsIGBDdXN0b20gbWV0aG9kICcke3Byb3B9J2AsIHByb3BlcnRpZXNbcHJvcF0pO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBwcmVwYXJlQXBpRm5BcmdzIChmbk5hbWUsIC4uLmFyZ3MpIHtcbiAgICBhcmdzID0gYXJncy5tYXAoYXJnID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgcmV0dXJuIGAnJHthcmd9J2A7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgICAgcmV0dXJuICdbZnVuY3Rpb25dJztcbiAgICAgICAgcmV0dXJuIGFyZztcbiAgICB9KTtcbiAgICBhcmdzID0gYXJncy5qb2luKCcsICcpO1xuXG4gICAgcmV0dXJuIGAuJHtmbk5hbWV9KCR7YXJnc30pYDtcbn1cblxuZnVuY3Rpb24gZ2V0RGVyaXZhdGl2ZVNlbGVjdG9yQXJncyAob3B0aW9ucywgc2VsZWN0b3JGbiwgYXBpRm4sIGZpbHRlciwgYWRkaXRpb25hbERlcGVuZGVuY2llcykge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zLCB7IHNlbGVjdG9yRm4sIGFwaUZuLCBmaWx0ZXIsIGFkZGl0aW9uYWxEZXBlbmRlbmNpZXMgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZFNuYXBzaG90UHJvcGVydGllcyAob2JqLCBnZXRTZWxlY3RvciwgU2VsZWN0b3JCdWlsZGVyLCBwcm9wZXJ0aWVzKSB7XG4gICAgcHJvcGVydGllcy5mb3JFYWNoKHByb3AgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBwcm9wLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjYWxsc2l0ZSA9IGdldENhbGxzaXRlRm9yTWV0aG9kKCdnZXQnKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBSZUV4ZWN1dGFibGVQcm9taXNlLmZyb21Gbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgZ2V0U25hcHNob3QoZ2V0U2VsZWN0b3IsIGNhbGxzaXRlLCBTZWxlY3RvckJ1aWxkZXIpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzbmFwc2hvdFtwcm9wXTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDdXN0b21NZXRob2RzIChvYmosIGdldFNlbGVjdG9yLCBTZWxlY3RvckJ1aWxkZXIsIGN1c3RvbU1ldGhvZHMpIHtcbiAgICBjb25zdCBjdXN0b21NZXRob2RQcm9wcyA9IGN1c3RvbU1ldGhvZHMgPyBPYmplY3Qua2V5cyhjdXN0b21NZXRob2RzKSA6IFtdO1xuXG4gICAgY3VzdG9tTWV0aG9kUHJvcHMuZm9yRWFjaChwcm9wID0+IHtcbiAgICAgICAgY29uc3QgeyByZXR1cm5ET01Ob2RlcyA9IGZhbHNlLCBtZXRob2QgfSA9IGN1c3RvbU1ldGhvZHNbcHJvcF07XG5cbiAgICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0ge1xuICAgICAgICAgICAgY3VzdG9tTWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICBzZWxlY3RvcjogICAgIGdldFNlbGVjdG9yKClcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBjYWxsc2l0ZU5hbWVzID0geyBpbnN0YW50aWF0aW9uOiBwcm9wIH07XG5cbiAgICAgICAgaWYgKHJldHVybkRPTU5vZGVzKSB7XG4gICAgICAgICAgICBvYmpbcHJvcF0gPSAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdG9yRm4gPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVzID0gc2VsZWN0b3IoKTtcblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VzdG9tTWV0aG9kLmFwcGx5KGN1c3RvbU1ldGhvZCwgW25vZGVzXS5jb25jYXQoYXJncykpO1xuICAgICAgICAgICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGFwaUZuID0gcHJlcGFyZUFwaUZuQXJncyhwcm9wLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSAoKSA9PiB0cnVlO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgYWRkaXRpb25hbERlcGVuZGVuY2llcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgYXJncyxcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tTWV0aG9kOiBtZXRob2RcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZURlcml2YXRpdmVTZWxlY3RvcldpdGhGaWx0ZXIoeyBnZXRTZWxlY3RvciwgU2VsZWN0b3JCdWlsZGVyLCBzZWxlY3RvckZuLCBhcGlGbiwgZmlsdGVyLCBhZGRpdGlvbmFsRGVwZW5kZW5jaWVzIH0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG9ialtwcm9wXSA9IChuZXcgQ2xpZW50RnVuY3Rpb25CdWlsZGVyKCguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBub2RlID0gc2VsZWN0b3IoKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBjdXN0b21NZXRob2QuYXBwbHkoY3VzdG9tTWV0aG9kLCBbbm9kZV0uY29uY2F0KGFyZ3MpKTtcbiAgICAgICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICB9LCB7IGRlcGVuZGVuY2llcyB9LCBjYWxsc2l0ZU5hbWVzKSkuZ2V0RnVuY3Rpb24oKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBhZGRTbmFwc2hvdFByb3BlcnR5U2hvcnRoYW5kcyAoeyBvYmosIGdldFNlbGVjdG9yLCBTZWxlY3RvckJ1aWxkZXIsIGN1c3RvbURPTVByb3BlcnRpZXMsIGN1c3RvbU1ldGhvZHMgfSkge1xuICAgIGxldCBwcm9wZXJ0aWVzID0gU05BUFNIT1RfUFJPUEVSVElFUztcblxuICAgIGlmIChjdXN0b21ET01Qcm9wZXJ0aWVzKVxuICAgICAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcy5jb25jYXQoT2JqZWN0LmtleXMoY3VzdG9tRE9NUHJvcGVydGllcykpO1xuXG4gICAgYWRkU25hcHNob3RQcm9wZXJ0aWVzKG9iaiwgZ2V0U2VsZWN0b3IsIFNlbGVjdG9yQnVpbGRlciwgcHJvcGVydGllcyk7XG4gICAgYWRkQ3VzdG9tTWV0aG9kcyhvYmosIGdldFNlbGVjdG9yLCBTZWxlY3RvckJ1aWxkZXIsIGN1c3RvbU1ldGhvZHMpO1xuXG4gICAgb2JqLmdldFN0eWxlUHJvcGVydHkgPSBwcm9wID0+IHtcbiAgICAgICAgY29uc3QgY2FsbHNpdGUgPSBnZXRDYWxsc2l0ZUZvck1ldGhvZCgnZ2V0U3R5bGVQcm9wZXJ0eScpO1xuXG4gICAgICAgIHJldHVybiBSZUV4ZWN1dGFibGVQcm9taXNlLmZyb21Gbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IGdldFNuYXBzaG90KGdldFNlbGVjdG9yLCBjYWxsc2l0ZSwgU2VsZWN0b3JCdWlsZGVyKTtcblxuICAgICAgICAgICAgcmV0dXJuIHNuYXBzaG90LnN0eWxlID8gc25hcHNob3Quc3R5bGVbcHJvcF0gOiB2b2lkIDA7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBvYmouZ2V0QXR0cmlidXRlID0gYXR0ck5hbWUgPT4ge1xuICAgICAgICBjb25zdCBjYWxsc2l0ZSA9IGdldENhbGxzaXRlRm9yTWV0aG9kKCdnZXRBdHRyaWJ1dGUnKTtcblxuICAgICAgICByZXR1cm4gUmVFeGVjdXRhYmxlUHJvbWlzZS5mcm9tRm4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc25hcHNob3QgPSBhd2FpdCBnZXRTbmFwc2hvdChnZXRTZWxlY3RvciwgY2FsbHNpdGUsIFNlbGVjdG9yQnVpbGRlcik7XG5cbiAgICAgICAgICAgIHJldHVybiBzbmFwc2hvdC5hdHRyaWJ1dGVzID8gc25hcHNob3QuYXR0cmlidXRlc1thdHRyTmFtZV0gOiB2b2lkIDA7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBvYmouaGFzQXR0cmlidXRlID0gYXR0ck5hbWUgPT4ge1xuICAgICAgICBjb25zdCBjYWxsc2l0ZSA9IGdldENhbGxzaXRlRm9yTWV0aG9kKCdoYXNBdHRyaWJ1dGUnKTtcblxuICAgICAgICByZXR1cm4gUmVFeGVjdXRhYmxlUHJvbWlzZS5mcm9tRm4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc25hcHNob3QgPSBhd2FpdCBnZXRTbmFwc2hvdChnZXRTZWxlY3RvciwgY2FsbHNpdGUsIFNlbGVjdG9yQnVpbGRlcik7XG5cbiAgICAgICAgICAgIHJldHVybiBzbmFwc2hvdC5hdHRyaWJ1dGVzID8gc25hcHNob3QuYXR0cmlidXRlcy5oYXNPd25Qcm9wZXJ0eShhdHRyTmFtZSkgOiBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIG9iai5nZXRCb3VuZGluZ0NsaWVudFJlY3RQcm9wZXJ0eSA9IHByb3AgPT4ge1xuICAgICAgICBjb25zdCBjYWxsc2l0ZSA9IGdldENhbGxzaXRlRm9yTWV0aG9kKCdnZXRCb3VuZGluZ0NsaWVudFJlY3RQcm9wZXJ0eScpO1xuXG4gICAgICAgIHJldHVybiBSZUV4ZWN1dGFibGVQcm9taXNlLmZyb21Gbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IGdldFNuYXBzaG90KGdldFNlbGVjdG9yLCBjYWxsc2l0ZSwgU2VsZWN0b3JCdWlsZGVyKTtcblxuICAgICAgICAgICAgcmV0dXJuIHNuYXBzaG90LmJvdW5kaW5nQ2xpZW50UmVjdCA/IHNuYXBzaG90LmJvdW5kaW5nQ2xpZW50UmVjdFtwcm9wXSA6IHZvaWQgMDtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIG9iai5oYXNDbGFzcyA9IG5hbWUgPT4ge1xuICAgICAgICBjb25zdCBjYWxsc2l0ZSA9IGdldENhbGxzaXRlRm9yTWV0aG9kKCdoYXNDbGFzcycpO1xuXG4gICAgICAgIHJldHVybiBSZUV4ZWN1dGFibGVQcm9taXNlLmZyb21Gbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IGdldFNuYXBzaG90KGdldFNlbGVjdG9yLCBjYWxsc2l0ZSwgU2VsZWN0b3JCdWlsZGVyKTtcblxuICAgICAgICAgICAgcmV0dXJuIHNuYXBzaG90LmNsYXNzTmFtZXMgPyBzbmFwc2hvdC5jbGFzc05hbWVzLmluZGV4T2YobmFtZSkgPiAtMSA6IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVDb3VudGVyIChnZXRTZWxlY3RvciwgU2VsZWN0b3JCdWlsZGVyKSB7XG4gICAgY29uc3QgYnVpbGRlciAgPSBuZXcgU2VsZWN0b3JCdWlsZGVyKGdldFNlbGVjdG9yKCksIHsgY291bnRlck1vZGU6IHRydWUgfSwgeyBpbnN0YW50aWF0aW9uOiAnU2VsZWN0b3InIH0pO1xuICAgIGNvbnN0IGNvdW50ZXIgID0gYnVpbGRlci5nZXRGdW5jdGlvbigpO1xuICAgIGNvbnN0IGNhbGxzaXRlID0gZ2V0Q2FsbHNpdGVGb3JNZXRob2QoJ2dldCcpO1xuXG4gICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBjb3VudGVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBlcnIuY2FsbHNpdGUgPSBjYWxsc2l0ZTtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgIH07XG59XG5cbmZ1bmN0aW9uIGFkZENvdW50ZXJQcm9wZXJ0aWVzICh7IG9iaiwgZ2V0U2VsZWN0b3IsIFNlbGVjdG9yQnVpbGRlciB9KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgJ2NvdW50Jywge1xuICAgICAgICBnZXQ6ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvdW50ZXIgPSBjcmVhdGVDb3VudGVyKGdldFNlbGVjdG9yLCBTZWxlY3RvckJ1aWxkZXIpO1xuXG4gICAgICAgICAgICByZXR1cm4gUmVFeGVjdXRhYmxlUHJvbWlzZS5mcm9tRm4oKCkgPT4gY291bnRlcigpKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgJ2V4aXN0cycsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb3VudGVyID0gY3JlYXRlQ291bnRlcihnZXRTZWxlY3RvciwgU2VsZWN0b3JCdWlsZGVyKTtcblxuICAgICAgICAgICAgcmV0dXJuIFJlRXhlY3V0YWJsZVByb21pc2UuZnJvbUZuKGFzeW5jICgpID0+IGF3YWl0IGNvdW50ZXIoKSA+IDApO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRGaWx0ZXJUb0NsaWVudEZ1bmN0aW9uSWZOZWNlc3NhcnkgKGNhbGxzaXRlTmFtZSwgZmlsdGVyLCBkZXBlbmRlbmNpZXMpIHtcbiAgICBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjb25zdCBidWlsZGVyID0gZmlsdGVyW2NsaWVudEZ1bmN0aW9uQnVpbGRlclN5bWJvbF07XG4gICAgICAgIGNvbnN0IGZuICAgICAgPSBidWlsZGVyID8gYnVpbGRlci5mbiA6IGZpbHRlcjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGJ1aWxkZXIgPyBhc3NpZ24oe30sIGJ1aWxkZXIub3B0aW9ucywgeyBkZXBlbmRlbmNpZXMgfSkgOiB7IGRlcGVuZGVuY2llcyB9O1xuXG4gICAgICAgIHJldHVybiAobmV3IENsaWVudEZ1bmN0aW9uQnVpbGRlcihmbiwgb3B0aW9ucywgeyBpbnN0YW50aWF0aW9uOiBjYWxsc2l0ZU5hbWUgfSkpLmdldEZ1bmN0aW9uKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlcjtcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVyaXZhdGl2ZVNlbGVjdG9yV2l0aEZpbHRlciAoeyBnZXRTZWxlY3RvciwgU2VsZWN0b3JCdWlsZGVyLCBzZWxlY3RvckZuLCBhcGlGbiwgZmlsdGVyLCBhZGRpdGlvbmFsRGVwZW5kZW5jaWVzIH0pIHtcbiAgICBjb25zdCBjb2xsZWN0aW9uTW9kZVNlbGVjdG9yQnVpbGRlciA9IG5ldyBTZWxlY3RvckJ1aWxkZXIoZ2V0U2VsZWN0b3IoKSwgeyBjb2xsZWN0aW9uTW9kZTogdHJ1ZSB9KTtcbiAgICBjb25zdCBjdXN0b21ET01Qcm9wZXJ0aWVzICAgICAgICAgICA9IGNvbGxlY3Rpb25Nb2RlU2VsZWN0b3JCdWlsZGVyLm9wdGlvbnMuY3VzdG9tRE9NUHJvcGVydGllcztcbiAgICBjb25zdCBjdXN0b21NZXRob2RzICAgICAgICAgICAgICAgICA9IGNvbGxlY3Rpb25Nb2RlU2VsZWN0b3JCdWlsZGVyLm9wdGlvbnMuY3VzdG9tTWV0aG9kcztcblxuICAgIGxldCBkZXBlbmRlbmNpZXMgPSB7XG4gICAgICAgIHNlbGVjdG9yOiAgICBjb2xsZWN0aW9uTW9kZVNlbGVjdG9yQnVpbGRlci5nZXRGdW5jdGlvbigpLFxuICAgICAgICBmaWx0ZXI6ICAgICAgZmlsdGVyLFxuICAgICAgICBmaWx0ZXJOb2RlczogZmlsdGVyTm9kZXNcbiAgICB9O1xuXG4gICAgY29uc3QgeyBib3VuZFRlc3RSdW4sIHRpbWVvdXQsIHZpc2liaWxpdHlDaGVjaywgYXBpRm5DaGFpbiB9ID0gY29sbGVjdGlvbk1vZGVTZWxlY3RvckJ1aWxkZXIub3B0aW9ucztcblxuICAgIGRlcGVuZGVuY2llcyA9IGFzc2lnbihkZXBlbmRlbmNpZXMsIGFkZGl0aW9uYWxEZXBlbmRlbmNpZXMpO1xuXG4gICAgY29uc3QgYnVpbGRlciA9IG5ldyBTZWxlY3RvckJ1aWxkZXIoc2VsZWN0b3JGbiwge1xuICAgICAgICBkZXBlbmRlbmNpZXMsXG4gICAgICAgIGN1c3RvbURPTVByb3BlcnRpZXMsXG4gICAgICAgIGN1c3RvbU1ldGhvZHMsXG4gICAgICAgIGJvdW5kVGVzdFJ1bixcbiAgICAgICAgdGltZW91dCxcbiAgICAgICAgdmlzaWJpbGl0eUNoZWNrLFxuICAgICAgICBhcGlGbkNoYWluLFxuICAgICAgICBhcGlGblxuICAgIH0sIHsgaW5zdGFudGlhdGlvbjogJ1NlbGVjdG9yJyB9KTtcblxuICAgIHJldHVybiBidWlsZGVyLmdldEZ1bmN0aW9uKCk7XG59XG5cbmNvbnN0IGZpbHRlckJ5VGV4dCA9IGNvbnZlcnRGaWx0ZXJUb0NsaWVudEZ1bmN0aW9uSWZOZWNlc3NhcnkoJ2ZpbHRlcicsIHNlbGVjdG9yVGV4dEZpbHRlcik7XG5jb25zdCBmaWx0ZXJCeUF0dHIgPSBjb252ZXJ0RmlsdGVyVG9DbGllbnRGdW5jdGlvbklmTmVjZXNzYXJ5KCdmaWx0ZXInLCBzZWxlY3RvckF0dHJpYnV0ZUZpbHRlcik7XG5cbmZ1bmN0aW9uIGVuc3VyZVJlZ0V4cENvbnRleHQgKHN0cikge1xuICAgIC8vIE5PVEU6IGlmIGEgcmVnZXhwIGlzIGNyZWF0ZWQgaW4gYSBzZXBhcmF0ZSBjb250ZXh0ICh2aWEgdGhlICd2bScgbW9kdWxlKSB3ZVxuICAgIC8vIHNob3VsZCB3cmFwIGl0IHdpdGggbmV3IFJlZ0V4cCgpIHRvIG1ha2UgdGhlIGBpbnN0YW5jZW9mIFJlZ0V4cGAgY2hlY2sgc3VjY2Vzc2Z1bC5cbiAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycgJiYgIShzdHIgaW5zdGFuY2VvZiBSZWdFeHApKVxuICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cChzdHIpO1xuXG4gICAgcmV0dXJuIHN0cjtcbn1cblxuZnVuY3Rpb24gYWRkRmlsdGVyTWV0aG9kcyAob3B0aW9ucykge1xuICAgIGNvbnN0IHsgb2JqLCBnZXRTZWxlY3RvciwgU2VsZWN0b3JCdWlsZGVyIH0gPSBvcHRpb25zO1xuXG4gICAgb2JqLm50aCA9IGluZGV4ID0+IHtcbiAgICAgICAgYXNzZXJ0VHlwZShpcy5udW1iZXIsICdudGgnLCAnXCJpbmRleFwiIGFyZ3VtZW50JywgaW5kZXgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUZuICAgPSBwcmVwYXJlQXBpRm5BcmdzKCdudGgnLCBpbmRleCk7XG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgU2VsZWN0b3JCdWlsZGVyKGdldFNlbGVjdG9yKCksIHsgaW5kZXgsIGFwaUZuIH0sIHsgaW5zdGFudGlhdGlvbjogJ1NlbGVjdG9yJyB9KTtcblxuICAgICAgICByZXR1cm4gYnVpbGRlci5nZXRGdW5jdGlvbigpO1xuICAgIH07XG5cbiAgICBvYmoud2l0aFRleHQgPSB0ZXh0ID0+IHtcbiAgICAgICAgYXNzZXJ0VHlwZShbaXMuc3RyaW5nLCBpcy5yZWdFeHBdLCAnd2l0aFRleHQnLCAnXCJ0ZXh0XCIgYXJndW1lbnQnLCB0ZXh0KTtcblxuICAgICAgICBjb25zdCBhcGlGbiA9IHByZXBhcmVBcGlGbkFyZ3MoJ3dpdGhUZXh0JywgdGV4dCk7XG5cbiAgICAgICAgdGV4dCA9IGVuc3VyZVJlZ0V4cENvbnRleHQodGV4dCk7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0b3JGbiA9ICgpID0+IHtcbiAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICBjb25zdCBub2RlcyA9IHNlbGVjdG9yKCk7XG5cbiAgICAgICAgICAgIGlmICghbm9kZXMubGVuZ3RoKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICByZXR1cm4gZmlsdGVyTm9kZXMobm9kZXMsIGZpbHRlciwgZG9jdW1lbnQsIHZvaWQgMCwgdGV4dFJlKTtcbiAgICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tdW5kZWYgKi9cbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBhcmdzID0gZ2V0RGVyaXZhdGl2ZVNlbGVjdG9yQXJncyhvcHRpb25zLCBzZWxlY3RvckZuLCBhcGlGbiwgZmlsdGVyQnlUZXh0LCB7IHRleHRSZTogbWFrZVJlZ0V4cCh0ZXh0KSB9KTtcblxuICAgICAgICByZXR1cm4gY3JlYXRlRGVyaXZhdGl2ZVNlbGVjdG9yV2l0aEZpbHRlcihhcmdzKTtcbiAgICB9O1xuXG4gICAgb2JqLndpdGhFeGFjdFRleHQgPSB0ZXh0ID0+IHtcbiAgICAgICAgYXNzZXJ0VHlwZShpcy5zdHJpbmcsICd3aXRoRXhhY3RUZXh0JywgJ1widGV4dFwiIGFyZ3VtZW50JywgdGV4dCk7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0b3JGbiA9ICgpID0+IHtcbiAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICBjb25zdCBub2RlcyA9IHNlbGVjdG9yKCk7XG5cbiAgICAgICAgICAgIGlmICghbm9kZXMubGVuZ3RoKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICByZXR1cm4gZmlsdGVyTm9kZXMobm9kZXMsIGZpbHRlciwgZG9jdW1lbnQsIHZvaWQgMCwgZXhhY3RUZXh0KTtcbiAgICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tdW5kZWYgKi9cbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBhcGlGbiA9IHByZXBhcmVBcGlGbkFyZ3MoJ3dpdGhFeGFjdFRleHQnLCB0ZXh0KTtcbiAgICAgICAgY29uc3QgYXJncyAgPSBnZXREZXJpdmF0aXZlU2VsZWN0b3JBcmdzKG9wdGlvbnMsIHNlbGVjdG9yRm4sIGFwaUZuLCBmaWx0ZXJCeVRleHQsIHsgZXhhY3RUZXh0OiB0ZXh0IH0pO1xuXG4gICAgICAgIHJldHVybiBjcmVhdGVEZXJpdmF0aXZlU2VsZWN0b3JXaXRoRmlsdGVyKGFyZ3MpO1xuICAgIH07XG5cbiAgICBvYmoud2l0aEF0dHJpYnV0ZSA9IChhdHRyTmFtZSwgYXR0clZhbHVlKSA9PiB7XG4gICAgICAgIGFzc2VydFR5cGUoW2lzLnN0cmluZywgaXMucmVnRXhwXSwgJ3dpdGhBdHRyaWJ1dGUnLCAnXCJhdHRyTmFtZVwiIGFyZ3VtZW50JywgYXR0ck5hbWUpO1xuXG4gICAgICAgIGNvbnN0IGFwaUZuID0gcHJlcGFyZUFwaUZuQXJncygnd2l0aEF0dHJpYnV0ZScsIGF0dHJOYW1lLCBhdHRyVmFsdWUpO1xuXG4gICAgICAgIGF0dHJOYW1lID0gZW5zdXJlUmVnRXhwQ29udGV4dChhdHRyTmFtZSk7XG5cbiAgICAgICAgaWYgKGF0dHJWYWx1ZSAhPT0gdm9pZCAwKSB7XG4gICAgICAgICAgICBhc3NlcnRUeXBlKFtpcy5zdHJpbmcsIGlzLnJlZ0V4cF0sICd3aXRoQXR0cmlidXRlJywgJ1wiYXR0clZhbHVlXCIgYXJndW1lbnQnLCBhdHRyVmFsdWUpO1xuICAgICAgICAgICAgYXR0clZhbHVlID0gZW5zdXJlUmVnRXhwQ29udGV4dChhdHRyVmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0b3JGbiA9ICgpID0+IHtcbiAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICBjb25zdCBub2RlcyA9IHNlbGVjdG9yKCk7XG5cbiAgICAgICAgICAgIGlmICghbm9kZXMubGVuZ3RoKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICByZXR1cm4gZmlsdGVyTm9kZXMobm9kZXMsIGZpbHRlciwgZG9jdW1lbnQsIHZvaWQgMCwgYXR0ck5hbWUsIGF0dHJWYWx1ZSk7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVuZGVmICovXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgYXJncyA9IGdldERlcml2YXRpdmVTZWxlY3RvckFyZ3Mob3B0aW9ucywgc2VsZWN0b3JGbiwgYXBpRm4sIGZpbHRlckJ5QXR0ciwge1xuICAgICAgICAgICAgYXR0ck5hbWUsXG4gICAgICAgICAgICBhdHRyVmFsdWVcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZURlcml2YXRpdmVTZWxlY3RvcldpdGhGaWx0ZXIoYXJncyk7XG4gICAgfTtcblxuICAgIG9iai5maWx0ZXIgPSAoZmlsdGVyLCBkZXBlbmRlbmNpZXMpID0+IHtcbiAgICAgICAgYXNzZXJ0VHlwZShbaXMuc3RyaW5nLCBpcy5mdW5jdGlvbl0sICdmaWx0ZXInLCAnXCJmaWx0ZXJcIiBhcmd1bWVudCcsIGZpbHRlcik7XG5cbiAgICAgICAgY29uc3QgYXBpRm4gPSBwcmVwYXJlQXBpRm5BcmdzKCdmaWx0ZXInLCBmaWx0ZXIpO1xuXG4gICAgICAgIGZpbHRlciA9IGNvbnZlcnRGaWx0ZXJUb0NsaWVudEZ1bmN0aW9uSWZOZWNlc3NhcnkoJ2ZpbHRlcicsIGZpbHRlciwgZGVwZW5kZW5jaWVzKTtcblxuICAgICAgICBjb25zdCBzZWxlY3RvckZuID0gKCkgPT4ge1xuICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cbiAgICAgICAgICAgIGNvbnN0IG5vZGVzID0gc2VsZWN0b3IoKTtcblxuICAgICAgICAgICAgaWYgKCFub2Rlcy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgICAgIHJldHVybiBmaWx0ZXJOb2Rlcyhub2RlcywgZmlsdGVyLCBkb2N1bWVudCwgdm9pZCAwKTtcbiAgICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tdW5kZWYgKi9cbiAgICAgICAgfTtcblxuXG4gICAgICAgIGNvbnN0IGFyZ3MgPSBnZXREZXJpdmF0aXZlU2VsZWN0b3JBcmdzKG9wdGlvbnMsIHNlbGVjdG9yRm4sIGFwaUZuLCBmaWx0ZXIpO1xuXG4gICAgICAgIHJldHVybiBjcmVhdGVEZXJpdmF0aXZlU2VsZWN0b3JXaXRoRmlsdGVyKGFyZ3MpO1xuICAgIH07XG5cbiAgICBvYmouZmlsdGVyVmlzaWJsZSA9ICgpID0+IHtcbiAgICAgICAgY29uc3QgYXBpRm4gICA9IHByZXBhcmVBcGlGbkFyZ3MoJ2ZpbHRlclZpc2libGUnKTtcbiAgICAgICAgY29uc3QgYnVpbGRlciA9IG5ldyBTZWxlY3RvckJ1aWxkZXIoZ2V0U2VsZWN0b3IoKSwgeyBmaWx0ZXJWaXNpYmxlOiB0cnVlLCBhcGlGbiB9LCB7IGluc3RhbnRpYXRpb246ICdTZWxlY3RvcicgfSk7XG5cbiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuZ2V0RnVuY3Rpb24oKTtcbiAgICB9O1xuXG4gICAgb2JqLmZpbHRlckhpZGRlbiA9ICgpID0+IHtcbiAgICAgICAgY29uc3QgYXBpRm4gICA9IHByZXBhcmVBcGlGbkFyZ3MoJ2ZpbHRlckhpZGRlbicpO1xuICAgICAgICBjb25zdCBidWlsZGVyID0gbmV3IFNlbGVjdG9yQnVpbGRlcihnZXRTZWxlY3RvcigpLCB7IGZpbHRlckhpZGRlbjogdHJ1ZSwgYXBpRm4gfSwgeyBpbnN0YW50aWF0aW9uOiAnU2VsZWN0b3InIH0pO1xuXG4gICAgICAgIHJldHVybiBidWlsZGVyLmdldEZ1bmN0aW9uKCk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gYWRkQ3VzdG9tRE9NUHJvcGVydGllc01ldGhvZCAoeyBvYmosIGdldFNlbGVjdG9yLCBTZWxlY3RvckJ1aWxkZXIgfSkge1xuICAgIG9iai5hZGRDdXN0b21ET01Qcm9wZXJ0aWVzID0gY3VzdG9tRE9NUHJvcGVydGllcyA9PiB7XG4gICAgICAgIGFzc2VydEFkZEN1c3RvbURPTVByb3BlcnRpZXNPcHRpb25zKGN1c3RvbURPTVByb3BlcnRpZXMpO1xuXG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgU2VsZWN0b3JCdWlsZGVyKGdldFNlbGVjdG9yKCksIHsgY3VzdG9tRE9NUHJvcGVydGllcyB9LCB7IGluc3RhbnRpYXRpb246ICdTZWxlY3RvcicgfSk7XG5cbiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuZ2V0RnVuY3Rpb24oKTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBhZGRDdXN0b21NZXRob2RzTWV0aG9kICh7IG9iaiwgZ2V0U2VsZWN0b3IsIFNlbGVjdG9yQnVpbGRlciB9KSB7XG4gICAgb2JqLmFkZEN1c3RvbU1ldGhvZHMgPSBmdW5jdGlvbiAobWV0aG9kcywgb3B0cykge1xuICAgICAgICBhc3NlcnRBZGRDdXN0b21NZXRob2RzKG1ldGhvZHMsIG9wdHMpO1xuXG4gICAgICAgIGNvbnN0IGN1c3RvbU1ldGhvZHMgPSB7fTtcblxuICAgICAgICBPYmplY3Qua2V5cyhtZXRob2RzKS5mb3JFYWNoKG1ldGhvZE5hbWUgPT4ge1xuICAgICAgICAgICAgY3VzdG9tTWV0aG9kc1ttZXRob2ROYW1lXSA9IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICAgICAgICAgbWV0aG9kc1ttZXRob2ROYW1lXSxcbiAgICAgICAgICAgICAgICByZXR1cm5ET01Ob2Rlczogb3B0cyAmJiAhIW9wdHMucmV0dXJuRE9NTm9kZXNcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgU2VsZWN0b3JCdWlsZGVyKGdldFNlbGVjdG9yKCksIHsgY3VzdG9tTWV0aG9kcyB9LCB7IGluc3RhbnRpYXRpb246ICdTZWxlY3RvcicgfSk7XG5cbiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuZ2V0RnVuY3Rpb24oKTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBhZGRIaWVyYXJjaGljYWxTZWxlY3RvcnMgKG9wdGlvbnMpIHtcbiAgICBjb25zdCB7IG9iaiB9ID0gb3B0aW9ucztcblxuICAgIC8vIEZpbmRcbiAgICBvYmouZmluZCA9IChmaWx0ZXIsIGRlcGVuZGVuY2llcykgPT4ge1xuICAgICAgICBhc3NlcnRUeXBlKFtpcy5zdHJpbmcsIGlzLmZ1bmN0aW9uXSwgJ2ZpbmQnLCAnXCJmaWx0ZXJcIiBhcmd1bWVudCcsIGZpbHRlcik7XG5cbiAgICAgICAgY29uc3QgYXBpRm4gPSBwcmVwYXJlQXBpRm5BcmdzKCdmaW5kJywgZmlsdGVyKTtcblxuICAgICAgICBmaWx0ZXIgPSBjb252ZXJ0RmlsdGVyVG9DbGllbnRGdW5jdGlvbklmTmVjZXNzYXJ5KCdmaW5kJywgZmlsdGVyLCBkZXBlbmRlbmNpZXMpO1xuXG4gICAgICAgIGNvbnN0IHNlbGVjdG9yRm4gPSAoKSA9PiB7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZiAqL1xuICAgICAgICAgICAgcmV0dXJuIGV4cGFuZFNlbGVjdG9yUmVzdWx0cyhzZWxlY3Rvciwgbm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmaWx0ZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlb2Ygbm9kZS5xdWVyeVNlbGVjdG9yQWxsID09PSAnZnVuY3Rpb24nID9cbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUucXVlcnlTZWxlY3RvckFsbChmaWx0ZXIpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgdmlzaXROb2RlID0gY3VycmVudE5vZGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjbkxlbmd0aCA9IGN1cnJlbnROb2RlLmNoaWxkTm9kZXMubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY25MZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hpbGQgPSBjdXJyZW50Tm9kZS5jaGlsZE5vZGVzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goY2hpbGQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB2aXNpdE5vZGUoY2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIHZpc2l0Tm9kZShub2RlKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXJOb2RlcyhyZXN1bHRzLCBmaWx0ZXIsIG51bGwsIG5vZGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVuZGVmICovXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgYXJncyA9IGdldERlcml2YXRpdmVTZWxlY3RvckFyZ3Mob3B0aW9ucywgc2VsZWN0b3JGbiwgYXBpRm4sIGZpbHRlciwgeyBleHBhbmRTZWxlY3RvclJlc3VsdHMgfSk7XG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZURlcml2YXRpdmVTZWxlY3RvcldpdGhGaWx0ZXIoYXJncyk7XG4gICAgfTtcblxuICAgIC8vIFBhcmVudFxuICAgIG9iai5wYXJlbnQgPSAoZmlsdGVyLCBkZXBlbmRlbmNpZXMpID0+IHtcbiAgICAgICAgaWYgKGZpbHRlciAhPT0gdm9pZCAwKVxuICAgICAgICAgICAgYXNzZXJ0VHlwZShbaXMuc3RyaW5nLCBpcy5mdW5jdGlvbiwgaXMubnVtYmVyXSwgJ3BhcmVudCcsICdcImZpbHRlclwiIGFyZ3VtZW50JywgZmlsdGVyKTtcblxuICAgICAgICBjb25zdCBhcGlGbiA9IHByZXBhcmVBcGlGbkFyZ3MoJ3BhcmVudCcsIGZpbHRlcik7XG5cbiAgICAgICAgZmlsdGVyID0gY29udmVydEZpbHRlclRvQ2xpZW50RnVuY3Rpb25JZk5lY2Vzc2FyeSgnZmluZCcsIGZpbHRlciwgZGVwZW5kZW5jaWVzKTtcblxuICAgICAgICBjb25zdCBzZWxlY3RvckZuID0gKCkgPT4ge1xuICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cbiAgICAgICAgICAgIHJldHVybiBleHBhbmRTZWxlY3RvclJlc3VsdHMoc2VsZWN0b3IsIG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmVudHMgPSBbXTtcblxuICAgICAgICAgICAgICAgIGZvciAobGV0IHBhcmVudCA9IG5vZGUucGFyZW50Tm9kZTsgcGFyZW50OyBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZSlcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50cy5wdXNoKHBhcmVudCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyICE9PSB2b2lkIDAgPyBmaWx0ZXJOb2RlcyhwYXJlbnRzLCBmaWx0ZXIsIGRvY3VtZW50LCBub2RlKSA6IHBhcmVudHM7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tdW5kZWYgKi9cbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBhcmdzID0gZ2V0RGVyaXZhdGl2ZVNlbGVjdG9yQXJncyhvcHRpb25zLCBzZWxlY3RvckZuLCBhcGlGbiwgZmlsdGVyLCB7IGV4cGFuZFNlbGVjdG9yUmVzdWx0cyB9KTtcblxuICAgICAgICByZXR1cm4gY3JlYXRlRGVyaXZhdGl2ZVNlbGVjdG9yV2l0aEZpbHRlcihhcmdzKTtcbiAgICB9O1xuXG4gICAgLy8gQ2hpbGRcbiAgICBvYmouY2hpbGQgPSAoZmlsdGVyLCBkZXBlbmRlbmNpZXMpID0+IHtcbiAgICAgICAgaWYgKGZpbHRlciAhPT0gdm9pZCAwKVxuICAgICAgICAgICAgYXNzZXJ0VHlwZShbaXMuc3RyaW5nLCBpcy5mdW5jdGlvbiwgaXMubnVtYmVyXSwgJ2NoaWxkJywgJ1wiZmlsdGVyXCIgYXJndW1lbnQnLCBmaWx0ZXIpO1xuXG4gICAgICAgIGNvbnN0IGFwaUZuID0gcHJlcGFyZUFwaUZuQXJncygnY2hpbGQnLCBmaWx0ZXIpO1xuXG4gICAgICAgIGZpbHRlciA9IGNvbnZlcnRGaWx0ZXJUb0NsaWVudEZ1bmN0aW9uSWZOZWNlc3NhcnkoJ2ZpbmQnLCBmaWx0ZXIsIGRlcGVuZGVuY2llcyk7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0b3JGbiA9ICgpID0+IHtcbiAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICByZXR1cm4gZXhwYW5kU2VsZWN0b3JSZXN1bHRzKHNlbGVjdG9yLCBub2RlID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZEVsZW1lbnRzID0gW107XG4gICAgICAgICAgICAgICAgY29uc3QgY25MZW5ndGggICAgICA9IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGg7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNuTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hpbGQgPSBub2RlLmNoaWxkTm9kZXNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSAxKVxuICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRFbGVtZW50cy5wdXNoKGNoaWxkKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyICE9PSB2b2lkIDAgPyBmaWx0ZXJOb2RlcyhjaGlsZEVsZW1lbnRzLCBmaWx0ZXIsIG5vZGUsIG5vZGUpIDogY2hpbGRFbGVtZW50cztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby11bmRlZiAqL1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGFyZ3MgPSBnZXREZXJpdmF0aXZlU2VsZWN0b3JBcmdzKG9wdGlvbnMsIHNlbGVjdG9yRm4sIGFwaUZuLCBmaWx0ZXIsIHsgZXhwYW5kU2VsZWN0b3JSZXN1bHRzIH0pO1xuXG4gICAgICAgIHJldHVybiBjcmVhdGVEZXJpdmF0aXZlU2VsZWN0b3JXaXRoRmlsdGVyKGFyZ3MpO1xuICAgIH07XG5cbiAgICAvLyBTaWJsaW5nXG4gICAgb2JqLnNpYmxpbmcgPSAoZmlsdGVyLCBkZXBlbmRlbmNpZXMpID0+IHtcbiAgICAgICAgaWYgKGZpbHRlciAhPT0gdm9pZCAwKVxuICAgICAgICAgICAgYXNzZXJ0VHlwZShbaXMuc3RyaW5nLCBpcy5mdW5jdGlvbiwgaXMubnVtYmVyXSwgJ3NpYmxpbmcnLCAnXCJmaWx0ZXJcIiBhcmd1bWVudCcsIGZpbHRlcik7XG5cbiAgICAgICAgY29uc3QgYXBpRm4gPSBwcmVwYXJlQXBpRm5BcmdzKCdzaWJsaW5nJywgZmlsdGVyKTtcblxuICAgICAgICBmaWx0ZXIgPSBjb252ZXJ0RmlsdGVyVG9DbGllbnRGdW5jdGlvbklmTmVjZXNzYXJ5KCdmaW5kJywgZmlsdGVyLCBkZXBlbmRlbmNpZXMpO1xuXG4gICAgICAgIGNvbnN0IHNlbGVjdG9yRm4gPSAoKSA9PiB7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZiAqL1xuICAgICAgICAgICAgcmV0dXJuIGV4cGFuZFNlbGVjdG9yUmVzdWx0cyhzZWxlY3Rvciwgbm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFwYXJlbnQpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICAgICAgY29uc3Qgc2libGluZ3MgPSBbXTtcbiAgICAgICAgICAgICAgICBjb25zdCBjbkxlbmd0aCA9IHBhcmVudC5jaGlsZE5vZGVzLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY25MZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZCA9IHBhcmVudC5jaGlsZE5vZGVzW2ldO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PT0gMSAmJiBjaGlsZCAhPT0gbm9kZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpYmxpbmdzLnB1c2goY2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXIgIT09IHZvaWQgMCA/IGZpbHRlck5vZGVzKHNpYmxpbmdzLCBmaWx0ZXIsIHBhcmVudCwgbm9kZSkgOiBzaWJsaW5ncztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby11bmRlZiAqL1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGFyZ3MgPSBnZXREZXJpdmF0aXZlU2VsZWN0b3JBcmdzKG9wdGlvbnMsIHNlbGVjdG9yRm4sIGFwaUZuLCBmaWx0ZXIsIHsgZXhwYW5kU2VsZWN0b3JSZXN1bHRzIH0pO1xuXG4gICAgICAgIHJldHVybiBjcmVhdGVEZXJpdmF0aXZlU2VsZWN0b3JXaXRoRmlsdGVyKGFyZ3MpO1xuICAgIH07XG5cbiAgICAvLyBOZXh0IHNpYmxpbmdcbiAgICBvYmoubmV4dFNpYmxpbmcgPSAoZmlsdGVyLCBkZXBlbmRlbmNpZXMpID0+IHtcbiAgICAgICAgaWYgKGZpbHRlciAhPT0gdm9pZCAwKVxuICAgICAgICAgICAgYXNzZXJ0VHlwZShbaXMuc3RyaW5nLCBpcy5mdW5jdGlvbiwgaXMubnVtYmVyXSwgJ25leHRTaWJsaW5nJywgJ1wiZmlsdGVyXCIgYXJndW1lbnQnLCBmaWx0ZXIpO1xuXG4gICAgICAgIGNvbnN0IGFwaUZuID0gcHJlcGFyZUFwaUZuQXJncygnbmV4dFNpYmxpbmcnLCBmaWx0ZXIpO1xuXG4gICAgICAgIGZpbHRlciA9IGNvbnZlcnRGaWx0ZXJUb0NsaWVudEZ1bmN0aW9uSWZOZWNlc3NhcnkoJ2ZpbmQnLCBmaWx0ZXIsIGRlcGVuZGVuY2llcyk7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0b3JGbiA9ICgpID0+IHtcbiAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICByZXR1cm4gZXhwYW5kU2VsZWN0b3JSZXN1bHRzKHNlbGVjdG9yLCBub2RlID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXBhcmVudClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzaWJsaW5ncyA9IFtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNuTGVuZ3RoID0gcGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGxldCBhZnRlck5vZGUgID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNuTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hpbGQgPSBwYXJlbnQuY2hpbGROb2Rlc1tpXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQgPT09IG5vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICBhZnRlck5vZGUgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGFmdGVyTm9kZSAmJiBjaGlsZC5ub2RlVHlwZSA9PT0gMSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpYmxpbmdzLnB1c2goY2hpbGQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXIgIT09IHZvaWQgMCA/IGZpbHRlck5vZGVzKHNpYmxpbmdzLCBmaWx0ZXIsIHBhcmVudCwgbm9kZSkgOiBzaWJsaW5ncztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby11bmRlZiAqL1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGFyZ3MgPSBnZXREZXJpdmF0aXZlU2VsZWN0b3JBcmdzKG9wdGlvbnMsIHNlbGVjdG9yRm4sIGFwaUZuLCBmaWx0ZXIsIHsgZXhwYW5kU2VsZWN0b3JSZXN1bHRzIH0pO1xuXG4gICAgICAgIHJldHVybiBjcmVhdGVEZXJpdmF0aXZlU2VsZWN0b3JXaXRoRmlsdGVyKGFyZ3MpO1xuICAgIH07XG5cbiAgICAvLyBQcmV2IHNpYmxpbmdcbiAgICBvYmoucHJldlNpYmxpbmcgPSAoZmlsdGVyLCBkZXBlbmRlbmNpZXMpID0+IHtcbiAgICAgICAgaWYgKGZpbHRlciAhPT0gdm9pZCAwKVxuICAgICAgICAgICAgYXNzZXJ0VHlwZShbaXMuc3RyaW5nLCBpcy5mdW5jdGlvbiwgaXMubnVtYmVyXSwgJ3ByZXZTaWJsaW5nJywgJ1wiZmlsdGVyXCIgYXJndW1lbnQnLCBmaWx0ZXIpO1xuXG4gICAgICAgIGNvbnN0IGFwaUZuID0gcHJlcGFyZUFwaUZuQXJncygncHJldlNpYmxpbmcnLCBmaWx0ZXIpO1xuXG4gICAgICAgIGZpbHRlciA9IGNvbnZlcnRGaWx0ZXJUb0NsaWVudEZ1bmN0aW9uSWZOZWNlc3NhcnkoJ2ZpbmQnLCBmaWx0ZXIsIGRlcGVuZGVuY2llcyk7XG5cbiAgICAgICAgY29uc3Qgc2VsZWN0b3JGbiA9ICgpID0+IHtcbiAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgICAgICByZXR1cm4gZXhwYW5kU2VsZWN0b3JSZXN1bHRzKHNlbGVjdG9yLCBub2RlID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXBhcmVudClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzaWJsaW5ncyA9IFtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNuTGVuZ3RoID0gcGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjbkxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gcGFyZW50LmNoaWxkTm9kZXNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkID09PSBub2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSAxKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChjaGlsZCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpbHRlciAhPT0gdm9pZCAwID8gZmlsdGVyTm9kZXMoc2libGluZ3MsIGZpbHRlciwgcGFyZW50LCBub2RlKSA6IHNpYmxpbmdzO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVuZGVmICovXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgYXJncyA9IGdldERlcml2YXRpdmVTZWxlY3RvckFyZ3Mob3B0aW9ucywgc2VsZWN0b3JGbiwgYXBpRm4sIGZpbHRlciwgeyBleHBhbmRTZWxlY3RvclJlc3VsdHMgfSk7XG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZURlcml2YXRpdmVTZWxlY3RvcldpdGhGaWx0ZXIoYXJncyk7XG4gICAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEFQSSAoc2VsZWN0b3IsIGdldFNlbGVjdG9yLCBTZWxlY3RvckJ1aWxkZXIsIGN1c3RvbURPTVByb3BlcnRpZXMsIGN1c3RvbU1ldGhvZHMpIHtcbiAgICBjb25zdCBvcHRpb25zID0geyBvYmo6IHNlbGVjdG9yLCBnZXRTZWxlY3RvciwgU2VsZWN0b3JCdWlsZGVyLCBjdXN0b21ET01Qcm9wZXJ0aWVzLCBjdXN0b21NZXRob2RzIH07XG5cbiAgICBhZGRGaWx0ZXJNZXRob2RzKG9wdGlvbnMpO1xuICAgIGFkZEhpZXJhcmNoaWNhbFNlbGVjdG9ycyhvcHRpb25zKTtcbiAgICBhZGRTbmFwc2hvdFByb3BlcnR5U2hvcnRoYW5kcyhvcHRpb25zKTtcbiAgICBhZGRDdXN0b21ET01Qcm9wZXJ0aWVzTWV0aG9kKG9wdGlvbnMpO1xuICAgIGFkZEN1c3RvbU1ldGhvZHNNZXRob2Qob3B0aW9ucyk7XG4gICAgYWRkQ291bnRlclByb3BlcnRpZXMob3B0aW9ucyk7XG59XG4iXX0= diff --git a/lib/client-functions/selectors/create-snapshot-methods.js b/lib/client-functions/selectors/create-snapshot-methods.js new file mode 100644 index 00000000..e2709e04 --- /dev/null +++ b/lib/client-functions/selectors/create-snapshot-methods.js @@ -0,0 +1,17 @@ +"use strict"; + +exports.__esModule = true; +exports.default = createSnapshotMethods; +function createSnapshotMethods(snapshot) { + const isElementSnapshot = !!snapshot.tagName; + + if (isElementSnapshot) { + snapshot.hasClass = name => snapshot.classNames.indexOf(name) > -1; + snapshot.getStyleProperty = prop => snapshot.style[prop]; + snapshot.getAttribute = attrName => snapshot.attributes[attrName]; + snapshot.hasAttribute = attrName => snapshot.attributes.hasOwnProperty(attrName); + snapshot.getBoundingClientRectProperty = prop => snapshot.boundingClientRect[prop]; + } +} +module.exports = exports["default"]; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGllbnQtZnVuY3Rpb25zL3NlbGVjdG9ycy9jcmVhdGUtc25hcHNob3QtbWV0aG9kcy5qcyJdLCJuYW1lcyI6WyJjcmVhdGVTbmFwc2hvdE1ldGhvZHMiLCJzbmFwc2hvdCIsImlzRWxlbWVudFNuYXBzaG90IiwidGFnTmFtZSIsImhhc0NsYXNzIiwibmFtZSIsImNsYXNzTmFtZXMiLCJpbmRleE9mIiwiZ2V0U3R5bGVQcm9wZXJ0eSIsInByb3AiLCJzdHlsZSIsImdldEF0dHJpYnV0ZSIsImF0dHJOYW1lIiwiYXR0cmlidXRlcyIsImhhc0F0dHJpYnV0ZSIsImhhc093blByb3BlcnR5IiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0UHJvcGVydHkiLCJib3VuZGluZ0NsaWVudFJlY3QiXSwibWFwcGluZ3MiOiI7OztrQkFBd0JBLHFCO0FBQVQsU0FBU0EscUJBQVQsQ0FBZ0NDLFFBQWhDLEVBQTBDO0FBQ3JELFVBQU1DLG9CQUFvQixDQUFDLENBQUNELFNBQVNFLE9BQXJDOztBQUVBLFFBQUlELGlCQUFKLEVBQXVCO0FBQ25CRCxpQkFBU0csUUFBVCxHQUF5Q0MsUUFBUUosU0FBU0ssVUFBVCxDQUFvQkMsT0FBcEIsQ0FBNEJGLElBQTVCLElBQW9DLENBQUMsQ0FBdEY7QUFDQUosaUJBQVNPLGdCQUFULEdBQXlDQyxRQUFRUixTQUFTUyxLQUFULENBQWVELElBQWYsQ0FBakQ7QUFDQVIsaUJBQVNVLFlBQVQsR0FBeUNDLFlBQVlYLFNBQVNZLFVBQVQsQ0FBb0JELFFBQXBCLENBQXJEO0FBQ0FYLGlCQUFTYSxZQUFULEdBQXlDRixZQUFZWCxTQUFTWSxVQUFULENBQW9CRSxjQUFwQixDQUFtQ0gsUUFBbkMsQ0FBckQ7QUFDQVgsaUJBQVNlLDZCQUFULEdBQXlDUCxRQUFRUixTQUFTZ0Isa0JBQVQsQ0FBNEJSLElBQTVCLENBQWpEO0FBQ0g7QUFDSiIsImZpbGUiOiJjbGllbnQtZnVuY3Rpb25zL3NlbGVjdG9ycy9jcmVhdGUtc25hcHNob3QtbWV0aG9kcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNyZWF0ZVNuYXBzaG90TWV0aG9kcyAoc25hcHNob3QpIHtcbiAgICBjb25zdCBpc0VsZW1lbnRTbmFwc2hvdCA9ICEhc25hcHNob3QudGFnTmFtZTtcblxuICAgIGlmIChpc0VsZW1lbnRTbmFwc2hvdCkge1xuICAgICAgICBzbmFwc2hvdC5oYXNDbGFzcyAgICAgICAgICAgICAgICAgICAgICA9IG5hbWUgPT4gc25hcHNob3QuY2xhc3NOYW1lcy5pbmRleE9mKG5hbWUpID4gLTE7XG4gICAgICAgIHNuYXBzaG90LmdldFN0eWxlUHJvcGVydHkgICAgICAgICAgICAgID0gcHJvcCA9PiBzbmFwc2hvdC5zdHlsZVtwcm9wXTtcbiAgICAgICAgc25hcHNob3QuZ2V0QXR0cmlidXRlICAgICAgICAgICAgICAgICAgPSBhdHRyTmFtZSA9PiBzbmFwc2hvdC5hdHRyaWJ1dGVzW2F0dHJOYW1lXTtcbiAgICAgICAgc25hcHNob3QuaGFzQXR0cmlidXRlICAgICAgICAgICAgICAgICAgPSBhdHRyTmFtZSA9PiBzbmFwc2hvdC5hdHRyaWJ1dGVzLmhhc093blByb3BlcnR5KGF0dHJOYW1lKTtcbiAgICAgICAgc25hcHNob3QuZ2V0Qm91bmRpbmdDbGllbnRSZWN0UHJvcGVydHkgPSBwcm9wID0+IHNuYXBzaG90LmJvdW5kaW5nQ2xpZW50UmVjdFtwcm9wXTtcbiAgICB9XG59XG4iXX0= diff --git a/lib/client-functions/selectors/selector-attribute-filter.js b/lib/client-functions/selectors/selector-attribute-filter.js new file mode 100644 index 00000000..54bae9ad --- /dev/null +++ b/lib/client-functions/selectors/selector-attribute-filter.js @@ -0,0 +1,30 @@ +'use strict'; + +exports.__esModule = true; +exports.default = selectorAttributeFilter; +// ------------------------------------------------------------- +// WARNING: this file is used by both the client and the server. +// Do not use any browser or node-specific API! +// ------------------------------------------------------------- + +/* eslint-disable no-undef */ +function selectorAttributeFilter(node, index, originNode, attrName, attrValue) { + if (node.nodeType !== 1) return false; + + const attributes = node.attributes; + let attr = null; + + const check = (actual, expect) => typeof expect === 'string' ? expect === actual : expect.test(actual); + + for (let i = 0; i < attributes.length; i++) { + attr = attributes[i]; + + if (check(attr.nodeName, attrName) && (!attrValue || check(attr.nodeValue, attrValue))) return true; + } + + return false; +} +/* eslint-enable no-undef */ + +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGllbnQtZnVuY3Rpb25zL3NlbGVjdG9ycy9zZWxlY3Rvci1hdHRyaWJ1dGUtZmlsdGVyLmpzIl0sIm5hbWVzIjpbInNlbGVjdG9yQXR0cmlidXRlRmlsdGVyIiwibm9kZSIsImluZGV4Iiwib3JpZ2luTm9kZSIsImF0dHJOYW1lIiwiYXR0clZhbHVlIiwibm9kZVR5cGUiLCJhdHRyaWJ1dGVzIiwiYXR0ciIsImNoZWNrIiwiYWN0dWFsIiwiZXhwZWN0IiwidGVzdCIsImkiLCJsZW5ndGgiLCJub2RlTmFtZSIsIm5vZGVWYWx1ZSJdLCJtYXBwaW5ncyI6Ijs7O2tCQU13QkEsdUI7QUFOeEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDZSxTQUFTQSx1QkFBVCxDQUFrQ0MsSUFBbEMsRUFBd0NDLEtBQXhDLEVBQStDQyxVQUEvQyxFQUEyREMsUUFBM0QsRUFBcUVDLFNBQXJFLEVBQWdGO0FBQzNGLFFBQUlKLEtBQUtLLFFBQUwsS0FBa0IsQ0FBdEIsRUFDSSxPQUFPLEtBQVA7O0FBRUosVUFBTUMsYUFBYU4sS0FBS00sVUFBeEI7QUFDQSxRQUFJQyxPQUFhLElBQWpCOztBQUVBLFVBQU1DLFFBQVEsQ0FBQ0MsTUFBRCxFQUFTQyxNQUFULEtBQW9CLE9BQU9BLE1BQVAsS0FBa0IsUUFBbEIsR0FBNkJBLFdBQVdELE1BQXhDLEdBQWlEQyxPQUFPQyxJQUFQLENBQVlGLE1BQVosQ0FBbkY7O0FBRUEsU0FBSyxJQUFJRyxJQUFJLENBQWIsRUFBZ0JBLElBQUlOLFdBQVdPLE1BQS9CLEVBQXVDRCxHQUF2QyxFQUE0QztBQUN4Q0wsZUFBT0QsV0FBV00sQ0FBWCxDQUFQOztBQUVBLFlBQUlKLE1BQU1ELEtBQUtPLFFBQVgsRUFBcUJYLFFBQXJCLE1BQW1DLENBQUNDLFNBQUQsSUFBY0ksTUFBTUQsS0FBS1EsU0FBWCxFQUFzQlgsU0FBdEIsQ0FBakQsQ0FBSixFQUNJLE9BQU8sSUFBUDtBQUNQOztBQUVELFdBQU8sS0FBUDtBQUNIO0FBQ0QiLCJmaWxlIjoiY2xpZW50LWZ1bmN0aW9ucy9zZWxlY3RvcnMvc2VsZWN0b3ItYXR0cmlidXRlLWZpbHRlci5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFdBUk5JTkc6IHRoaXMgZmlsZSBpcyB1c2VkIGJ5IGJvdGggdGhlIGNsaWVudCBhbmQgdGhlIHNlcnZlci5cbi8vIERvIG5vdCB1c2UgYW55IGJyb3dzZXIgb3Igbm9kZS1zcGVjaWZpYyBBUEkhXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBzZWxlY3RvckF0dHJpYnV0ZUZpbHRlciAobm9kZSwgaW5kZXgsIG9yaWdpbk5vZGUsIGF0dHJOYW1lLCBhdHRyVmFsdWUpIHtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSAhPT0gMSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgY29uc3QgYXR0cmlidXRlcyA9IG5vZGUuYXR0cmlidXRlcztcbiAgICBsZXQgYXR0ciAgICAgICA9IG51bGw7XG5cbiAgICBjb25zdCBjaGVjayA9IChhY3R1YWwsIGV4cGVjdCkgPT4gdHlwZW9mIGV4cGVjdCA9PT0gJ3N0cmluZycgPyBleHBlY3QgPT09IGFjdHVhbCA6IGV4cGVjdC50ZXN0KGFjdHVhbCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYXR0ciA9IGF0dHJpYnV0ZXNbaV07XG5cbiAgICAgICAgaWYgKGNoZWNrKGF0dHIubm9kZU5hbWUsIGF0dHJOYW1lKSAmJiAoIWF0dHJWYWx1ZSB8fCBjaGVjayhhdHRyLm5vZGVWYWx1ZSwgYXR0clZhbHVlKSkpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG4vKiBlc2xpbnQtZW5hYmxlIG5vLXVuZGVmICovXG4iXX0= diff --git a/lib/client-functions/selectors/selector-builder.js b/lib/client-functions/selectors/selector-builder.js new file mode 100644 index 00000000..f4d1269f --- /dev/null +++ b/lib/client-functions/selectors/selector-builder.js @@ -0,0 +1,223 @@ +'use strict'; + +exports.__esModule = true; + +var _stringify = require('babel-runtime/core-js/json/stringify'); + +var _stringify2 = _interopRequireDefault(_stringify); + +var _lodash = require('lodash'); + +var _dedent = require('dedent'); + +var _dedent2 = _interopRequireDefault(_dedent); + +var _clientFunctionBuilder = require('../client-function-builder'); + +var _clientFunctionBuilder2 = _interopRequireDefault(_clientFunctionBuilder); + +var _replicator = require('../replicator'); + +var _runtime = require('../../errors/runtime'); + +var _builderSymbol = require('../builder-symbol'); + +var _builderSymbol2 = _interopRequireDefault(_builderSymbol); + +var _message = require('../../errors/runtime/message'); + +var _message2 = _interopRequireDefault(_message); + +var _typeAssertions = require('../../errors/runtime/type-assertions'); + +var _observation = require('../../test-run/commands/observation'); + +var _defineLazyProperty = require('../../utils/define-lazy-property'); + +var _defineLazyProperty2 = _interopRequireDefault(_defineLazyProperty); + +var _addApi = require('./add-api'); + +var _createSnapshotMethods = require('./create-snapshot-methods'); + +var _createSnapshotMethods2 = _interopRequireDefault(_createSnapshotMethods); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class SelectorBuilder extends _clientFunctionBuilder2.default { + constructor(fn, options, callsiteNames) { + const apiFn = options && options.apiFn; + const builderFromSelector = fn && fn[_builderSymbol2.default]; + const builderFromPromiseOrSnapshot = fn && fn.selector && fn.selector[_builderSymbol2.default]; + let builder = builderFromSelector || builderFromPromiseOrSnapshot; + + builder = builder instanceof SelectorBuilder ? builder : null; + + if (builder) { + fn = builder.fn; + + if (options === void 0 || typeof options === 'object') options = (0, _lodash.merge)({}, builder.options, options, { sourceSelectorBuilder: builder }); + } + + super(fn, options, callsiteNames); + + if (!this.options.apiFnChain) { + const fnType = typeof this.fn; + let item = fnType === 'string' ? `'${this.fn}'` : `[${fnType}]`; + + item = `Selector(${item})`; + this.options.apiFn = item; + this.options.apiFnChain = [item]; + } + + if (apiFn) this.options.apiFnChain.push(apiFn); + + this.options.apiFnID = this.options.apiFnChain.length - 1; + } + + _getCompiledFnCode() { + // OPTIMIZATION: if selector was produced from another selector and + // it has same dependencies as source selector, then we can + // avoid recompilation and just re-use already compiled code. + const hasSameDependenciesAsSourceSelector = this.options.sourceSelectorBuilder && this.options.sourceSelectorBuilder.options.dependencies === this.options.dependencies; + + if (hasSameDependenciesAsSourceSelector) return this.options.sourceSelectorBuilder.compiledFnCode; + + const code = typeof this.fn === 'string' ? `(function(){return document.querySelectorAll(${(0, _stringify2.default)(this.fn)});});` : super._getCompiledFnCode(); + + if (code) { + return (0, _dedent2.default)(`(function(){ + var __f$=${code}; + return function(){ + var args = __dependencies$.boundArgs || arguments; + var selectorFilter = window['%testCafeSelectorFilter%']; + + var nodes = __f$.apply(this, args); + nodes = selectorFilter.cast(nodes); + + if (!nodes.length && !selectorFilter.error) + selectorFilter.error = __dependencies$.apiInfo.apiFnID; + + return selectorFilter.filter(nodes, __dependencies$.filterOptions, __dependencies$.apiInfo); + }; + })();`); + } + + return null; + } + + _createInvalidFnTypeError() { + return new _runtime.ClientFunctionAPIError(this.callsiteNames.instantiation, this.callsiteNames.instantiation, _message2.default.selectorInitializedWithWrongType, typeof this.fn); + } + + _executeCommand(args, testRun, callsite) { + const resultPromise = super._executeCommand(args, testRun, callsite); + + this._addBoundArgsSelectorGetter(resultPromise, args); + + // OPTIMIZATION: use buffer function as selector not to trigger lazy property ahead of time + (0, _addApi.addAPI)(resultPromise, () => resultPromise.selector, SelectorBuilder, this.options.customDOMProperties, this.options.customMethods); + + return resultPromise; + } + + _getSourceSelectorBuilderApiFnID() { + let selectorAncestor = this; + + while (selectorAncestor.options.sourceSelectorBuilder) selectorAncestor = selectorAncestor.options.sourceSelectorBuilder; + + return selectorAncestor.options.apiFnID; + } + + getFunctionDependencies() { + const dependencies = super.getFunctionDependencies(); + + var _options = this.options; + const filterVisible = _options.filterVisible, + filterHidden = _options.filterHidden, + counterMode = _options.counterMode, + collectionMode = _options.collectionMode, + index = _options.index, + customDOMProperties = _options.customDOMProperties, + customMethods = _options.customMethods, + apiFnChain = _options.apiFnChain, + boundArgs = _options.boundArgs; + + + return (0, _lodash.merge)({}, dependencies, { + filterOptions: { + filterVisible, + filterHidden, + counterMode, + collectionMode, + index: (0, _lodash.isNil)(index) ? null : index + }, + apiInfo: { + apiFnChain, + apiFnID: this._getSourceSelectorBuilderApiFnID() + }, + boundArgs, + customDOMProperties, + customMethods + }); + } + + _createTestRunCommand(encodedArgs, encodedDependencies) { + return new _observation.ExecuteSelectorCommand({ + instantiationCallsiteName: this.callsiteNames.instantiation, + fnCode: this.compiledFnCode, + args: encodedArgs, + dependencies: encodedDependencies, + needError: this.options.needError, + apiFnChain: this.options.apiFnChain, + visibilityCheck: !!this.options.visibilityCheck, + timeout: this.options.timeout + }); + } + + _validateOptions(options) { + super._validateOptions(options); + + if (!(0, _lodash.isNil)(options.visibilityCheck)) (0, _typeAssertions.assertType)(_typeAssertions.is.boolean, this.callsiteNames.instantiation, '"visibilityCheck" option', options.visibilityCheck); + + if (!(0, _lodash.isNil)(options.timeout)) (0, _typeAssertions.assertType)(_typeAssertions.is.nonNegativeNumber, this.callsiteNames.instantiation, '"timeout" option', options.timeout); + } + + _getReplicatorTransforms() { + const transforms = super._getReplicatorTransforms(); + + transforms.push(new _replicator.SelectorNodeTransform()); + + return transforms; + } + + _addBoundArgsSelectorGetter(obj, selectorArgs) { + (0, _defineLazyProperty2.default)(obj, 'selector', () => { + const builder = new SelectorBuilder(this.getFunction(), { boundArgs: selectorArgs }); + + return builder.getFunction(); + }); + } + + _decorateFunction(selectorFn) { + super._decorateFunction(selectorFn); + + (0, _addApi.addAPI)(selectorFn, () => selectorFn, SelectorBuilder, this.options.customDOMProperties, this.options.customMethods); + } + + _processResult(result, selectorArgs) { + const snapshot = super._processResult(result, selectorArgs); + + if (snapshot && !this.options.counterMode) { + this._addBoundArgsSelectorGetter(snapshot, selectorArgs); + (0, _createSnapshotMethods2.default)(snapshot); + + if (this.options.customMethods) (0, _addApi.addCustomMethods)(snapshot, () => snapshot.selector, SelectorBuilder, this.options.customMethods); + } + + return snapshot; + } +} +exports.default = SelectorBuilder; +module.exports = exports['default']; +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGllbnQtZnVuY3Rpb25zL3NlbGVjdG9ycy9zZWxlY3Rvci1idWlsZGVyLmpzIl0sIm5hbWVzIjpbIlNlbGVjdG9yQnVpbGRlciIsIkNsaWVudEZ1bmN0aW9uQnVpbGRlciIsImNvbnN0cnVjdG9yIiwiZm4iLCJvcHRpb25zIiwiY2FsbHNpdGVOYW1lcyIsImFwaUZuIiwiYnVpbGRlckZyb21TZWxlY3RvciIsImZ1bmN0aW9uQnVpbGRlclN5bWJvbCIsImJ1aWxkZXJGcm9tUHJvbWlzZU9yU25hcHNob3QiLCJzZWxlY3RvciIsImJ1aWxkZXIiLCJzb3VyY2VTZWxlY3RvckJ1aWxkZXIiLCJhcGlGbkNoYWluIiwiZm5UeXBlIiwiaXRlbSIsInB1c2giLCJhcGlGbklEIiwibGVuZ3RoIiwiX2dldENvbXBpbGVkRm5Db2RlIiwiaGFzU2FtZURlcGVuZGVuY2llc0FzU291cmNlU2VsZWN0b3IiLCJkZXBlbmRlbmNpZXMiLCJjb21waWxlZEZuQ29kZSIsImNvZGUiLCJfY3JlYXRlSW52YWxpZEZuVHlwZUVycm9yIiwiQ2xpZW50RnVuY3Rpb25BUElFcnJvciIsImluc3RhbnRpYXRpb24iLCJNRVNTQUdFIiwic2VsZWN0b3JJbml0aWFsaXplZFdpdGhXcm9uZ1R5cGUiLCJfZXhlY3V0ZUNvbW1hbmQiLCJhcmdzIiwidGVzdFJ1biIsImNhbGxzaXRlIiwicmVzdWx0UHJvbWlzZSIsIl9hZGRCb3VuZEFyZ3NTZWxlY3RvckdldHRlciIsImN1c3RvbURPTVByb3BlcnRpZXMiLCJjdXN0b21NZXRob2RzIiwiX2dldFNvdXJjZVNlbGVjdG9yQnVpbGRlckFwaUZuSUQiLCJzZWxlY3RvckFuY2VzdG9yIiwiZ2V0RnVuY3Rpb25EZXBlbmRlbmNpZXMiLCJmaWx0ZXJWaXNpYmxlIiwiZmlsdGVySGlkZGVuIiwiY291bnRlck1vZGUiLCJjb2xsZWN0aW9uTW9kZSIsImluZGV4IiwiYm91bmRBcmdzIiwiZmlsdGVyT3B0aW9ucyIsImFwaUluZm8iLCJfY3JlYXRlVGVzdFJ1bkNvbW1hbmQiLCJlbmNvZGVkQXJncyIsImVuY29kZWREZXBlbmRlbmNpZXMiLCJFeGVjdXRlU2VsZWN0b3JDb21tYW5kIiwiaW5zdGFudGlhdGlvbkNhbGxzaXRlTmFtZSIsImZuQ29kZSIsIm5lZWRFcnJvciIsInZpc2liaWxpdHlDaGVjayIsInRpbWVvdXQiLCJfdmFsaWRhdGVPcHRpb25zIiwiaXMiLCJib29sZWFuIiwibm9uTmVnYXRpdmVOdW1iZXIiLCJfZ2V0UmVwbGljYXRvclRyYW5zZm9ybXMiLCJ0cmFuc2Zvcm1zIiwiU2VsZWN0b3JOb2RlVHJhbnNmb3JtIiwib2JqIiwic2VsZWN0b3JBcmdzIiwiZ2V0RnVuY3Rpb24iLCJfZGVjb3JhdGVGdW5jdGlvbiIsInNlbGVjdG9yRm4iLCJfcHJvY2Vzc1Jlc3VsdCIsInJlc3VsdCIsInNuYXBzaG90Il0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBOztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7Ozs7O0FBRWUsTUFBTUEsZUFBTixTQUE4QkMsK0JBQTlCLENBQW9EO0FBQy9EQyxnQkFBYUMsRUFBYixFQUFpQkMsT0FBakIsRUFBMEJDLGFBQTFCLEVBQXlDO0FBQ3JDLGNBQU1DLFFBQStCRixXQUFXQSxRQUFRRSxLQUF4RDtBQUNBLGNBQU1DLHNCQUErQkosTUFBTUEsR0FBR0ssdUJBQUgsQ0FBM0M7QUFDQSxjQUFNQywrQkFBK0JOLE1BQU1BLEdBQUdPLFFBQVQsSUFBcUJQLEdBQUdPLFFBQUgsQ0FBWUYsdUJBQVosQ0FBMUQ7QUFDQSxZQUFJRyxVQUFpQ0osdUJBQXVCRSw0QkFBNUQ7O0FBRUFFLGtCQUFVQSxtQkFBbUJYLGVBQW5CLEdBQXFDVyxPQUFyQyxHQUErQyxJQUF6RDs7QUFFQSxZQUFJQSxPQUFKLEVBQWE7QUFDVFIsaUJBQUtRLFFBQVFSLEVBQWI7O0FBRUEsZ0JBQUlDLFlBQVksS0FBSyxDQUFqQixJQUFzQixPQUFP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QUFyQixFQUE2QkwsWUFBN0IsQ0FBakI7O0FBRUEsWUFBSU0sWUFBWSxDQUFDLEtBQUtuRSxPQUFMLENBQWFzQyxXQUE5QixFQUEyQztBQUN2QyxpQkFBS1IsMkJBQUwsQ0FBaUNxQyxRQUFqQyxFQUEyQ04sWUFBM0M7QUFDQSxpREFBc0JNLFFBQXRCOztBQUVBLGdCQUFJLEtBQUtuRSxPQUFMLENBQWFnQyxhQUFqQixFQUNJLDhCQUFpQm1DLFFBQWpCLEVBQTJCLE1BQU1BLFNBQVM3RCxRQUExQyxFQUFvRFYsZUFBcEQsRUFBcUUsS0FBS0ksT0FBTCxDQUFhZ0MsYUFBbEY7QUFDUDs7QUFFRCxlQUFPbUMsUUFBUDtBQUNIO0FBekw4RDtrQkFBOUN2RSxlIiwiZmlsZSI6ImNsaWVudC1mdW5jdGlvbnMvc2VsZWN0b3JzL3NlbGVjdG9yLWJ1aWxkZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc05pbCBhcyBpc051bGxPclVuZGVmaW5lZCwgbWVyZ2UgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGRlZGVudCBmcm9tICdkZWRlbnQnO1xuaW1wb3J0IENsaWVudEZ1bmN0aW9uQnVpbGRlciBmcm9tICcuLi9jbGllbnQtZnVuY3Rpb24tYnVpbGRlcic7XG5pbXBvcnQgeyBTZWxlY3Rvck5vZGVUcmFuc2Zvcm0gfSBmcm9tICcuLi9yZXBsaWNhdG9yJztcbmltcG9ydCB7IENsaWVudEZ1bmN0aW9uQVBJRXJyb3IgfSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgZnVuY3Rpb25CdWlsZGVyU3ltYm9sIGZyb20gJy4uL2J1aWxkZXItc3ltYm9sJztcbmltcG9ydCBNRVNTQUdFIGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lL21lc3NhZ2UnO1xuaW1wb3J0IHsgYXNzZXJ0VHlwZSwgaXMgfSBmcm9tICcuLi8uLi9lcnJvcnMvcnVudGltZS90eXBlLWFzc2VydGlvbnMnO1xuaW1wb3J0IHsgRXhlY3V0ZVNlbGVjdG9yQ29tbWFuZCB9IGZyb20gJy4uLy4uL3Rlc3QtcnVuL2NvbW1hbmRzL29ic2VydmF0aW9uJztcbmltcG9ydCBkZWZpbmVMYXp5UHJvcGVydHkgZnJvbSAnLi4vLi4vdXRpbHMvZGVmaW5lLWxhenktcHJvcGVydHknO1xuaW1wb3J0IHsgYWRkQVBJLCBhZGRDdXN0b21NZXRob2RzIH0gZnJvbSAnLi9hZGQtYXBpJztcbmltcG9ydCBjcmVhdGVTbmFwc2hvdE1ldGhvZHMgZnJvbSAnLi9jcmVhdGUtc25hcHNob3QtbWV0aG9kcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNlbGVjdG9yQnVpbGRlciBleHRlbmRzIENsaWVudEZ1bmN0aW9uQnVpbGRlciB7XG4gICAgY29uc3RydWN0b3IgKGZuLCBvcHRpb25zLCBjYWxsc2l0ZU5hbWVzKSB7XG4gICAgICAgIGNvbnN0IGFwaUZuICAgICAgICAgICAgICAgICAgICAgICAgPSBvcHRpb25zICYmIG9wdGlvbnMuYXBpRm47XG4gICAgICAgIGNvbnN0IGJ1aWxkZXJGcm9tU2VsZWN0b3IgICAgICAgICAgPSBmbiAmJiBmbltmdW5jdGlvbkJ1aWxkZXJTeW1ib2xdO1xuICAgICAgICBjb25zdCBidWlsZGVyRnJvbVByb21pc2VPclNuYXBzaG90ID0gZm4gJiYgZm4uc2VsZWN0b3IgJiYgZm4uc2VsZWN0b3JbZnVuY3Rpb25CdWlsZGVyU3ltYm9sXTtcbiAgICAgICAgbGV0IGJ1aWxkZXIgICAgICAgICAgICAgICAgICAgICAgICA9IGJ1aWxkZXJGcm9tU2VsZWN0b3IgfHwgYnVpbGRlckZyb21Qcm9taXNlT3JTbmFwc2hvdDtcblxuICAgICAgICBidWlsZGVyID0gYnVpbGRlciBpbnN0YW5jZW9mIFNlbGVjdG9yQnVpbGRlciA/IGJ1aWxkZXIgOiBudWxsO1xuXG4gICAgICAgIGlmIChidWlsZGVyKSB7XG4gICAgICAgICAgICBmbiA9IGJ1aWxkZXIuZm47XG5cbiAgICAgICAgICAgIGlmIChvcHRpb25zID09PSB2b2lkIDAgfHwgdHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBtZXJnZSh7fSwgYnVpbGRlci5vcHRpb25zLCBvcHRpb25zLCB7IHNvdXJjZVNlbGVjdG9yQnVpbGRlcjogYnVpbGRlciB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN1cGVyKGZuLCBvcHRpb25zLCBjYWxsc2l0ZU5hbWVzKTtcblxuICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5hcGlGbkNoYWluKSB7XG4gICAgICAgICAgICBjb25zdCBmblR5cGUgPSB0eXBlb2YgdGhpcy5mbjtcbiAgICAgICAgICAgIGxldCBpdGVtICAgICA9IGZuVHlwZSA9PT0gJ3N0cmluZycgPyBgJyR7dGhpcy5mbn0nYCA6IGBbJHtmblR5cGV9XWA7XG5cbiAgICAgICAgICAgIGl0ZW0gICAgICAgICAgICAgICAgICAgID0gYFNlbGVjdG9yKCR7aXRlbX0pYDtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5hcGlGbiAgICAgID0gaXRlbTtcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5hcGlGbkNoYWluID0gW2l0ZW1dO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFwaUZuKVxuICAgICAgICAgICAgdGhpcy5vcHRpb25zLmFwaUZuQ2hhaW4ucHVzaChhcGlGbik7XG5cbiAgICAgICAgdGhpcy5vcHRpb25zLmFwaUZuSUQgPSB0aGlzLm9wdGlvbnMuYXBpRm5DaGFpbi5sZW5ndGggLSAxO1xuICAgIH1cblxuICAgIF9nZXRDb21waWxlZEZuQ29kZSAoKSB7XG4gICAgICAgIC8vIE9QVElNSVpBVElPTjogaWYgc2VsZWN0b3Igd2FzIHByb2R1Y2VkIGZyb20gYW5vdGhlciBzZWxlY3RvciBhbmRcbiAgICAgICAgLy8gaXQgaGFzIHNhbWUgZGVwZW5kZW5jaWVzIGFzIHNvdXJjZSBzZWxlY3RvciwgdGhlbiB3ZSBjYW5cbiAgICAgICAgLy8gYXZvaWQgcmVjb21waWxhdGlvbiBhbmQganVzdCByZS11c2UgYWxyZWFkeSBjb21waWxlZCBjb2RlLlxuICAgICAgICBjb25zdCBoYXNTYW1lRGVwZW5kZW5jaWVzQXNTb3VyY2VTZWxlY3RvciA9IHRoaXMub3B0aW9ucy5zb3VyY2VTZWxlY3RvckJ1aWxkZXIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuc291cmNlU2VsZWN0b3JCdWlsZGVyLm9wdGlvbnMuZGVwZW5kZW5jaWVzID09PVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5kZXBlbmRlbmNpZXM7XG5cbiAgICAgICAgaWYgKGhhc1NhbWVEZXBlbmRlbmNpZXNBc1NvdXJjZVNlbGVjdG9yKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5zb3VyY2VTZWxlY3RvckJ1aWxkZXIuY29tcGlsZWRGbkNvZGU7XG5cbiAgICAgICAgY29uc3QgY29kZSA9IHR5cGVvZiB0aGlzLmZuID09PSAnc3RyaW5nJyA/XG4gICAgICAgICAgICBgKGZ1bmN0aW9uKCl7cmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJHtKU09OLnN0cmluZ2lmeSh0aGlzLmZuKX0pO30pO2AgOlxuICAgICAgICAgICAgc3VwZXIuX2dldENvbXBpbGVkRm5Db2RlKCk7XG5cbiAgICAgICAgaWYgKGNvZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBkZWRlbnQoXG4gICAgICAgICAgICAgICAgYChmdW5jdGlvbigpe1xuICAgICAgICAgICAgICAgICAgICB2YXIgX19mJD0ke2NvZGV9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhcmdzICAgICAgICAgICA9IF9fZGVwZW5kZW5jaWVzJC5ib3VuZEFyZ3MgfHwgYXJndW1lbnRzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdG9yRmlsdGVyID0gd2luZG93WycldGVzdENhZmVTZWxlY3RvckZpbHRlciUnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gX19mJC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzICAgICA9IHNlbGVjdG9yRmlsdGVyLmNhc3Qobm9kZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5vZGVzLmxlbmd0aCAmJiAhc2VsZWN0b3JGaWx0ZXIuZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JGaWx0ZXIuZXJyb3IgPSBfX2RlcGVuZGVuY2llcyQuYXBpSW5mby5hcGlGbklEO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0b3JGaWx0ZXIuZmlsdGVyKG5vZGVzLCBfX2RlcGVuZGVuY2llcyQuZmlsdGVyT3B0aW9ucywgX19kZXBlbmRlbmNpZXMkLmFwaUluZm8pO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICB9KSgpO2BcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBfY3JlYXRlSW52YWxpZEZuVHlwZUVycm9yICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBDbGllbnRGdW5jdGlvbkFQSUVycm9yKHRoaXMuY2FsbHNpdGVOYW1lcy5pbnN0YW50aWF0aW9uLCB0aGlzLmNhbGxzaXRlTmFtZXMuaW5zdGFudGlhdGlvbiwgTUVTU0FHRS5zZWxlY3RvckluaXRpYWxpemVkV2l0aFdyb25nVHlwZSwgdHlwZW9mIHRoaXMuZm4pO1xuICAgIH1cblxuICAgIF9leGVjdXRlQ29tbWFuZCAoYXJncywgdGVzdFJ1biwgY2FsbHNpdGUpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0UHJvbWlzZSA9IHN1cGVyLl9leGVjdXRlQ29tbWFuZChhcmdzLCB0ZXN0UnVuLCBjYWxsc2l0ZSk7XG5cbiAgICAgICAgdGhpcy5fYWRkQm91bmRBcmdzU2VsZWN0b3JHZXR0ZXIocmVzdWx0UHJvbWlzZSwgYXJncyk7XG5cbiAgICAgICAgLy8gT1BUSU1JWkFUSU9OOiB1c2UgYnVmZmVyIGZ1bmN0aW9uIGFzIHNlbGVjdG9yIG5vdCB0byB0cmlnZ2VyIGxhenkgcHJvcGVydHkgYWhlYWQgb2YgdGltZVxuICAgICAgICBhZGRBUEkocmVzdWx0UHJvbWlzZSwgKCkgPT4gcmVzdWx0UHJvbWlzZS5zZWxlY3RvciwgU2VsZWN0b3JCdWlsZGVyLCB0aGlzLm9wdGlvbnMuY3VzdG9tRE9NUHJvcGVydGllcywgdGhpcy5vcHRpb25zLmN1c3RvbU1ldGhvZHMpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHRQcm9taXNlO1xuICAgIH1cblxuICAgIF9nZXRTb3VyY2VTZWxlY3RvckJ1aWxkZXJBcGlGbklEICgpIHtcbiAgICAgICAgbGV0IHNlbGVjdG9yQW5jZXN0b3IgPSB0aGlzO1xuXG4gICAgICAgIHdoaWxlIChzZWxlY3RvckFuY2VzdG9yLm9wdGlvbnMuc291cmNlU2VsZWN0b3JCdWlsZGVyKVxuICAgICAgICAgICAgc2VsZWN0b3JBbmNlc3RvciA9IHNlbGVjdG9yQW5jZXN0b3Iub3B0aW9ucy5zb3VyY2VTZWxlY3RvckJ1aWxkZXI7XG5cbiAgICAgICAgcmV0dXJuIHNlbGVjdG9yQW5jZXN0b3Iub3B0aW9ucy5hcGlGbklEO1xuICAgIH1cblxuICAgIGdldEZ1bmN0aW9uRGVwZW5kZW5jaWVzICgpIHtcbiAgICAgICAgY29uc3QgZGVwZW5kZW5jaWVzID0gc3VwZXIuZ2V0RnVuY3Rpb25EZXBlbmRlbmNpZXMoKTtcblxuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBmaWx0ZXJWaXNpYmxlLFxuICAgICAgICAgICAgZmlsdGVySGlkZGVuLFxuICAgICAgICAgICAgY291bnRlck1vZGUsXG4gICAgICAgICAgICBjb2xsZWN0aW9uTW9kZSxcbiAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgY3VzdG9tRE9NUHJvcGVydGllcyxcbiAgICAgICAgICAgIGN1c3RvbU1ldGhvZHMsXG4gICAgICAgICAgICBhcGlGbkNoYWluLFxuICAgICAgICAgICAgYm91bmRBcmdzXG4gICAgICAgIH0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICAgICAgcmV0dXJuIG1lcmdlKHt9LCBkZXBlbmRlbmNpZXMsIHtcbiAgICAgICAgICAgIGZpbHRlck9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJWaXNpYmxlLFxuICAgICAgICAgICAgICAgIGZpbHRlckhpZGRlbixcbiAgICAgICAgICAgICAgICBjb3VudGVyTW9kZSxcbiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uTW9kZSxcbiAgICAgICAgICAgICAgICBpbmRleDogaXNOdWxsT3JVbmRlZmluZWQoaW5kZXgpID8gbnVsbCA6IGluZGV4XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXBpSW5mbzoge1xuICAgICAgICAgICAgICAgIGFwaUZuQ2hhaW4sXG4gICAgICAgICAgICAgICAgYXBpRm5JRDogdGhpcy5fZ2V0U291cmNlU2VsZWN0b3JCdWlsZGVyQXBpRm5JRCgpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm91bmRBcmdzLFxuICAgICAgICAgICAgY3VzdG9tRE9NUHJvcGVydGllcyxcbiAgICAgICAgICAgIGN1c3RvbU1ldGhvZHNcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZVRlc3RSdW5Db21tYW5kIChlbmNvZGVkQXJncywgZW5jb2RlZERlcGVuZGVuY2llcykge1xuICAgICAgICByZXR1cm4gbmV3IEV4ZWN1dGVTZWxlY3RvckNvbW1hbmQoe1xuICAgICAgICAgICAgaW5zdGFudGlhdGlvbkNhbGxzaXRlTmFtZTogdGhpcy5jYWxsc2l0ZU5hbWVzLmluc3RhbnRpYXRpb24sXG4gICAgICAgICAgICBmbkNvZGU6ICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXBpbGVkRm5Db2RlLFxuICAgICAgICAgICAgYXJnczogICAgICAgICAgICAgICAgICAgICAgZW5jb2RlZEFyZ3MsXG4gICAgICAgICAgICBkZXBlbmRlbmNpZXM6ICAgICAgICAgICAgICBlbmNvZGVkRGVwZW5kZW5jaWVzLFxuICAgICAgICAgICAgbmVlZEVycm9yOiAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLm5lZWRFcnJvcixcbiAgICAgICAgICAgIGFwaUZuQ2hhaW46ICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5hcGlGbkNoYWluLFxuICAgICAgICAgICAgdmlzaWJpbGl0eUNoZWNrOiAgICAgICAgICAgISF0aGlzLm9wdGlvbnMudmlzaWJpbGl0eUNoZWNrLFxuICAgICAgICAgICAgdGltZW91dDogICAgICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLnRpbWVvdXRcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX3ZhbGlkYXRlT3B0aW9ucyAob3B0aW9ucykge1xuICAgICAgICBzdXBlci5fdmFsaWRhdGVPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgICAgIGlmICghaXNOdWxsT3JVbmRlZmluZWQob3B0aW9ucy52aXNpYmlsaXR5Q2hlY2spKVxuICAgICAgICAgICAgYXNzZXJ0VHlwZShpcy5ib29sZWFuLCB0aGlzLmNhbGxzaXRlTmFtZXMuaW5zdGFudGlhdGlvbiwgJ1widmlzaWJpbGl0eUNoZWNrXCIgb3B0aW9uJywgb3B0aW9ucy52aXNpYmlsaXR5Q2hlY2spO1xuXG4gICAgICAgIGlmICghaXNOdWxsT3JVbmRlZmluZWQob3B0aW9ucy50aW1lb3V0KSlcbiAgICAgICAgICAgIGFzc2VydFR5cGUoaXMubm9uTmVnYXRpdmVOdW1iZXIsIHRoaXMuY2FsbHNpdGVOYW1lcy5pbnN0YW50aWF0aW9uLCAnXCJ0aW1lb3V0XCIgb3B0aW9uJywgb3B0aW9ucy50aW1lb3V0KTtcbiAgICB9XG5cbiAgICBfZ2V0UmVwbGljYXRvclRyYW5zZm9ybXMgKCkge1xuICAgICAgICBjb25zdCB0cmFuc2Zvcm1zID0gc3VwZXIuX2dldFJlcGxpY2F0b3JUcmFuc2Zvcm1zKCk7XG5cbiAgICAgICAgdHJhbnNmb3Jtcy5wdXNoKG5ldyBTZWxlY3Rvck5vZGVUcmFuc2Zvcm0oKSk7XG5cbiAgICAgICAgcmV0dXJuIHRyYW5zZm9ybXM7XG4gICAgfVxuXG4gICAgX2FkZEJvdW5kQXJnc1NlbGVjdG9yR2V0dGVyIChvYmosIHNlbGVjdG9yQXJncykge1xuICAgICAgICBkZWZpbmVMYXp5UHJvcGVydHkob2JqLCAnc2VsZWN0b3InLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWlsZGVyID0gbmV3IFNlbGVjdG9yQnVpbGRlcih0aGlzLmdldEZ1bmN0aW9uKCksIHsgYm91bmRBcmdzOiBzZWxlY3RvckFyZ3MgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmdldEZ1bmN0aW9uKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIF9kZWNvcmF0ZUZ1bmN0aW9uIChzZWxlY3RvckZuKSB7XG4gICAgICAgIHN1cGVyLl9kZWNvcmF0ZUZ1bmN0aW9uKHNlbGVjdG9yRm4pO1xuXG4gICAgICAgIGFkZEFQSShzZWxlY3RvckZuLCAoKSA9PiBzZWxlY3RvckZuLCBTZWxlY3RvckJ1aWxkZXIsIHRoaXMub3B0aW9ucy5jdXN0b21ET01Qcm9wZXJ0aWVzLCB0aGlzLm9wdGlvbnMuY3VzdG9tTWV0aG9kcyk7XG4gICAgfVxuXG4gICAgX3Byb2Nlc3NSZXN1bHQgKHJlc3VsdCwgc2VsZWN0b3JBcmdzKSB7XG4gICAgICAgIGNvbnN0IHNuYXBzaG90ID0gc3VwZXIuX3Byb2Nlc3NSZXN1bHQocmVzdWx0LCBzZWxlY3RvckFyZ3MpO1xuXG4gICAgICAgIGlmIChzbmFwc2hvdCAmJiAhdGhpcy5vcHRpb25zLmNvdW50ZXJNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLl9hZGRCb3VuZEFyZ3NTZWxlY3RvckdldHRlcihzbmFwc2hvdCwgc2VsZWN0b3JBcmdzKTtcbiAgICAgICAgICAgIGNyZWF0ZVNuYXBzaG90TWV0aG9kcyhzbmFwc2hvdCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuY3VzdG9tTWV0aG9kcylcbiAgICAgICAgICAgICAgICBhZGRDdXN0b21NZXRob2RzKHNuYXBzaG90LCAoKSA9PiBzbmFwc2hvdC5zZWxlY3RvciwgU2VsZWN0b3JCdWlsZGVyLCB0aGlzLm9wdGlvbnMuY3VzdG9tTWV0aG9kcyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc25hcHNob3Q7XG4gICAgfVxufVxuXG4iXX0= diff --git a/lib/client-functions/selectors/selector-text-filter.js b/lib/client-functions/selectors/selector-text-filter.js new file mode 100644 index 00000000..bf918946 --- /dev/null +++ b/lib/client-functions/selectors/selector-text-filter.js @@ -0,0 +1,61 @@ +'use strict'; + +exports.__esModule = true; +exports.default = selectorTextFilter; +// ------------------------------------------------------------- +// WARNING: this file is used by both the client and the server. +// Do not use any browser or node-specific API! +// ------------------------------------------------------------- + +/* eslint-disable no-undef */ +function selectorTextFilter(node, index, originNode, textFilter) { + + function hasChildrenWithText(parentNode) { + const cnCount = parentNode.childNodes.length; + + for (let i = 0; i < cnCount; i++) { + if (selectorTextFilter(parentNode.childNodes[i], index, originNode, textFilter)) return true; + } + + return false; + } + + function checkNodeText(text) { + if (textFilter instanceof RegExp) return textFilter.test(text); + return textFilter === text.trim(); + } + + // Element + if (node.nodeType === 1) { + let text = node.innerText; + + // NOTE: In Firefox,