diff --git a/src/browser/connection/gateway.ts b/src/browser/connection/gateway.ts index 89524d84696..63b3344bf19 100644 --- a/src/browser/connection/gateway.ts +++ b/src/browser/connection/gateway.ts @@ -5,6 +5,8 @@ import { Proxy } from 'testcafe-hammerhead'; import { Dictionary } from '../../configuration/interfaces'; import BrowserConnection from './index'; import { IncomingMessage, ServerResponse } from 'http'; +import promisifyEvent from 'promisify-event'; +import SetupWindowResult from './setup-window-result'; const IDLE_PAGE_SCRIPT = read('../../client/browser/idle-page/index.js'); const IDLE_PAGE_STYLE = read('../../client/browser/idle-page/styles.css'); @@ -52,6 +54,7 @@ export default class BrowserConnectionGateway { this._dispatch('/browser/init-script/{id}', proxy, BrowserConnectionGateway._onInitScriptResponse, 'POST'); this._dispatch('/browser/active-window-id/{id}', proxy, BrowserConnectionGateway._onGetActiveWindowIdRequest); this._dispatch('/browser/active-window-id/{id}', proxy, BrowserConnectionGateway._onSetActiveWindowIdRequest, 'POST'); + this._dispatch('/browser/set-up-window/{id}', proxy, BrowserConnectionGateway._onSetupWindow, 'POST'); proxy.GET('/browser/connect', (req: IncomingMessage, res: ServerResponse) => this._connectNextRemoteBrowser(req, res)); proxy.GET('/browser/connect/', (req: IncomingMessage, res: ServerResponse) => this._connectNextRemoteBrowser(req, res)); @@ -84,7 +87,7 @@ export default class BrowserConnectionGateway { } // Route handlers - private static _onConnection (req: IncomingMessage, res: ServerResponse, connection: BrowserConnection): void { + private static async _onConnection (req: IncomingMessage, res: ServerResponse, connection: BrowserConnection): Promise { if (connection.isReady()) respond500(res, 'The connection is already established.'); @@ -92,7 +95,18 @@ export default class BrowserConnectionGateway { const userAgent = req.headers['user-agent'] as string; connection.establish(userAgent); - redirect(res, connection.idleUrl); + + if (connection.permanent) + redirect(res, connection.idleUrl); + + else { + promisifyEvent(connection, 'jobAdded') + .then(async () => { + const testRunUrl = await connection.getTestRunUrl(true) || connection.idleUrl; + + redirect(res, testRunUrl); + }); + } } } @@ -171,6 +185,14 @@ export default class BrowserConnectionGateway { } } + private static async _onSetupWindow (req: IncomingMessage, res: ServerResponse, connection: BrowserConnection): Promise { + if (BrowserConnectionGateway._ensureConnectionReady(res, connection)) { + await connection.setUpBrowserWindow(); + + respondWithJSON(res, { result: SetupWindowResult.ok }); + } + } + private async _connectNextRemoteBrowser (req: IncomingMessage, res: ServerResponse): Promise { preventCaching(res); diff --git a/src/browser/connection/index.ts b/src/browser/connection/index.ts index 3a98c2ef276..51c98c27859 100644 --- a/src/browser/connection/index.ts +++ b/src/browser/connection/index.ts @@ -58,6 +58,7 @@ export default class BrowserConnection extends EventEmitter { public readonly idleUrl: string; private forcedIdleUrl: string; private readonly initScriptUrl: string; + private readonly setupWindowUrl: string; private readonly heartbeatRelativeUrl: string; private readonly statusRelativeUrl: string; private readonly statusDoneRelativeUrl: string; @@ -96,10 +97,11 @@ export default class BrowserConnection extends EventEmitter { this.pendingTestRunUrl = null; this.allowMultipleWindows = allowMultipleWindows; - 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.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.setupWindowUrl = `${gateway.domain}/browser/set-up-window/${this.id}`; this.heartbeatRelativeUrl = `/browser/heartbeat/${this.id}`; this.statusRelativeUrl = `/browser/status/${this.id}`; @@ -182,7 +184,7 @@ export default class BrowserConnection extends EventEmitter { }, this.HEARTBEAT_TIMEOUT); } - private async _getTestRunUrl (needPopNext: boolean): Promise { + public async getTestRunUrl (needPopNext: boolean): Promise { if (needPopNext || !this.pendingTestRunUrl) this.pendingTestRunUrl = await this._popNextTestRunUrl(); @@ -301,6 +303,8 @@ export default class BrowserConnection extends EventEmitter { public addJob (job: any): void { this.jobQueue.push(job); + + this.emit('jobAdded'); } public removeJob (job: any): void { @@ -364,7 +368,7 @@ export default class BrowserConnection extends EventEmitter { const initScriptPromise = this.initScriptsQueue.shift(); if (initScriptPromise) - initScriptPromise.resolve(JSON.parse(data)); + initScriptPromise.resolve(data); } public isHeadlessBrowser (): boolean { @@ -382,7 +386,7 @@ export default class BrowserConnection extends EventEmitter { } if (this.status === BrowserConnectionStatus.opened) { - const testRunUrl = await this._getTestRunUrl(isTestDone || this.testRunAborted); + const testRunUrl = await this.getTestRunUrl(isTestDone || this.testRunAborted); this.testRunAborted = false; @@ -413,4 +417,8 @@ export default class BrowserConnection extends EventEmitter { this.status === BrowserConnectionStatus.opened || this.status === BrowserConnectionStatus.closing; } + + public async setUpBrowserWindow (): Promise { + return this.provider.setUpBrowserWindow(this.id); + } } diff --git a/src/browser/connection/setup-window-result.ts b/src/browser/connection/setup-window-result.ts new file mode 100644 index 00000000000..203c93f3433 --- /dev/null +++ b/src/browser/connection/setup-window-result.ts @@ -0,0 +1,6 @@ +enum SetupWindowResult { + ok = 'ok', + failed = 'failed' +} + +export default SetupWindowResult; diff --git a/src/browser/interfaces.ts b/src/browser/interfaces.ts new file mode 100644 index 00000000000..cdf07db339e --- /dev/null +++ b/src/browser/interfaces.ts @@ -0,0 +1,8 @@ +export interface WindowDimentionsInfo { + width: number; + height: number; + outerWidth: number; + outerHeight: number; + availableWidth: number; + availableHeight: number; +} diff --git a/src/browser/provider/built-in/dedicated/chrome/index.js b/src/browser/provider/built-in/dedicated/chrome/index.js index 193e1fd55a6..df56cfa2841 100644 --- a/src/browser/provider/built-in/dedicated/chrome/index.js +++ b/src/browser/provider/built-in/dedicated/chrome/index.js @@ -39,15 +39,18 @@ export default { await this.waitForConnectionReady(browserId); - runtimeInfo.viewportSize = await this.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); - runtimeInfo.activeWindowId = null; - if (allowMultipleWindows) runtimeInfo.activeWindowId = this.calculateWindowId(); await cdp.createClient(runtimeInfo); this.openedBrowsers[browserId] = runtimeInfo; + }, + + async resizeWindowAfterOpeningBrowser (browserId) { + const runtimeInfo = this.openedBrowsers[browserId]; + + runtimeInfo.viewportSize = await this.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); await this._ensureWindowIsExpanded(browserId, runtimeInfo.viewportSize); }, diff --git a/src/browser/provider/index.ts b/src/browser/provider/index.ts index 18f8dad74d1..b2b532d4180 100644 --- a/src/browser/provider/index.ts +++ b/src/browser/provider/index.ts @@ -3,12 +3,10 @@ import OS from 'os-family'; import { dirname } from 'path'; import makeDir from 'make-dir'; import BrowserConnection from '../connection'; -import delay from '../../utils/delay'; import { GET_TITLE_SCRIPT, GET_WINDOW_DIMENSIONS_INFO_SCRIPT } from './utils/client-functions'; import WARNING_MESSAGE from '../../notifications/warning-message'; import { Dictionary } from '../../configuration/interfaces'; - -const BROWSER_OPENING_DELAY = 2000; +import { WindowDimentionsInfo } from '../interfaces'; const RESIZE_DIFF_SIZE = { width: 100, @@ -94,17 +92,17 @@ export default class BrowserProvider { if (!await browserTools.isMaximized(title)) return; - const currentSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + const currentSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT) as WindowDimentionsInfo; const etalonSize = subtractSizes(currentSize, RESIZE_DIFF_SIZE); await browserTools.resize(title, currentSize.width, currentSize.height, etalonSize.width, etalonSize.height); - let resizedSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + let resizedSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT) as WindowDimentionsInfo; let correctionSize = subtractSizes(resizedSize, etalonSize); await browserTools.resize(title, resizedSize.width, resizedSize.height, etalonSize.width, etalonSize.height); - resizedSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + resizedSize = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT) as WindowDimentionsInfo; correctionSize = sumSizes(correctionSize, subtractSizes(resizedSize, etalonSize)); @@ -118,7 +116,7 @@ export default class BrowserProvider { if (!this._isBrowserIdle(browserId)) return; - const sizeInfo = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT); + const sizeInfo = await this.plugin.runInitScript(browserId, GET_WINDOW_DIMENSIONS_INFO_SCRIPT) as WindowDimentionsInfo; if (this.localBrowsersInfo[browserId]) { this.localBrowsersInfo[browserId].maxScreenSize = { @@ -134,10 +132,6 @@ export default class BrowserProvider { await this._ensureLocalBrowserInfo(browserId); - // NOTE: delay to ensure the window finished the opening - await this.plugin.waitForConnectionReady(browserId); - await delay(BROWSER_OPENING_DELAY); - if (this.localBrowsersInfo[browserId]) this.localBrowsersInfo[browserId].windowDescriptor = await browserTools.findWindow(browserId); } @@ -245,9 +239,6 @@ export default class BrowserProvider { public async openBrowser (browserId: string, pageUrl: string, browserName: string, allowMultipleWindows: boolean): Promise { await this.plugin.openBrowser(browserId, pageUrl, browserName, allowMultipleWindows); - - if (await this.canUseDefaultWindowActions(browserId)) - await this._ensureBrowserWindowParameters(browserId); } public async closeBrowser (browserId: string): Promise { @@ -354,4 +345,11 @@ export default class BrowserProvider { public setActiveWindowId (browserId: string, val: string): void { this.plugin.setActiveWindowId(browserId, val); } + + public async setUpBrowserWindow (browserId: string): Promise { + if (this.plugin.resizeWindowAfterOpeningBrowser) + await this.plugin.resizeWindowAfterOpeningBrowser(browserId); + + await this._ensureBrowserWindowParameters(browserId); + } } diff --git a/src/browser/provider/utils/client-functions.js b/src/browser/provider/utils/client-functions.ts similarity index 68% rename from src/browser/provider/utils/client-functions.js rename to src/browser/provider/utils/client-functions.ts index 6ef4cf0a878..103f713db8a 100644 --- a/src/browser/provider/utils/client-functions.js +++ b/src/browser/provider/utils/client-functions.ts @@ -1,9 +1,12 @@ /*eslint-disable no-undef, no-var*/ -function getTitle () { - return document.title; +import { WindowDimentionsInfo } from '../../interfaces'; + +function getTitle (): string { + // @ts-ignore + return window['%testCafeCore%'].domUtils.getDocumentTitle(document); } -function getWindowDimensionsInfo () { +function getWindowDimensionsInfo (): WindowDimentionsInfo { return { width: window.innerWidth, height: window.innerHeight, diff --git a/src/client/browser/index.js b/src/client/browser/index.js index e27f859ef10..43d1b17ea8f 100644 --- a/src/client/browser/index.js +++ b/src/client/browser/index.js @@ -88,7 +88,7 @@ function executeInitScript (initScriptUrl, createXHR) { if (!res.code) return null; - return sendXHR(initScriptUrl, createXHR, { method: 'POST', data: JSON.stringify(evaluate(res.code)) }); //eslint-disable-line no-restricted-globals + return sendXHR(initScriptUrl, createXHR, { method: 'POST', data: evaluate(res.code) }); }) .then(() => { window.setTimeout(() => executeInitScript(initScriptUrl, createXHR), 1000); @@ -163,6 +163,6 @@ export function getActiveWindowId (activeWindowIdUrl, createXHR) { export function setActiveWindowId (activeWindowIdUrl, createXHR, windowId) { return sendXHR(activeWindowIdUrl, createXHR, { method: 'POST', - data: JSON.stringify({ windowId }) //eslint-disable-line no-restricted-globals + data: { windowId } }); } diff --git a/src/client/core/utils/dom.js b/src/client/core/utils/dom.js index a8705e5df38..f4eed0c0473 100644 --- a/src/client/core/utils/dom.js +++ b/src/client/core/utils/dom.js @@ -516,3 +516,11 @@ export function contains (element, target) { return !!findParent(target, true, node => node === element); } + +export function setDocumentTitle (document, title) { + hammerhead.nativeMethods.documentTitleSetter.call(document, title); +} + +export function getDocumentTitle (document) { + return hammerhead.nativeMethods.documentTitleGetter.call(document); +} diff --git a/src/client/driver/driver.js b/src/client/driver/driver.js index 0886bca6051..c524768cac3 100644 --- a/src/client/driver/driver.js +++ b/src/client/driver/driver.js @@ -116,7 +116,7 @@ const STATUS_WITH_COMMAND_RESULT_EVENT = 'status-with-command-result-event'; const EMPTY_COMMAND_EVENT = 'empty-command-event'; export default class Driver extends serviceUtils.EventEmitter { - constructor (testRunId, communicationUrls, runInfo, options) { + constructor (testRunId, browserId, communicationUrls, runInfo, options) { super(); this.COMMAND_EXECUTING_FLAG = 'testcafe|driver|command-executing-flag'; @@ -124,10 +124,13 @@ export default class Driver extends serviceUtils.EventEmitter { this.PENDING_WINDOW_SWITCHING_FLAG = 'testcafe|driver|pending-window-switching-flag'; this.testRunId = testRunId; + this.browserId = browserId; this.heartbeatUrl = communicationUrls.heartbeat; this.browserStatusUrl = communicationUrls.status; this.browserStatusDoneUrl = communicationUrls.statusDone; this.browserActiveWindowId = communicationUrls.activeWindowId; + this.initScriptUrl = communicationUrls.initScriptUrl; + this.setupWindowUrl = communicationUrls.setupWindowUrl; this.userAgent = runInfo.userAgent; this.fixtureName = runInfo.fixtureName; this.testName = runInfo.testName; @@ -161,6 +164,9 @@ export default class Driver extends serviceUtils.EventEmitter { if (options.retryTestPages) browser.enableRetryingTestPages(); + browser.startHeartbeat(this.heartbeatUrl, hammerhead.createNativeXHR); + browser.startInitScriptExecution(this.initScriptUrl, hammerhead.createNativeXHR); + this.pageInitialRequestBarrier = new RequestBarrier(); this.readyPromise = eventUtils @@ -1127,13 +1133,21 @@ export default class Driver extends serviceUtils.EventEmitter { this.speed = this.initialSpeed; this._initConsoleMessages(); + this._setDocumentTitle(); + } + + _setDocumentTitle () { + const title = `[${this.browserId}]`; + + domUtils.setDocumentTitle(document, title); } _doFirstPageLoadSetup () { if (this.isFirstPageLoad && this.canUseDefaultWindowActions) { - // Stub: perform initial setup of the test first page - - return Promise.resolve(); + return browser.sendXHR(this.setupWindowUrl, hammerhead.createNativeXHR, { method: 'POST' }) + .then(() => { + browser.stopInitScriptExecution(); + }); } return Promise.resolve(); diff --git a/src/client/driver/iframe-driver.js b/src/client/driver/iframe-driver.js index 1414c3f03de..7a149512cb1 100644 --- a/src/client/driver/iframe-driver.js +++ b/src/client/driver/iframe-driver.js @@ -9,8 +9,8 @@ import { TYPE as MESSAGE_TYPE } from './driver-link/messages'; import IframeNativeDialogTracker from './native-dialog-tracker/iframe'; export default class IframeDriver extends Driver { - constructor (testRunId, options) { - super(testRunId, {}, {}, options); + constructor (testRunId, browserId, options) { + super(testRunId, browserId, {}, {}, options); this.lastParentDriverMessageId = null; this.parentDriverLink = new ParentIframeDriverLink(window.parent); diff --git a/src/client/test-run/iframe.js.mustache b/src/client/test-run/iframe.js.mustache index 0a7a0756a7d..e5ef0dfce3e 100644 --- a/src/client/test-run/iframe.js.mustache +++ b/src/client/test-run/iframe.js.mustache @@ -1,6 +1,6 @@ (function () { var IframeDriver = window['%testCafeIframeDriver%']; - var driver = new IframeDriver({{{testRunId}}}, { + var driver = new IframeDriver({{{testRunId}}}, {{{browserId}}} { selectorTimeout: {{{selectorTimeout}}}, pageLoadTimeout: {{{pageLoadTimeout}}}, dialogHandler: {{{dialogHandler}}}, diff --git a/src/client/test-run/index.js.mustache b/src/client/test-run/index.js.mustache index ac999e34e05..8252fea1c7e 100644 --- a/src/client/test-run/index.js.mustache +++ b/src/client/test-run/index.js.mustache @@ -19,6 +19,8 @@ var browserStatusUrl = origin + {{{browserStatusRelativeUrl}}}; var browserStatusDoneUrl = origin + {{{browserStatusDoneRelativeUrl}}}; var browserActiveWindowIdUrl = origin + {{{browserActiveWindowIdUrl}}}; + var browserInitScriptUrl = {{{browserInitScriptUrl}}}; + var browserSetupWindowUrl = {{{browserSetupWindowUrl}}}; var skipJsErrors = {{{skipJsErrors}}}; var dialogHandler = {{{dialogHandler}}}; var userAgent = {{{userAgent}}}; @@ -27,8 +29,12 @@ var canUseDefaultWindowActions = {{{canUseDefaultWindowActions}}}; var ClientDriver = window['%testCafeDriver%']; - var driver = new ClientDriver(testRunId, - { heartbeat: browserHeartbeatUrl, status: browserStatusUrl, statusDone: browserStatusDoneUrl, activeWindowId: browserActiveWindowIdUrl }, + var driver = new ClientDriver(testRunId, browserId, + { + heartbeat: browserHeartbeatUrl, status: browserStatusUrl, statusDone: browserStatusDoneUrl, + activeWindowId: browserActiveWindowIdUrl, initScriptUrl: browserInitScriptUrl, + setupWindowUrl: browserSetupWindowUrl + }, { userAgent: userAgent, fixtureName: fixtureName, testName: testName }, { selectorTimeout: selectorTimeout, diff --git a/src/test-run/index.js b/src/test-run/index.js index 26d7b051cc0..eaf25408d20 100644 --- a/src/test-run/index.js +++ b/src/test-run/index.js @@ -238,6 +238,8 @@ export default class TestRun extends AsyncEventEmitter { browserStatusRelativeUrl: JSON.stringify(this.browserConnection.statusRelativeUrl), browserStatusDoneRelativeUrl: JSON.stringify(this.browserConnection.statusDoneRelativeUrl), browserActiveWindowIdUrl: JSON.stringify(this.browserConnection.activeWindowIdUrl), + browserInitScriptUrl: JSON.stringify(this.browserConnection.initScriptUrl), + browserSetupWindowUrl: JSON.stringify(this.browserConnection.setupWindowUrl), userAgent: JSON.stringify(this.browserConnection.userAgent), testName: JSON.stringify(this.test.name), fixtureName: JSON.stringify(this.test.fixture.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 5a87ba95dda..7f4f1702f48 100644 --- a/test/functional/fixtures/api/es-next/take-screenshot/test.js +++ b/test/functional/fixtures/api/es-next/take-screenshot/test.js @@ -4,6 +4,7 @@ const chai = require('chai'); const { expect } = chai; const config = require('../../../../config.js'); const assertionHelper = require('../../../../assertion-helper.js'); +const { noop } = require('lodash'); chai.use(require('chai-string')); @@ -41,12 +42,9 @@ const getReporter = function (scope) { reportTestStart: (name, meta, { testRunIds }) => { scope.testRunIds = testRunIds; }, - reportFixtureStart: () => { - }, - reportTaskStart: () => { - }, - reportTaskDone: () => { - } + reportFixtureStart: noop, + reportTaskStart: noop, + reportTaskDone: noop }; }; }; diff --git a/test/functional/fixtures/browser-provider/browser-reconnect/test.js b/test/functional/fixtures/browser-provider/browser-reconnect/test.js index a2007835bf6..eacafd48bc7 100644 --- a/test/functional/fixtures/browser-provider/browser-reconnect/test.js +++ b/test/functional/fixtures/browser-provider/browser-reconnect/test.js @@ -3,6 +3,7 @@ const expect = require('chai').expect; const config = require('../../../config'); const browserProviderPool = require('../../../../../lib/browser/provider/pool'); const BrowserConnection = require('../../../../../lib/browser/connection'); +const { noop } = require('lodash'); let errors = null; @@ -11,12 +12,9 @@ function customReporter () { reportTestDone (name, testRunInfo) { errors = testRunInfo.errs; }, - reportFixtureStart () { - }, - reportTaskStart () { - }, - reportTaskDone () { - } + reportFixtureStart: noop, + reportTaskStart: noop, + reportTaskDone: noop }; } diff --git a/test/functional/fixtures/concurrency/test.js b/test/functional/fixtures/concurrency/test.js index ce789558985..9397517517d 100644 --- a/test/functional/fixtures/concurrency/test.js +++ b/test/functional/fixtures/concurrency/test.js @@ -1,8 +1,8 @@ -const path = require('path'); -const expect = require('chai').expect; -const isCI = require('is-ci'); -const config = require('../../config'); - +const path = require('path'); +const { expect } = require('chai'); +const isCI = require('is-ci'); +const config = require('../../config'); +const { noop } = require('lodash'); if (config.useLocalBrowsers) { describe('Concurrency', function () { @@ -75,13 +75,9 @@ if (config.useLocalBrowsers) { this.write('Fixture ' + name + ' started').newline(); }, - reportTaskStart: function () { - - }, - - reportTaskDone: function () { + reportTaskStart: noop, - } + reportTaskDone: noop }; } diff --git a/test/functional/fixtures/regression/gh-3835/test.js b/test/functional/fixtures/regression/gh-3835/test.js index 635a3368a2c..bda02f17f04 100644 --- a/test/functional/fixtures/regression/gh-3835/test.js +++ b/test/functional/fixtures/regression/gh-3835/test.js @@ -1,4 +1,5 @@ -const expect = require('chai').expect; +const { expect } = require('chai'); +const { noop } = require('lodash'); function timeout (ms) { return new Promise(resolve => setTimeout(resolve, ms)); @@ -12,13 +13,10 @@ const getReporter = function (delay) { return { name: () => { return { - reportTestDone () { - }, - reportFixtureStart: () => { - }, - reportTaskStart: () => { - }, - reportTaskDone: async () => { + reportTestDone: noop, + reportFixtureStart: noop, + reportTaskStart: noop, + reportTaskDone: async () => { startedReportTaskCount++; await timeout(delay); diff --git a/test/functional/fixtures/regression/gh-4675/test.js b/test/functional/fixtures/regression/gh-4675/test.js index ffe0f052409..6b06809d3fb 100644 --- a/test/functional/fixtures/regression/gh-4675/test.js +++ b/test/functional/fixtures/regression/gh-4675/test.js @@ -1,18 +1,19 @@ const path = require('path'); -const expect = require('chai').expect; +const { expect } = require('chai'); const createTestCafe = require('../../../../../lib'); const config = require('../../../config.js'); +const { noop } = require('lodash'); function customReporter (name) { return () => { return { - name: name, - reportTestDone () { }, - reportFixtureStart () { }, + name: name, + reportTestDone: noop, + reportFixtureStart: noop, reportTaskStart () { this.write(''); }, - reportTaskDone () { } + reportTaskDone: noop }; }; } diff --git a/test/functional/fixtures/regression/gh-4725/test.js b/test/functional/fixtures/regression/gh-4725/test.js index 2ab46af0ba1..7392c7e7b44 100644 --- a/test/functional/fixtures/regression/gh-4725/test.js +++ b/test/functional/fixtures/regression/gh-4725/test.js @@ -1,4 +1,5 @@ -const expect = require('chai').expect; +const { expect } = require('chai'); +const { noop } = require('lodash'); const log = []; @@ -10,12 +11,9 @@ function customReporter () { reportTestDone (name) { log.push(`done: ${name}`); }, - reportFixtureStart () { - }, - reportTaskStart () { - }, - reportTaskDone () { - } + reportFixtureStart: noop, + reportTaskStart: noop, + reportTaskDone: noop }; } diff --git a/test/functional/fixtures/regression/gh-4787/test.js b/test/functional/fixtures/regression/gh-4787/test.js index 5a0404f57c3..d4c07a60bc0 100644 --- a/test/functional/fixtures/regression/gh-4787/test.js +++ b/test/functional/fixtures/regression/gh-4787/test.js @@ -1,4 +1,4 @@ -const expect = require('chai').expect; +const { expect } = require('chai'); const path = require('path'); const createTestCafe = require('../../../../../lib'); const config = require('../../../config.js'); diff --git a/test/server/browser-connection-test.js b/test/server/browser-connection-test.js index 4fd2b71acc4..e4a00c509e4 100644 --- a/test/server/browser-connection-test.js +++ b/test/server/browser-connection-test.js @@ -5,6 +5,7 @@ const createTestCafe = require('../../lib/'); const COMMAND = require('../../lib/browser/connection/command'); const browserProviderPool = require('../../lib/browser/provider/pool'); const BrowserConnectionStatus = require('../../lib/browser/connection/status'); +const { noop } = require('lodash'); const promisedRequest = promisify(request); @@ -23,6 +24,11 @@ describe('Browser connection', function () { } }; + const jobMock = { + popNextTestRunUrl: async () => 'first tested page url', + hasQueuedTestRuns: true + }; + before(function () { this.timeout(20000); @@ -50,6 +56,12 @@ describe('Browser connection', function () { .createBrowserConnection() .then(function (bc) { connection = bc; + + connection.on('ready', () => { + process.nextTick(() => { + connection.addJob(jobMock); + }); + }); }); }); @@ -58,10 +70,10 @@ describe('Browser connection', function () { connection.close(); }); - it('Should fire "ready" event and redirect to idle page once established', function () { + it('Should fire "ready" event and redirect to idle page once established', () => { let eventFired = false; - connection.on('ready', function () { + connection.on('ready', () => { eventFired = true; }); @@ -75,7 +87,7 @@ describe('Browser connection', function () { }; return promisedRequest(options) - .then(function (res) { + .then(res => { expect(eventFired).to.be.true; expect(connection.status).eql(BrowserConnectionStatus.opened); expect(connection.userAgent).eql('Chrome 41.0.2227.1 / macOS 10.10.1'); @@ -84,12 +96,12 @@ describe('Browser connection', function () { }); }); - it('Should respond with error if connection was established twice', function () { + it('Should respond with error if connection was established twice', () => { return promisedRequest(connection.url) - .then(function () { + .then(() => { return promisedRequest(connection.url); }) - .then(function (res) { + .then(res => { expect(res.statusCode).eql(500); expect(res.body).eql('The connection is already established.'); }); @@ -116,71 +128,69 @@ describe('Browser connection', function () { request(options); }); - it('Should provide status', function () { + it('Should provide status', () => { function createBrowserJobMock (urls) { return { - popNextTestRunUrl: function () { - const url = urls.shift(); - - return url; - }, + popNextTestRunUrl: () => urls.shift(), get hasQueuedTestRuns () { return urls.length; }, - once: function () { - // Do nothing =) - }, + once: noop, - on: function () { - // Do nothing - } + on: noop }; } - connection.addJob(createBrowserJobMock(['1', '2'])); - connection.addJob(createBrowserJobMock(['3'])); - function queryStatus () { return promisedRequest(connection.statusDoneUrl); } - return promisedRequest(connection.url) + connection.on('ready', () => { + process.nextTick(() => { + connection.jobQueue.length = 0; + + connection.addJob(createBrowserJobMock(['1', '2'])); + connection.addJob(createBrowserJobMock(['3'])); + }); + }); + return promisedRequest(connection.url) .then(queryStatus) - .then(function (res) { + .then(res => { expect(JSON.parse(res.body)).eql({ cmd: COMMAND.run, url: '1' }); }) .then(queryStatus) - .then(function (res) { + .then(res => { expect(JSON.parse(res.body)).eql({ cmd: COMMAND.run, url: '2' }); }) .then(queryStatus) - .then(function (res) { + .then(res => { expect(JSON.parse(res.body)).eql({ cmd: COMMAND.run, url: '3' }); }) .then(queryStatus) - .then(function (res) { + .then(res => { expect(JSON.parse(res.body)).eql({ cmd: COMMAND.idle, url: connection.idleUrl }); }); }); - it('Should respond to the service queries with error if not ready', function () { + it('Should respond to the service queries with error if not ready', () => { let testCases = [ connection.heartbeatUrl, connection.idleUrl, connection.statusUrl ]; - testCases = testCases.map(function (url) { - return promisedRequest(url).then(function (res) { - expect(res.statusCode).eql(500); - expect(res.body).eql('The connection is not ready yet.'); - }); + testCases = testCases.map(url => { + return promisedRequest(url) + .then(res => { + expect(res.statusCode).eql(500); + expect(res.body).eql('The connection is not ready yet.'); + }); }); return Promise.all(testCases); diff --git a/test/server/reporter-test.js b/test/server/reporter-test.js index 6613e726787..fd0de1e3fd6 100644 --- a/test/server/reporter-test.js +++ b/test/server/reporter-test.js @@ -1,9 +1,9 @@ -const { expect } = require('chai'); -const { chunk, random } = require('lodash'); -const Reporter = require('../../lib/reporter'); -const Task = require('../../lib/runner/task'); -const Videos = require('../../lib/video-recorder/videos'); -const delay = require('../../lib/utils/delay'); +const { expect } = require('chai'); +const { chunk, random, noop } = require('lodash'); +const Reporter = require('../../lib/reporter'); +const Task = require('../../lib/runner/task'); +const Videos = require('../../lib/video-recorder/videos'); +const delay = require('../../lib/utils/delay'); describe('Reporter', () => { // Runnable configuration mocks @@ -1041,15 +1041,11 @@ describe('Reporter', () => { function createReporter () { return new Reporter({ - reportTaskStart: function () { - }, - reportTaskDone: function () { - }, - reportFixtureStart: function () { - }, - reportTestStart: function () { - }, - reportTestDone: function (name, testRunInfo) { + reportTaskStart: noop, + reportTaskDone: noop, + reportFixtureStart: noop, + reportTestStart: noop, + reportTestDone: function (name, testRunInfo) { videoLog.push(testRunInfo.videos); } }, taskMock); diff --git a/test/server/runner-test.js b/test/server/runner-test.js index 5ffff027821..93dde460b28 100644 --- a/test/server/runner-test.js +++ b/test/server/runner-test.js @@ -60,6 +60,7 @@ describe('Runner', () => { browserProviderPool.addProvider('remote', origRemoteBrowserProvider); connection.close(); + return testCafe.close(); }); @@ -941,6 +942,11 @@ describe('Runner', () => { } }; + const jobMock = { + popNextTestRunUrl: async () => 'first tested page url', + hasQueuedTestRuns: true + }; + function taskDone () { this.pendingBrowserJobs.forEach(job => { this.emit('browser-job-done', job); @@ -973,7 +979,11 @@ describe('Runner', () => { setTimeout(taskActionCallback.bind(this), TASK_ACTION_DELAY); return this.browserConnectionGroups.map(bcGroup => { - return { browserConnections: bcGroup }; + bcGroup.map(bc => bc.addJob(jobMock)); + + jobMock.browserConnections = bcGroup; + + return jobMock; }); };