diff --git a/README.md b/README.md index 7267cb8e8..374884ad3 100644 --- a/README.md +++ b/README.md @@ -1098,6 +1098,20 @@ Allows to intercept [HTTP request options](https://github.com/sindresorhus/got#o (RequestOptions) => RequestOptions ``` +In runtime a unique `X-Request-ID` header is generated for each browser request which consists of `${FIRST_X_REQ_ID}__${LAST_X_REQ_ID}`, where: +- `FIRST_X_REQ_ID` - unique uuid for each test (different for each retry), allows to find all requests related to a single test run; +- `LAST_X_REQ_ID` - unique uuid for each browser request, allows to find one unique request in one test (together with `FIRST_X_REQ_ID`). + +Header `X-Request-ID` can be useful if you manage the cloud with browsers yourself and collect logs with requests. Real-world example: `2f31ffb7-369d-41f4-bbb8-77744615d2eb__e8d011d8-bb76-42b9-b80e-02f03b8d6fe1`. + +To override generated `X-Request-ID` to your own value you need specify it in `transformRequest` handler. Example: + +```javascript +transformRequest: (req) => { + req.handler["X-Request-ID"] = "my_x_req_id"; +} +``` + #### transformResponse Allows to intercept [HTTP response object](https://github.com/sindresorhus/got#response) after a WebDriver response has arrived. Default value is `null`. If function is passed then it takes `Response` (original response object) as the first and `RequestOptions` as the second argument. Should return modified `Response`. Example: diff --git a/src/browser-pool/basic-pool.js b/src/browser-pool/basic-pool.js index 495ae8444..f1e539b61 100644 --- a/src/browser-pool/basic-pool.js +++ b/src/browser-pool/basic-pool.js @@ -23,8 +23,7 @@ module.exports = class BasicPool extends Pool { } async getBrowser(id, opts = {}) { - const { version } = opts; - const browser = Browser.create(this._config, id, version); + const browser = Browser.create(this._config, { ...opts, id }); try { await browser.init(); diff --git a/src/browser/browser.js b/src/browser/browser.js index 58d4619ba..0f79298fb 100644 --- a/src/browser/browser.js +++ b/src/browser/browser.js @@ -1,7 +1,9 @@ "use strict"; +const crypto = require("crypto"); const _ = require("lodash"); const { SAVE_HISTORY_MODE } = require("../constants/config"); +const { X_REQUEST_ID_DELIMITER } = require("../constants/browser"); const history = require("./history"); const addRunStepCommand = require("./commands/runStep"); @@ -19,13 +21,14 @@ const CUSTOM_SESSION_OPTS = [ ]; module.exports = class Browser { - static create(config, id, version) { - return new this(config, id, version); + static create(config, opts) { + return new this(config, opts); } - constructor(config, id, version) { - this.id = id; - this.version = version; + constructor(config, opts) { + this.id = opts.id; + this.version = opts.version; + this.testXReqId = opts.testXReqId; this._config = config.forBrowser(this.id); this._debug = config.system.debug; @@ -82,7 +85,21 @@ module.exports = class Browser { _getSessionOptsFromConfig(optNames = CUSTOM_SESSION_OPTS) { return optNames.reduce((options, optName) => { - if (!_.isNull(this._config[optName])) { + if (optName === "transformRequest") { + options[optName] = req => { + if (!_.isNull(this._config[optName])) { + req = this._config[optName](req); + } + + if (!req.headers["X-Request-ID"]) { + req.headers["X-Request-ID"] = `${ + this.testXReqId + }${X_REQUEST_ID_DELIMITER}${crypto.randomUUID()}`; + } + + return req; + }; + } else if (!_.isNull(this._config[optName])) { options[optName] = this._config[optName]; } diff --git a/src/browser/existing-browser.js b/src/browser/existing-browser.js index d55ae8749..174cf119f 100644 --- a/src/browser/existing-browser.js +++ b/src/browser/existing-browser.js @@ -19,14 +19,14 @@ const { isSupportIsolation } = require("../utils/browser"); const OPTIONAL_SESSION_OPTS = ["transformRequest", "transformResponse"]; module.exports = class ExistingBrowser extends Browser { - static create(config, id, version, emitter) { - return new this(config, id, version, emitter); + static create(config, opts) { + return new this(config, opts); } - constructor(config, id, version, emitter) { - super(config, id, version); + constructor(config, opts) { + super(config, opts); - this._emitter = emitter; + this._emitter = opts.emitter; this._camera = Camera.create(this._config.screenshotMode, () => this._takeScreenshot()); this._meta = this._initMeta(); @@ -169,7 +169,7 @@ module.exports = class ExistingBrowser extends Browser { return { pid: process.pid, browserVersion: this.version, - "X-Request-ID": this._config.headers["X-Request-ID"], + testXReqId: this.testXReqId, ...this._config.meta, }; } diff --git a/src/browser/new-browser.js b/src/browser/new-browser.js index 6368085a0..011400e08 100644 --- a/src/browser/new-browser.js +++ b/src/browser/new-browser.js @@ -31,8 +31,8 @@ const headlessBrowserOptions = { }; module.exports = class NewBrowser extends Browser { - constructor(config, id, version) { - super(config, id, version); + constructor(config, opts) { + super(config, opts); signalHandler.on("exit", () => this.quit()); } diff --git a/src/constants/browser.ts b/src/constants/browser.ts index f7772cf45..cbbbe5eb4 100644 --- a/src/constants/browser.ts +++ b/src/constants/browser.ts @@ -1 +1,2 @@ export const MIN_CHROME_VERSION_SUPPORT_ISOLATION = 93; +export const X_REQUEST_ID_DELIMITER = "__"; diff --git a/src/runner/browser-agent.js b/src/runner/browser-agent.js index 7d6252ef1..0bd43b343 100644 --- a/src/runner/browser-agent.js +++ b/src/runner/browser-agent.js @@ -1,11 +1,11 @@ "use strict"; module.exports = class BrowserAgent { - static create(id, version, pool) { - return new this(id, version, pool); + static create(opts = {}) { + return new this(opts); } - constructor(id, version, pool) { + constructor({ id, version, pool }) { this.browserId = id; this._version = version; diff --git a/src/runner/browser-runner.ts b/src/runner/browser-runner.ts index 583a3fc3e..75286dac2 100644 --- a/src/runner/browser-runner.ts +++ b/src/runner/browser-runner.ts @@ -60,7 +60,11 @@ export class BrowserRunner extends Runner { } private async _runTest(test: Test): Promise { - const browserAgent = BrowserAgent.create(this._browserId, test.browserVersion, this.browserPool); + const browserAgent = BrowserAgent.create({ + id: this._browserId, + version: test.browserVersion, + pool: this.browserPool, + }); const runner = TestRunner.create(test, this.config, browserAgent); runner.on(MasterEvents.TEST_BEGIN, (test: Test) => this.suiteMonitor.testBegin(test)); diff --git a/src/runner/test-runner/high-priority-browser-agent.js b/src/runner/test-runner/high-priority-browser-agent.js index 6099d358d..389d45cfe 100644 --- a/src/runner/test-runner/high-priority-browser-agent.js +++ b/src/runner/test-runner/high-priority-browser-agent.js @@ -9,8 +9,8 @@ module.exports = class HighPriorityBrowserAgent { this._browserAgent = browserAgent; } - getBrowser() { - return this._browserAgent.getBrowser({ highPriority: true }); + getBrowser(opts = {}) { + return this._browserAgent.getBrowser({ ...opts, highPriority: true }); } freeBrowser(...args) { diff --git a/src/runner/test-runner/regular-test-runner.js b/src/runner/test-runner/regular-test-runner.js index 449bd9c9a..f551498ec 100644 --- a/src/runner/test-runner/regular-test-runner.js +++ b/src/runner/test-runner/regular-test-runner.js @@ -1,5 +1,6 @@ "use strict"; +const crypto = require("crypto"); const _ = require("lodash"); const { Runner } = require("../runner"); const logger = require("../../utils/logger"); @@ -64,6 +65,7 @@ module.exports = class RegularTestRunner extends Runner { sessionCaps: this._browser.capabilities, sessionOpts: this._browser.publicAPI.options, file: this._test.file, + testXReqId: this._browser.testXReqId, }); } @@ -80,7 +82,7 @@ module.exports = class RegularTestRunner extends Runner { async _getBrowser() { try { - this._browser = await this._browserAgent.getBrowser(); + this._browser = await this._browserAgent.getBrowser({ testXReqId: crypto.randomUUID() }); this._test.sessionId = this._browser.sessionId; return this._browser; diff --git a/src/worker/hermione.ts b/src/worker/hermione.ts index 3f017654e..cd7ddb111 100644 --- a/src/worker/hermione.ts +++ b/src/worker/hermione.ts @@ -11,6 +11,7 @@ export interface WorkerRunTestOpts { sessionId: string; sessionCaps: WdioBrowser["capabilities"]; sessionOpts: WdioBrowser["options"]; + testXReqId: string; } export interface AssertViewResultsSuccess { diff --git a/src/worker/runner/browser-agent.js b/src/worker/runner/browser-agent.js index ce7f29783..43bf7d0e7 100644 --- a/src/worker/runner/browser-agent.js +++ b/src/worker/runner/browser-agent.js @@ -1,24 +1,25 @@ "use strict"; module.exports = class BrowserAgent { - static create(browserId, browserVersion, pool) { - return new BrowserAgent(browserId, browserVersion, pool); + static create(opts) { + return new this(opts); } - constructor(browserId, browserVersion, pool) { - this.browserId = browserId; - this.browserVersion = browserVersion; + constructor({ id, version, pool }) { + this.browserId = id; + this.browserVersion = version; this._pool = pool; } - getBrowser({ sessionId, sessionCaps, sessionOpts }) { + getBrowser({ sessionId, sessionCaps, sessionOpts, testXReqId }) { return this._pool.getBrowser({ browserId: this.browserId, browserVersion: this.browserVersion, sessionId, sessionCaps, sessionOpts, + testXReqId, }); } diff --git a/src/worker/runner/browser-pool.js b/src/worker/runner/browser-pool.js index 1796cae2e..c81ab468c 100644 --- a/src/worker/runner/browser-pool.js +++ b/src/worker/runner/browser-pool.js @@ -16,8 +16,13 @@ module.exports = class BrowserPool { this._calibrator = new Calibrator(); } - async getBrowser({ browserId, browserVersion, sessionId, sessionCaps, sessionOpts }) { - const browser = Browser.create(this._config, browserId, browserVersion, this._emitter); + async getBrowser({ browserId, browserVersion, sessionId, sessionCaps, sessionOpts, testXReqId }) { + const browser = Browser.create(this._config, { + id: browserId, + version: browserVersion, + testXReqId, + emitter: this._emitter, + }); try { await browser.init({ sessionId, sessionCaps, sessionOpts }, this._calibrator); diff --git a/src/worker/runner/index.js b/src/worker/runner/index.js index 4fcf3bbe8..e67f06041 100644 --- a/src/worker/runner/index.js +++ b/src/worker/runner/index.js @@ -27,12 +27,12 @@ module.exports = class Runner extends AsyncEmitter { ]); } - async runTest(fullTitle, { browserId, browserVersion, file, sessionId, sessionCaps, sessionOpts }) { + async runTest(fullTitle, { browserId, browserVersion, file, sessionId, sessionCaps, sessionOpts, testXReqId }) { const tests = await this._testParser.parse({ file, browserId }); const test = tests.find(t => t.fullTitle() === fullTitle); - const browserAgent = BrowserAgent.create(browserId, browserVersion, this._browserPool); + const browserAgent = BrowserAgent.create({ id: browserId, version: browserVersion, pool: this._browserPool }); const runner = TestRunner.create(test, this._config.forBrowser(browserId), browserAgent); - return runner.run({ sessionId, sessionCaps, sessionOpts }); + return runner.run({ sessionId, sessionCaps, sessionOpts, testXReqId }); } }; diff --git a/src/worker/runner/test-runner/index.js b/src/worker/runner/test-runner/index.js index ace64318b..15e148580 100644 --- a/src/worker/runner/test-runner/index.js +++ b/src/worker/runner/test-runner/index.js @@ -22,14 +22,14 @@ module.exports = class TestRunner { this._browserAgent = browserAgent; } - async run({ sessionId, sessionCaps, sessionOpts }) { + async run({ sessionId, sessionCaps, sessionOpts, testXReqId }) { const test = this._test; const hermioneCtx = test.hermioneCtx || {}; let browser; try { - browser = await this._browserAgent.getBrowser({ sessionId, sessionCaps, sessionOpts }); + browser = await this._browserAgent.getBrowser({ sessionId, sessionCaps, sessionOpts, testXReqId }); } catch (e) { throw Object.assign(e, { hermioneCtx }); } diff --git a/test/src/browser-pool/basic-pool.js b/test/src/browser-pool/basic-pool.js index 5a46fbd48..f5095ed40 100644 --- a/test/src/browser-pool/basic-pool.js +++ b/test/src/browser-pool/basic-pool.js @@ -33,13 +33,13 @@ describe("browser-pool/basic-pool", () => { await mkPool_({ config }).getBrowser("broId"); - assert.calledWith(Browser.create, config, "broId"); + assert.calledWith(Browser.create, config, { id: "broId" }); }); it("should create new browser with specified version when requested", async () => { await mkPool_().getBrowser("broId", { version: "1.0" }); - assert.calledWith(Browser.create, sinon.match.any, "broId", "1.0"); + assert.calledWith(Browser.create, sinon.match.any, { id: "broId", version: "1.0" }); }); it("should init browser", async () => { diff --git a/test/src/browser/existing-browser.js b/test/src/browser/existing-browser.js index 4df1ca0a5..2d57a3c69 100644 --- a/test/src/browser/existing-browser.js +++ b/test/src/browser/existing-browser.js @@ -1,6 +1,7 @@ "use strict"; const { EventEmitter } = require("events"); +const crypto = require("crypto"); const _ = require("lodash"); const Promise = require("bluebird"); const webdriverio = require("webdriverio"); @@ -12,7 +13,7 @@ const clientBridge = require("src/browser/client-bridge"); const logger = require("src/utils/logger"); const history = require("src/browser/history"); const { SAVE_HISTORY_MODE, WEBDRIVER_PROTOCOL, DEVTOOLS_PROTOCOL } = require("src/constants/config"); -const { MIN_CHROME_VERSION_SUPPORT_ISOLATION } = require("src/constants/browser"); +const { MIN_CHROME_VERSION_SUPPORT_ISOLATION, X_REQUEST_ID_DELIMITER } = require("src/constants/browser"); const { mkExistingBrowser_: mkBrowser_, mkSessionStub_, @@ -56,7 +57,7 @@ describe("ExistingBrowser", () => { it("should set emitter", () => { const emitter = new EventEmitter(); - const browser = mkBrowser_({}, "bro", null, emitter); + const browser = mkBrowser_({}, { emitter }); assert.deepEqual(browser.emitter, emitter); }); @@ -69,7 +70,7 @@ describe("ExistingBrowser", () => { }); it("should extend meta-info with browserVersion by default", () => { - const browser = mkBrowser_({}, "bro-id", "10.1"); + const browser = mkBrowser_({}, { id: "bro-id", version: "10.1" }); assert.propertyVal(browser.meta, "browserVersion", "10.1"); }); @@ -79,6 +80,12 @@ describe("ExistingBrowser", () => { assert.propertyVal(browser.meta, "k1", "v1"); }); + + it('should extend meta-info with "testXReqId" field', () => { + const browser = mkBrowser_({}, { testXReqId: "12345" }); + + assert.propertyVal(browser.meta, "testXReqId", "12345"); + }); }); describe("Camera", () => { @@ -136,21 +143,63 @@ describe("ExistingBrowser", () => { assert.calledWithMatch(webdriverio.attach, { foo: "bar" }); }); - it('should attach to browser with "transform*" options from browser config', async () => { - const transformRequestStub = sinon.stub(); - const transformResponseStub = sinon.stub(); + describe("transformRequest option", () => { + beforeEach(() => { + sandbox.stub(crypto, "randomUUID").returns("00000"); + }); - await initBrowser_( - mkBrowser_({ - transformRequest: transformRequestStub, - transformResponse: transformResponseStub, - }), - ); + it("should call user handler from config", async () => { + const request = { headers: {} }; + const transformRequestStub = sinon.stub().returns(request); - assert.calledOnce(webdriverio.attach); - assert.calledWithMatch(webdriverio.attach, { - transformRequest: transformRequestStub, - transformResponse: transformResponseStub, + await initBrowser_(mkBrowser_({ transformRequest: transformRequestStub })); + + const { transformRequest } = webdriverio.attach.lastCall.args[0]; + transformRequest(request); + + assert.calledOnceWith(transformRequestStub, request); + }); + + it('should not add "X-Request-ID" header if it is already add by user', async () => { + const request = { headers: {} }; + const transformRequestStub = req => { + req.headers["X-Request-ID"] = "100500"; + return req; + }; + + await initBrowser_(mkBrowser_({ transformRequest: transformRequestStub })); + + const { transformRequest } = webdriverio.attach.lastCall.args[0]; + transformRequest(request); + + assert.equal(request.headers["X-Request-ID"], "100500"); + }); + + it('should add "X-Request-ID" header', async () => { + crypto.randomUUID.returns("67890"); + const testXReqId = "12345"; + const request = { headers: {} }; + + await initBrowser_(mkBrowser_({}, { testXReqId })); + + const { transformRequest } = webdriverio.attach.lastCall.args[0]; + transformRequest(request); + + assert.equal(request.headers["X-Request-ID"], `12345${X_REQUEST_ID_DELIMITER}67890`); + }); + }); + + describe("transformResponse option", () => { + it("should call user handler from config", async () => { + const transformResponseStub = sinon.stub(); + const response = {}; + + await initBrowser_(mkBrowser_({ transformResponse: transformResponseStub })); + + const { transformResponse } = webdriverio.attach.lastCall.args[0]; + transformResponse(response); + + assert.calledOnceWith(transformResponseStub, response); }); }); diff --git a/test/src/browser/new-browser.js b/test/src/browser/new-browser.js index 6455c956e..47ae5e96a 100644 --- a/test/src/browser/new-browser.js +++ b/test/src/browser/new-browser.js @@ -1,10 +1,12 @@ "use strict"; +const crypto = require("crypto"); const webdriverio = require("webdriverio"); const logger = require("src/utils/logger"); const signalHandler = require("src/signal-handler"); const history = require("src/browser/history"); const { WEBDRIVER_PROTOCOL, SAVE_HISTORY_MODE } = require("src/constants/config"); +const { X_REQUEST_ID_DELIMITER } = require("src/constants/browser"); const { mkNewBrowser_: mkBrowser_, mkSessionStub_ } = require("./utils"); describe("NewBrowser", () => { @@ -36,6 +38,7 @@ describe("NewBrowser", () => { connectionRetryTimeout: 3000, connectionRetryCount: 0, baseUrl: "http://base_url", + transformRequest: sinon.match.func, }); }); @@ -116,8 +119,7 @@ describe("NewBrowser", () => { it("it is already exists in capabilities", async () => { await mkBrowser_( { desiredCapabilities: { browserName: "browser", browserVersion: "1.0" } }, - "browser", - "2.0", + { id: "browser", version: "2.0" }, ).init(); assert.calledWithMatch(webdriverio.remote, { @@ -126,7 +128,7 @@ describe("NewBrowser", () => { }); it("w3c protocol is used", async () => { - await mkBrowser_({ sessionEnvFlags: { isW3C: true } }, "browser", "2.0").init(); + await mkBrowser_({ sessionEnvFlags: { isW3C: true } }, { id: "browser", version: "2.0" }).init(); assert.calledWithMatch(webdriverio.remote, { capabilities: { browserName: "browser", browserVersion: "2.0" }, @@ -188,6 +190,66 @@ describe("NewBrowser", () => { assert.notCalled(session.setTimeouts); }); + describe("transformRequest option", () => { + beforeEach(() => { + sandbox.stub(crypto, "randomUUID").returns("00000"); + }); + + it("should call user handler from config", async () => { + const request = { headers: {} }; + const transformRequestStub = sinon.stub().returns(request); + + await mkBrowser_({ transformRequest: transformRequestStub }).init(); + + const { transformRequest } = webdriverio.remote.lastCall.args[0]; + transformRequest(request); + + assert.calledOnceWith(transformRequestStub, request); + }); + + it('should not add "X-Request-ID" header if it is already add by user', async () => { + const request = { headers: {} }; + const transformRequestStub = req => { + req.headers["X-Request-ID"] = "100500"; + return req; + }; + + await mkBrowser_({ transformRequest: transformRequestStub }).init(); + + const { transformRequest } = webdriverio.remote.lastCall.args[0]; + transformRequest(request); + + assert.equal(request.headers["X-Request-ID"], "100500"); + }); + + it('should add "X-Request-ID" header', async () => { + crypto.randomUUID.returns("67890"); + const testXReqId = "12345"; + const request = { headers: {} }; + + await mkBrowser_({}, { testXReqId }).init(); + + const { transformRequest } = webdriverio.remote.lastCall.args[0]; + transformRequest(request); + + assert.equal(request.headers["X-Request-ID"], `12345${X_REQUEST_ID_DELIMITER}67890`); + }); + }); + + describe("transformResponse option", () => { + it("should call user handler from config", async () => { + const transformResponseStub = sinon.stub(); + const response = {}; + + await mkBrowser_({ transformResponse: transformResponseStub }).init(); + + const { transformResponse } = webdriverio.remote.lastCall.args[0]; + transformResponse(response); + + assert.calledOnceWith(transformResponseStub, response); + }); + }); + describe("commands-history", () => { beforeEach(() => { sandbox.spy(history, "initCommandHistory"); diff --git a/test/src/browser/utils.js b/test/src/browser/utils.js index 9f8d8459d..53919c789 100644 --- a/test/src/browser/utils.js +++ b/test/src/browser/utils.js @@ -49,12 +49,15 @@ function createBrowserConfig_(opts = {}) { }; } -exports.mkNewBrowser_ = (opts, browser = "browser", version) => { - return NewBrowser.create(createBrowserConfig_(opts), browser, version); +exports.mkNewBrowser_ = (configOpts, opts = { id: "browser", version: "1.0", testXReqId: "" }) => { + return NewBrowser.create(createBrowserConfig_(configOpts), opts); }; -exports.mkExistingBrowser_ = (opts, browser = "browser", browserVersion, emitter = "emitter") => { - return ExistingBrowser.create(createBrowserConfig_(opts), browser, browserVersion, emitter); +exports.mkExistingBrowser_ = ( + configOpts, + opts = { id: "browser", version: "1.0", testXReqId: "", emitter: "emitter" }, +) => { + return ExistingBrowser.create(createBrowserConfig_(configOpts), opts); }; exports.mkMockStub_ = () => { diff --git a/test/src/runner/browser-agent.js b/test/src/runner/browser-agent.js index b442ba4db..f546549be 100644 --- a/test/src/runner/browser-agent.js +++ b/test/src/runner/browser-agent.js @@ -11,7 +11,7 @@ describe("runner/browser-agent", () => { version = version || "some.default.version"; pool = pool || Object.create(BrowserPool.prototype); - return BrowserAgent.create(id, version, pool); + return BrowserAgent.create({ id, version, pool }); } function mkBrowser_(opts = {}) { diff --git a/test/src/runner/browser-runner.js b/test/src/runner/browser-runner.js index 56296361f..6e4cf5ef9 100644 --- a/test/src/runner/browser-runner.js +++ b/test/src/runner/browser-runner.js @@ -155,8 +155,8 @@ describe("runner/browser-runner", () => { await run_({ runner }); assert.calledTwice(BrowserAgent.create); - assert.calledWith(BrowserAgent.create.firstCall, "bro", "1.0", pool); - assert.calledWith(BrowserAgent.create.secondCall, "bro", "1.0", pool); + assert.calledWith(BrowserAgent.create.firstCall, { id: "bro", version: "1.0", pool }); + assert.calledWith(BrowserAgent.create.secondCall, { id: "bro", version: "1.0", pool }); }); it("should create test runner for each test in collection", async () => { diff --git a/test/src/runner/test-runner/high-priority-browser-agent.js b/test/src/runner/test-runner/high-priority-browser-agent.js index 44bc55264..f7c7893ab 100644 --- a/test/src/runner/test-runner/high-priority-browser-agent.js +++ b/test/src/runner/test-runner/high-priority-browser-agent.js @@ -5,13 +5,13 @@ const HighPriorityBrowserAgent = require("src/runner/test-runner/high-priority-b describe("runner/test-runner/high-priority-browser-agent", () => { describe("getBrowser", () => { - it("should call base browser agent getBrowser with highPriority option", () => { + it("should call base browser agent getBrowser with p highPriority option", () => { const browserAgent = sinon.createStubInstance(BrowserAgent); const highPriorityBrowserAgent = HighPriorityBrowserAgent.create(browserAgent); - highPriorityBrowserAgent.getBrowser(); + highPriorityBrowserAgent.getBrowser({ foo: "bar" }); - assert.calledOnceWith(browserAgent.getBrowser, { highPriority: true }); + assert.calledOnceWith(browserAgent.getBrowser, { foo: "bar", highPriority: true }); }); it("should return base browser agent getBrowser result", () => { diff --git a/test/src/runner/test-runner/regular-test-runner.js b/test/src/runner/test-runner/regular-test-runner.js index 0e8a2e6d4..7b3a0e2da 100644 --- a/test/src/runner/test-runner/regular-test-runner.js +++ b/test/src/runner/test-runner/regular-test-runner.js @@ -1,5 +1,6 @@ "use strict"; +const crypto = require("crypto"); const _ = require("lodash"); const BrowserAgent = require("src/runner/browser-agent"); @@ -32,7 +33,7 @@ describe("runner/test-runner/regular-test-runner", () => { const mkRunner_ = (opts = {}) => { const test = opts.test || new Test({ title: "defaultTest" }); - const browserAgent = opts.browserAgent || BrowserAgent.create(); + const browserAgent = opts.browserAgent || BrowserAgent.create({}); return RegularTestRunner.create(test, browserAgent); }; @@ -70,6 +71,7 @@ describe("runner/test-runner/regular-test-runner", () => { sandbox.stub(AssertViewResults.prototype, "get").returns({}); sandbox.stub(logger, "warn"); + sandbox.stub(crypto, "randomUUID").returns(""); }); afterEach(() => sandbox.restore()); @@ -87,7 +89,9 @@ describe("runner/test-runner/regular-test-runner", () => { describe("run", () => { it("should get browser before running test", async () => { - BrowserAgent.prototype.getBrowser.resolves( + const testXReqId = "12345"; + crypto.randomUUID.returns(testXReqId); + BrowserAgent.prototype.getBrowser.withArgs({ testXReqId }).resolves( stubBrowser_({ id: "bro", version: "1.0", @@ -96,6 +100,7 @@ describe("runner/test-runner/regular-test-runner", () => { publicAPI: { options: { foo: "bar" }, }, + testXReqId, }), ); const workers = mkWorkers_(); @@ -111,6 +116,7 @@ describe("runner/test-runner/regular-test-runner", () => { sessionId: "100500", sessionCaps: { browserName: "bro" }, sessionOpts: { foo: "bar" }, + testXReqId, }), ); }); diff --git a/test/src/worker/runner/browser-agent.js b/test/src/worker/runner/browser-agent.js index 6d5baf937..486d7d74b 100644 --- a/test/src/worker/runner/browser-agent.js +++ b/test/src/worker/runner/browser-agent.js @@ -17,14 +17,16 @@ describe("worker/browser-agent", () => { sessionId: "100-500", sessionCaps: "some-caps", sessionOpts: "some-opts", + testXReqId: "12345", }) .returns({ some: "browser" }); - const browserAgent = BrowserAgent.create("bro-id", null, browserPool); + const browserAgent = BrowserAgent.create({ id: "bro-id", version: null, pool: browserPool }); const browser = browserAgent.getBrowser({ sessionId: "100-500", sessionCaps: "some-caps", sessionOpts: "some-opts", + testXReqId: "12345", }); assert.deepEqual(browser, { some: "browser" }); @@ -38,14 +40,16 @@ describe("worker/browser-agent", () => { sessionId: "100-500", sessionCaps: "some-caps", sessionOpts: "some-opts", + testXReqId: "12345", }) .returns({ some: "browser" }); - const browserAgent = BrowserAgent.create("bro-id", "10.1", browserPool); + const browserAgent = BrowserAgent.create({ id: "bro-id", version: "10.1", pool: browserPool }); const browser = browserAgent.getBrowser({ sessionId: "100-500", sessionCaps: "some-caps", sessionOpts: "some-opts", + testXReqId: "12345", }); assert.deepEqual(browser, { some: "browser" }); @@ -54,7 +58,7 @@ describe("worker/browser-agent", () => { describe("freeBrowser", () => { it("should free the browser in the pool", () => { - BrowserAgent.create(null, null, browserPool).freeBrowser({ some: "browser" }); + BrowserAgent.create({ pool: browserPool }).freeBrowser({ some: "browser" }); assert.calledOnceWith(browserPool.freeBrowser, { some: "browser" }); }); diff --git a/test/src/worker/runner/browser-pool.js b/test/src/worker/runner/browser-pool.js index cacd8180a..d7b029ad3 100644 --- a/test/src/worker/runner/browser-pool.js +++ b/test/src/worker/runner/browser-pool.js @@ -52,24 +52,16 @@ describe("worker/browser-pool", () => { const config = stubConfig(); const emitter = new EventEmitter(); const browserPool = createPool({ config, emitter }); - const browser = stubBrowser({ browserId: "bro-id" }); - Browser.create.withArgs(config, "bro-id", undefined, emitter).returns(browser); - - await browserPool.getBrowser({ browserId: "bro-id" }); - - assert.calledOnceWith(Browser.create, config, "bro-id", undefined, emitter); - }); - - it("should create specific version of browser with correct args", async () => { - const config = stubConfig(); - const emitter = new EventEmitter(); - const browserPool = createPool({ config, emitter }); - const browser = stubBrowser({ browserId: "bro-id" }); - Browser.create.withArgs(config, "bro-id", "10.1", emitter).returns(browser); + Browser.create.returns(stubBrowser({ browserId: "bro-id" })); - await browserPool.getBrowser({ browserId: "bro-id", browserVersion: "10.1" }); + await browserPool.getBrowser({ browserId: "bro-id", browserVersion: "1.0", testXReqId: "12345" }); - assert.calledOnceWith(Browser.create, config, "bro-id", "10.1", emitter); + assert.calledOnceWith(Browser.create, config, { + id: "bro-id", + version: "1.0", + testXReqId: "12345", + emitter, + }); }); it("should init a new created browser ", async () => { @@ -108,22 +100,11 @@ describe("worker/browser-pool", () => { const config = stubConfig(); const browserPool = createPool({ config }); const browser = stubBrowser({ browserId: "bro-id" }); - - Browser.create.withArgs(config, "bro-id").returns(browser); + Browser.create.returns(browser); return assert.becomes(browserPool.getBrowser({ browserId: "bro-id" }), browser); }); - it("should return a new createt browser with specific version", () => { - const config = stubConfig(); - const browserPool = createPool({ config }); - const browser = stubBrowser({ browserId: "bro-id" }); - - Browser.create.withArgs(config, "bro-id", "10.1").returns(browser); - - return assert.becomes(browserPool.getBrowser({ browserId: "bro-id", browserVersion: "10.1" }), browser); - }); - describe("getting of browser fails", () => { beforeEach(() => { sandbox.spy(BrowserPool.prototype, "freeBrowser"); diff --git a/test/src/worker/runner/index.js b/test/src/worker/runner/index.js index 43d022258..c8025c3ba 100644 --- a/test/src/worker/runner/index.js +++ b/test/src/worker/runner/index.js @@ -93,15 +93,17 @@ describe("worker/runner", () => { }); it("should create browser agent for test runner", async () => { + const pool = { browser: "pool" }; + BrowserPool.create.returns(pool); const runner = mkRunner_(); const test = makeTest({ fullTitle: () => "some test" }); CachingTestParser.prototype.parse.resolves([test]); const browserAgent = Object.create(BrowserAgent.prototype); - BrowserAgent.create.withArgs("bro").returns(browserAgent); + BrowserAgent.create.withArgs({ id: "bro", version: "1.0", pool }).returns(browserAgent); - await runner.runTest("some test", { browserId: "bro" }); + await runner.runTest("some test", { browserId: "bro", browserVersion: "1.0" }); assert.calledOnceWith(TestRunner.create, test, sinon.match.any, browserAgent); }); @@ -128,12 +130,14 @@ describe("worker/runner", () => { sessionId: "100500", sessionCaps: "some-caps", sessionOpts: "some-opts", + testXReqId: "12345", }); assert.calledOnceWith(TestRunner.prototype.run, { sessionId: "100500", sessionCaps: "some-caps", sessionOpts: "some-opts", + testXReqId: "12345", }); }); }); diff --git a/test/src/worker/runner/test-runner/index.js b/test/src/worker/runner/test-runner/index.js index 29967a3ff..b322c0037 100644 --- a/test/src/worker/runner/test-runner/index.js +++ b/test/src/worker/runner/test-runner/index.js @@ -106,7 +106,12 @@ describe("worker/runner/test-runner", () => { it("should request browser for passed session", async () => { const runner = mkRunner_(); - const opts = { sessionId: "100500", sessionCaps: "some-caps", sessionOpts: "some-opts" }; + const opts = { + sessionId: "100500", + sessionCaps: "some-caps", + sessionOpts: "some-opts", + testXReqId: "12345", + }; await runner.run(opts);