diff --git a/javascript/selenium-webdriver/bidi/networkTypes.js b/javascript/selenium-webdriver/bidi/networkTypes.js index 57e2f56f34895..ebd3c40e0e4f8 100644 --- a/javascript/selenium-webdriver/bidi/networkTypes.js +++ b/javascript/selenium-webdriver/bidi/networkTypes.js @@ -119,6 +119,17 @@ class Header { get value() { return this._value } + + /** + * Converts the Header to a map. + * @returns {Map} A map representation of the Header. + */ + asMap() { + return new Map([ + ['name', this.name], + ['value', Object.fromEntries(this.value.asMap())], + ]) + } } /** diff --git a/javascript/selenium-webdriver/test/bidi/network_commands_test.js b/javascript/selenium-webdriver/test/bidi/network_commands_test.js index f3969c7917888..69045d9285685 100644 --- a/javascript/selenium-webdriver/test/bidi/network_commands_test.js +++ b/javascript/selenium-webdriver/test/bidi/network_commands_test.js @@ -27,6 +27,7 @@ const { until } = require('selenium-webdriver/index') const { ContinueRequestParameters } = require('selenium-webdriver/bidi/continueRequestParameters') const { ContinueResponseParameters } = require('selenium-webdriver/bidi/continueResponseParameters') const { ProvideResponseParameters } = require('selenium-webdriver/bidi/provideResponseParameters') +const { BytesValue, Header } = require('selenium-webdriver/bidi/networkTypes') suite( function (env) { @@ -162,6 +163,37 @@ suite( assert.strictEqual(counter >= 1, true) }) + + it('can provide response with headers', async function () { + await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT)) + + let counter = 0 + + await network.beforeRequestSent(async (event) => { + const headers = [ + new Header('content-type', new BytesValue(BytesValue.Type.STRING, 'application/json')), + new Header('x-custom-header', new BytesValue(BytesValue.Type.STRING, 'test-value')), + ] + + const body = new BytesValue( + BytesValue.Type.BASE64, + Buffer.from(JSON.stringify({ status: 'ok' })).toString('base64'), + ) + + const params = new ProvideResponseParameters(event.request.request) + .statusCode(200) + .body(body) + .headers(headers) + .reasonPhrase('OK') + + await network.provideResponse(params) + counter = counter + 1 + }) + + await driver.get(Pages.logEntryAdded) + + assert.strictEqual(counter >= 1, true) + }) }) }, { browsers: [Browser.FIREFOX] }, diff --git a/javascript/selenium-webdriver/test/bidi/network_types_test.js b/javascript/selenium-webdriver/test/bidi/network_types_test.js new file mode 100644 index 0000000000000..4abe7a879e68c --- /dev/null +++ b/javascript/selenium-webdriver/test/bidi/network_types_test.js @@ -0,0 +1,51 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +'use strict' + +const assert = require('node:assert') +const { BytesValue, Header } = require('selenium-webdriver/bidi/networkTypes') +const { ProvideResponseParameters } = require('selenium-webdriver/bidi/provideResponseParameters') + +describe('ProvideResponseParameters with Headers', function () { + it('should accept headers without throwing asMap error (issue #16339)', function () { + const bufferStr = Buffer.from(JSON.stringify({})).toString('base64') + const byteLength = Buffer.byteLength(bufferStr) + + const headers = [ + new Header('content-type', new BytesValue(BytesValue.Type.STRING, 'application/json')), + new Header('access-control-allow-methods', new BytesValue(BytesValue.Type.STRING, '*')), + new Header('access-control-allow-origin', new BytesValue(BytesValue.Type.STRING, '*')), + new Header('content-length', new BytesValue(BytesValue.Type.STRING, byteLength.toString())), + ] + + const body = new BytesValue(BytesValue.Type.BASE64, bufferStr) + + // This should not throw "TypeError: header.asMap is not a function" + assert.doesNotThrow(() => { + new ProvideResponseParameters(1).statusCode(200).body(body).headers(headers).reasonPhrase('OK') + }) + }) + + it('should return correct map structure from asMap', function () { + const header = new Header('content-type', new BytesValue(BytesValue.Type.STRING, 'application/json')) + const map = header.asMap() + + assert.strictEqual(map.get('name'), 'content-type') + assert.deepStrictEqual(map.get('value'), { type: 'string', value: 'application/json' }) + }) +})