diff --git a/lib/core/client.js b/lib/core/client.js index f99446589d..ee1aa3f9d9 100644 --- a/lib/core/client.js +++ b/lib/core/client.js @@ -13,6 +13,7 @@ const ElementGlobal = require('../api/_loaders/element-global.js'); const Factory = require('../transport/factory.js'); const {isAndroid, isIos} = require('../utils/mobile'); const namespacedApi = require('../core/namespaced-api.js'); +const cdp = require('../transport/selenium-webdriver/cdp.js'); const {LocateStrategy, Locator} = Element; const {Logger, isUndefined, isDefined, isObject, isFunction, isSafari, isChrome} = Utils; @@ -757,6 +758,9 @@ class NightwatchClient extends EventEmitter { Logger.info(`Received session with ID: ${data.sessionId}\n`); + // Reset cdp connection every time a new webdriver session is created. + cdp.resetConnection(); + this.emit('nightwatch:session.create', data); return data; diff --git a/lib/transport/selenium-webdriver/index.js b/lib/transport/selenium-webdriver/index.js index 1622b53048..72e9de4eba 100644 --- a/lib/transport/selenium-webdriver/index.js +++ b/lib/transport/selenium-webdriver/index.js @@ -8,7 +8,6 @@ const {IosSessionNotCreatedError, AndroidConnectionError} = require('../../utils const httpClient = require('./httpclient.js'); const Session = require('./session.js'); const BaseTransport = require('../'); -const CDP = require('./cdp.js'); const {colors} = Logger; const {isErrorResponse, checkLegacyResponse, throwDecodedError, WebDriverError} = error; const {IosSessionErrors} = require('../errors'); @@ -189,7 +188,7 @@ class Transport extends BaseTransport { async sessionFinished(reason) { this.emit('session:finished', reason); - CDP.resetConnection(); + await this.closeDriver(); } diff --git a/lib/transport/selenium-webdriver/method-mappings.js b/lib/transport/selenium-webdriver/method-mappings.js index f06f112f1c..1ccf27271e 100644 --- a/lib/transport/selenium-webdriver/method-mappings.js +++ b/lib/transport/selenium-webdriver/method-mappings.js @@ -1062,7 +1062,7 @@ module.exports = class MethodMappings { /////////////////////////////////////////////////////////////////////////// async registerAuth(username, password) { - const cdpConnection = await cdp.getConnection(this.driver); + const cdpConnection = await cdp.getConnection(this.driver, true); await this.driver.register(username, password, cdpConnection); return { diff --git a/test/lib/command-mocks.js b/test/lib/command-mocks.js index 4f79dcc93a..78220abbec 100644 --- a/test/lib/command-mocks.js +++ b/test/lib/command-mocks.js @@ -453,7 +453,8 @@ module.exports = { sessionId = '13521-10219-202', headless = true, deleteSession = true, - url = '/wd/hub/session' + url = '/wd/hub/session', + times = 0 }) { const browserName = 'chrome'; const headlessOpt = headless ? 'headless=new' : ''; @@ -472,7 +473,7 @@ module.exports = { postdata: JSON.stringify({ capabilities: {firstMatch: [{}], alwaysMatch: {browserName, ...options}} }), - + times, response: JSON.stringify({ value: { sessionId, @@ -486,16 +487,19 @@ module.exports = { }, !persist); if (!deleteSession) { - return; + return this; } MockServer.addMock({ - url: `/session/${sessionId}`, + url: `${url}/${sessionId}`, method: 'DELETE', + times, response: { value: null } }, !persist); + + return this; }, createNewW3CSession({ diff --git a/test/src/apidemos/cdp/testCdpCommands.js b/test/src/apidemos/cdp/testCdpCommands.js index 90e45ca6d1..d368b040ab 100644 --- a/test/src/apidemos/cdp/testCdpCommands.js +++ b/test/src/apidemos/cdp/testCdpCommands.js @@ -26,16 +26,16 @@ describe('cdp commands test', function() { }); }); - it('reset cdp connection after each session', function() { + it('reset cdp connection after each session is created', function() { const testsPath = [path.join(__dirname, '../../../apidemos/cdp')]; - let resetConnectionCalled = false; + let resetConnectionCalled = 0; - mockery.registerMock('./cdp.js', { + mockery.registerMock('../transport/selenium-webdriver/cdp.js', { getConnection: function(...args) { return Promise.resolve(); }, resetConnection: function() { - resetConnectionCalled = true; + resetConnectionCalled += 1; } }); @@ -49,7 +49,6 @@ describe('cdp commands test', function() { }) .navigateTo({url: 'http://localhost', persist: true}); - const globals = { calls: 0, @@ -57,9 +56,9 @@ describe('cdp commands test', function() { waitForConditionTimeout: 120, retryAssertionTimeout: 1000, - reporter(results) { - assert.strictEqual(resetConnectionCalled, true); + // cdp connection is reset once for each session (two test suites). + assert.strictEqual(resetConnectionCalled, 2); if (results.lastError) { throw results.lastError; } @@ -77,5 +76,64 @@ describe('cdp commands test', function() { })); }); - + it('reset cdp connection after each selenium session is created', function() { + const testsPath = [path.join(__dirname, '../../../apidemos/cdp')]; + let resetConnectionCalled = 0; + + Mocks + .createChromeSession({ + headless: false, + times: 2 + }); + + MockServer.addMock({ + url: '/wd/hub/session/13521-10219-202/url', + method: 'POST', + postdata: JSON.stringify({ + url: 'http://localhost' + }), + response: { + value: null + }, + times: 2 + }); + + mockery.registerMock('../transport/selenium-webdriver/cdp.js', { + getConnection: function(...args) { + return Promise.resolve(); + }, + resetConnection: function() { + resetConnectionCalled += 1; + } + }); + + const globals = { + calls: 0, + waitForConditionPollInterval: 50, + waitForConditionTimeout: 120, + retryAssertionTimeout: 1000, + + reporter(results) { + // cdp connection is reset once for each session (two test suites). + assert.strictEqual(resetConnectionCalled, 2); + if (results.lastError) { + throw results.lastError; + } + } + }; + + return NightwatchClient.runTests(testsPath, settings({ + desiredCapabilities: { + browserName: 'chrome' + }, + selenium: { + host: 'localhost', + port: 10195, + start_process: false + }, + output: false, + skip_testcases_on_fail: false, + globals + })); + }); });